@@ -44,6 +44,7 @@ using vtr::t_linked_vptr;
4444t_model* hard_adders = NULL ;
4545t_linked_vptr* add_list = NULL ;
4646t_linked_vptr* processed_adder_list = NULL ;
47+ t_linked_vptr* split_adder_list = NULL ;
4748t_linked_vptr* chain_list = NULL ;
4849int total = 0 ;
4950int * adder = NULL ;
@@ -646,7 +647,7 @@ void split_adder(nnode_t* nodeo, int a, int b, int sizea, int sizeb, int cin, in
646647 init_split_adder (nodeo, node[i], a, sizea, b, sizeb, cin, cout, i, flag, netlist);
647648
648649 // store the processed hard adder node for optimization
649- processed_adder_list = insert_in_vptr_list (processed_adder_list , node[i]);
650+ split_adder_list = insert_in_vptr_list (split_adder_list , node[i]);
650651 }
651652
652653 chain_information_t * adder_chain = allocate_chain_info ();
@@ -767,21 +768,21 @@ void split_adder(nnode_t* nodeo, int a, int b, int sizea, int sizeb, int cin, in
767768 return ;
768769}
769770
770- /* -------------------------------------------------------------------------
771- * (function: iterate_adders)
772- *
773- * This function will iterate over all of the add operations that
774- * exist in the netlist and perform a splitting so that they can
775- * fit into a basic hard adder block that exists on the FPGA.
776- * If the proper option is set, then it will be expanded as well
777- * to just use a fixed size hard adder.
778- *-----------------------------------------------------------------------*/
779- void iterate_adders (netlist_t * netlist) {
771+ /* *
772+ * -------------------------------------------------------------------------
773+ * (function: split_instantiate_hard_adder)
774+ *
775+ * @brief to split a hard adder into an adder chain of single
776+ * bit adders and instantiate each of them
777+ *
778+ * @param node multibit hard adder node
779+ * @param netlist pointer to netlist
780+ * -----------------------------------------------------------------------*/
781+ void split_instantiate_hard_adder (nnode_t * node, uintptr_t mark, netlist_t * netlist) {
780782 int sizea, sizeb, sizecin; // the size of
781783 int a, b;
782784 int count, counta, countb;
783785 int num = 0 ;
784- nnode_t * node;
785786
786787 // offset to the adder size in case a dummy adder is added to
787788 // start of the adder chain to feed the first cin with gnd
@@ -796,6 +797,60 @@ void iterate_adders(netlist_t* netlist) {
796797 sizea = hard_adders->inputs ->next ->size ;
797798
798799 oassert (sizecin == 1 );
800+ oassert (node != NULL );
801+
802+ if (node->type == HARD_IP)
803+ node->type = ADD;
804+
805+ oassert (node->type == ADD);
806+
807+ a = node->input_port_sizes [0 ];
808+ b = node->input_port_sizes [1 ];
809+ num = (a >= b) ? a : b;
810+ node->bit_width = num;
811+ oassert (num >= min_threshold_adder && num >= min_add);
812+ // if the first cin in a chain is fed by a global input (offset = 0) the adder width is the
813+ // input width + 1 (to pass the last cout -> sumout) divided by size of the adder input ports
814+ // otherwise (offset = 1) a dummy adder is added to the chain to feed the first cin with gnd
815+ // how many adders a can split
816+ counta = (a + 1 ) / sizea + offset;
817+ // how many adders b can split
818+ countb = (b + 1 ) / sizeb + offset;
819+ // how many adders need to be split
820+ if (counta >= countb)
821+ count = counta;
822+ else
823+ count = countb;
824+ total++;
825+ split_adder (node, a, b, sizea, sizeb, 1 , 1 , count, netlist);
826+
827+ while (split_adder_list != NULL ) {
828+ nnode_t * hard_adder = (nnode_t *)split_adder_list->data_vptr ;
829+ split_adder_list = delete_in_vptr_list (split_adder_list);
830+ instantiate_hard_adder (hard_adder, mark, netlist);
831+ }
832+ return ;
833+ }
834+
835+ /* -------------------------------------------------------------------------
836+ * (function: iterate_adders)
837+ *
838+ * This function will iterate over all of the add operations that
839+ * exist in the netlist and perform a splitting so that they can
840+ * fit into a basic hard adder block that exists on the FPGA.
841+ * If the proper option is set, then it will be expanded as well
842+ * to just use a fixed size hard adder.
843+ *-----------------------------------------------------------------------*/
844+ void iterate_adders (netlist_t * /* netlist */ ) {
845+ int a, b;
846+ int num = 0 ;
847+ nnode_t * node;
848+
849+ /* Can only perform the optimization if hard adders exist! */
850+ if (hard_adders == NULL )
851+ return ;
852+
853+ t_linked_vptr* new_add_list = NULL ;
799854
800855 while (add_list != NULL ) {
801856 node = (nnode_t *)add_list->data_vptr ;
@@ -811,25 +866,13 @@ void iterate_adders(netlist_t* netlist) {
811866 num = (a >= b) ? a : b;
812867 node->bit_width = num;
813868 if (num >= min_threshold_adder && num >= min_add) {
814- // if the first cin in a chain is fed by a global input (offset = 0) the adder width is the
815- // input width + 1 (to pass the last cout -> sumout) divided by size of the adder input ports
816- // otherwise (offset = 1) a dummy adder is added to the chain to feed the first cin with gnd
817- // how many adders a can split
818- counta = (a + 1 ) / sizea + offset;
819- // how many adders b can split
820- countb = (b + 1 ) / sizeb + offset;
821- // how many adders need to be split
822- if (counta >= countb)
823- count = counta;
824- else
825- count = countb;
826- total++;
827- split_adder (node, a, b, sizea, sizeb, 1 , 1 , count, netlist);
869+ new_add_list = insert_in_vptr_list (new_add_list, node);
828870 }
829871 // Store the node into processed_adder_list if the threshold is bigger than num
830872 else
831873 processed_adder_list = insert_in_vptr_list (processed_adder_list, node);
832874 }
875+ add_list = new_add_list;
833876 return ;
834877}
835878
@@ -1222,8 +1265,56 @@ static nnode_t* make_adder(operation_list funct, nnode_t* current_adder, nnode_t
12221265 return new_funct;
12231266}
12241267
1268+ /* --------------------------------------------------------------------------
1269+ * (function: instantiate_simple_soft_adder )
1270+ * This is simply a copy of instantiate_add_w_carry;
1271+ * need to be worked out
1272+ * to use a single copy to avoid code repetition.
1273+ *------------------------------------------------------------------------*/
1274+ void instantiate_simple_soft_adder (nnode_t * node, short mark, netlist_t * netlist) {
1275+ // define locations in array when fetching pins
1276+ const int out = 0 , input_a = 1 , input_b = 2 , pinout_count = 3 ;
1277+
1278+ oassert (node->num_input_pins > 0 );
1279+
1280+ int * width = (int *)vtr::malloc (pinout_count * sizeof (int ));
1281+
1282+ if (node->num_input_port_sizes == 2 )
1283+ width[out] = node->output_port_sizes [0 ];
1284+ else
1285+ width[out] = node->num_output_pins ;
1286+
1287+ width[input_a] = node->input_port_sizes [0 ];
1288+ width[input_b] = node->input_port_sizes [1 ];
1289+
1290+ instantiate_add_w_carry_block (width, node, mark, netlist, 0 );
1291+
1292+ vtr::free (width);
1293+ }
1294+
12251295void instantiate_add_w_carry_block (int * width, nnode_t * node, short mark, netlist_t * netlist, short subtraction) {
1226- nnode_t * previous_carry = (subtraction) ? netlist->vcc_node : netlist->gnd_node ;
1296+ nnode_t * previous_carry;
1297+ /* *
1298+ * while hard adders are available, the function "iterate_adders"
1299+ * explode the add node into an adder chain in which each adders has cin
1300+ * pin. This is required due to adder hardblock structure. However, the
1301+ * cin pin need to be handled in the case of inferring a chain add node
1302+ * as soft logic (using MixingOptimization) since the soft logic inferrence
1303+ * automatically consider GND or VCC as cin pin according to the node type
1304+ */
1305+ // check if node has cin port
1306+ if (node->num_input_port_sizes == 3 ) {
1307+ npin_t * cin = node->input_pins [width[1 ] + width[2 ]];
1308+ previous_carry = make_3port_gate (CARRY_FUNC, 1 , 1 , 1 , 1 , node, mark);
1309+ /* hook the GND as cin pin */
1310+ add_input_pin_to_node (previous_carry, get_zero_pin (netlist), 0 );
1311+ /* connect the add node's cin as CARRY_FUNC inputs */
1312+ add_input_pin_to_node (previous_carry, get_one_pin (netlist), 1 );
1313+ remap_pin_to_new_node (cin, previous_carry, 2 );
1314+ } else {
1315+ /* considering VCC or GND as cin based on node type */
1316+ previous_carry = (subtraction) ? netlist->vcc_node : netlist->gnd_node ;
1317+ }
12271318
12281319 for (int i = 0 ; i < width[0 ]; i++) {
12291320 /* set of flags for building purposes */
0 commit comments