@@ -65,25 +65,24 @@ static bool warn_undriven(nnode_t* node, nnet_t* net) {
65
65
return false ;
66
66
}
67
67
68
- // TODO Uncomment this for In Outs
69
- // static void merge_with_inputs(nnode_t* node, long pin_idx) {
70
- // oassert(pin_idx < node->num_input_pins);
71
- // nnet_t* net = node->input_pins[pin_idx]->net;
72
- // warn_undriven(node, net);
73
- // // Merge node with all inputs with fanout of 1
74
- // if (net->num_fanout_pins <= 1) {
75
- // for (int i = 0; i < net->num_driver_pins; i++) {
76
- // npin_t* driver = net->driver_pins[i];
77
- // if (driver->name != NULL && ((driver->node->type == MULTIPLY) || (driver->node->type == HARD_IP) || (driver->node->type == MEMORY) || (driver->node->type == ADD) || (driver->node->type == MINUS))) {
78
- // vtr::free(driver->name);
79
- // driver->name = vtr::strdup(node->name);
80
- // } else {
81
- // vtr::free(driver->node->name);
82
- // driver->node->name = vtr::strdup(node->name);
83
- // }
84
- // }
85
- // }
86
- // }
68
+ static void merge_with_inputs (nnode_t * node, long pin_idx) {
69
+ oassert (pin_idx < node->num_input_pins );
70
+ nnet_t * net = node->input_pins [pin_idx]->net ;
71
+ warn_undriven (node, net);
72
+ // Merge node with all inputs with fanout of 1
73
+ if (net->num_fanout_pins <= 1 ) {
74
+ for (int i = 0 ; i < net->num_driver_pins ; i++) {
75
+ npin_t * driver = net->driver_pins [i];
76
+ if (driver->name != NULL && ((driver->node ->type == MULTIPLY) || (driver->node ->type == HARD_IP) || (driver->node ->type == MEMORY) || (driver->node ->type == ADD) || (driver->node ->type == MINUS))) {
77
+ vtr::free (driver->name );
78
+ driver->name = vtr::strdup (node->name );
79
+ } else {
80
+ vtr::free (driver->node ->name );
81
+ driver->node ->name = vtr::strdup (node->name );
82
+ }
83
+ }
84
+ }
85
+ }
87
86
88
87
static void print_net_driver (FILE* out, nnode_t * node, nnet_t * net, long driver_idx) {
89
88
oassert (driver_idx < net->num_driver_pins );
@@ -133,21 +132,27 @@ static void print_output_pin(FILE* out, nnode_t* node) {
133
132
fprintf (out, " %s" , node->name );
134
133
}
135
134
135
+ static char * buffer_multi_drivers (FILE* out, nnode_t * node, long pin_idx)
136
+ {
137
+ nnet_t * net = node->input_pins [pin_idx]->net ;
138
+ if (net->num_driver_pins > 1 ) {
139
+ char * name = op_node_name (BUF_NODE, node->name );
140
+ // Assign each driver to the implicit buffer
141
+ for (int j = 0 ; j < net->num_driver_pins ; j++) {
142
+ fprintf (out, " .names" );
143
+ print_net_driver (out, node, net, j);
144
+ fprintf (out, " %s\n 1 1\n\n " , name);
145
+ }
146
+ return name;
147
+ }
148
+ return NULL ;
149
+ }
150
+
136
151
static void print_dot_names_header (FILE* out, nnode_t * node) {
137
152
char ** names = (char **)vtr::calloc (node->num_input_pins , sizeof (char *));
138
153
139
- // Create an implicit buffer if there are multiple drivers to the component
140
154
for (int i = 0 ; i < node->num_input_pins ; i++) {
141
- nnet_t * input_net = node->input_pins [i]->net ;
142
- if (input_net->num_driver_pins > 1 ) {
143
- names[i] = op_node_name (BUF_NODE, node->name );
144
- // Assign each driver to the implicit buffer
145
- for (int j = 0 ; j < input_net->num_driver_pins ; j++) {
146
- fprintf (out, " .names" );
147
- print_net_driver (out, node, input_net, j);
148
- fprintf (out, " %s\n 1 1\n\n " , names[i]);
149
- }
150
- }
155
+ names[i] = buffer_multi_drivers (out, node, i);
151
156
}
152
157
153
158
// Print the actual header
@@ -221,14 +226,13 @@ void output_blif(FILE* out, netlist_t* netlist) {
221
226
fprintf (out, " \n .names gnd\n .names unconn\n .names vcc\n 1\n " );
222
227
fprintf (out, " \n " );
223
228
224
- // TODO Uncomment this for In Outs
225
229
// connect all the outputs up to the last gate
226
- // for (long i = 0; i < netlist->num_top_output_nodes; i++) {
227
- // nnode_t* node = netlist->top_output_nodes[i];
228
- // for (int j = 0; j < node->num_input_pins; j++) {
229
- // merge_with_inputs(node, j);
230
- // }
231
- // }
230
+ for (long i = 0 ; i < netlist->num_top_output_nodes ; i++) {
231
+ nnode_t * node = netlist->top_output_nodes [i];
232
+ for (int j = 0 ; j < node->num_input_pins ; j++) {
233
+ merge_with_inputs (node, j);
234
+ }
235
+ }
232
236
233
237
/* traverse the internals of the flat net-list */
234
238
if (strcmp (configuration.output_type .c_str (), " blif" ) == 0 ) {
@@ -241,8 +245,7 @@ void output_blif(FILE* out, netlist_t* netlist) {
241
245
for (long i = 0 ; i < netlist->num_top_output_nodes ; i++) {
242
246
nnode_t * node = netlist->top_output_nodes [i];
243
247
244
- // TODO Change this to > 1 for In Outs
245
- if (node->input_pins [0 ]->net ->num_fanout_pins > 0 ) {
248
+ if (node->input_pins [0 ]->net ->num_fanout_pins > 1 ) {
246
249
nnet_t * net = node->input_pins [0 ]->net ;
247
250
warn_undriven (node, net);
248
251
for (int j = 0 ; j < net->num_driver_pins ; j++) {
@@ -541,21 +544,26 @@ void define_ff(nnode_t* node, FILE* out) {
541
544
// grab the edge sensitivity of the flip flop
542
545
const char * edge_type_str = edge_type_blif_str (node);
543
546
544
- std::string input;
545
- std::string output;
546
- std::string clock_driver;
547
+ char * input_driver = buffer_multi_drivers (out, node, 0 );
547
548
548
549
fprintf (out, " .latch" );
549
550
550
551
/* input */
551
- print_input_single_driver (out, node, 0 );
552
+ if (!input_driver)
553
+ print_input_single_driver (out, node, 0 );
554
+ else {
555
+ // Use the implicit buffer we created before
556
+ fprintf (out, " %s" , input_driver);
557
+ vtr::free (input_driver);
558
+ }
552
559
553
560
/* output */
554
561
print_output_pin (out, node);
555
562
556
563
/* sensitivity */
557
564
fprintf (out, " %s" , edge_type_str);
558
565
566
+ // TODO Should clocks support mutliple drivers?
559
567
/* clock */
560
568
print_input_single_driver (out, node, 1 );
561
569
0 commit comments