@@ -44,6 +44,7 @@ using vtr::t_linked_vptr;
44
44
t_model* hard_adders = NULL ;
45
45
t_linked_vptr* add_list = NULL ;
46
46
t_linked_vptr* processed_adder_list = NULL ;
47
+ t_linked_vptr* split_adder_list = NULL ;
47
48
t_linked_vptr* chain_list = NULL ;
48
49
int total = 0 ;
49
50
int * adder = NULL ;
@@ -646,7 +647,7 @@ void split_adder(nnode_t* nodeo, int a, int b, int sizea, int sizeb, int cin, in
646
647
init_split_adder (nodeo, node[i], a, sizea, b, sizeb, cin, cout, i, flag, netlist);
647
648
648
649
// 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]);
650
651
}
651
652
652
653
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
767
768
return ;
768
769
}
769
770
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) {
780
782
int sizea, sizeb, sizecin; // the size of
781
783
int a, b;
782
784
int count, counta, countb;
783
785
int num = 0 ;
784
- nnode_t * node;
785
786
786
787
// offset to the adder size in case a dummy adder is added to
787
788
// start of the adder chain to feed the first cin with gnd
@@ -796,6 +797,60 @@ void iterate_adders(netlist_t* netlist) {
796
797
sizea = hard_adders->inputs ->next ->size ;
797
798
798
799
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 ;
799
854
800
855
while (add_list != NULL ) {
801
856
node = (nnode_t *)add_list->data_vptr ;
@@ -811,25 +866,13 @@ void iterate_adders(netlist_t* netlist) {
811
866
num = (a >= b) ? a : b;
812
867
node->bit_width = num;
813
868
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);
828
870
}
829
871
// Store the node into processed_adder_list if the threshold is bigger than num
830
872
else
831
873
processed_adder_list = insert_in_vptr_list (processed_adder_list, node);
832
874
}
875
+ add_list = new_add_list;
833
876
return ;
834
877
}
835
878
@@ -1222,8 +1265,56 @@ static nnode_t* make_adder(operation_list funct, nnode_t* current_adder, nnode_t
1222
1265
return new_funct;
1223
1266
}
1224
1267
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
+
1225
1295
void 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
+ }
1227
1318
1228
1319
for (int i = 0 ; i < width[0 ]; i++) {
1229
1320
/* set of flags for building purposes */
0 commit comments