@@ -65,25 +65,24 @@ static bool warn_undriven(nnode_t* node, nnet_t* net) {
6565 return false ;
6666}
6767
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+ }
8786
8887static void print_net_driver (FILE* out, nnode_t * node, nnet_t * net, long driver_idx) {
8988 oassert (driver_idx < net->num_driver_pins );
@@ -133,21 +132,27 @@ static void print_output_pin(FILE* out, nnode_t* node) {
133132 fprintf (out, " %s" , node->name );
134133}
135134
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+
136151static void print_dot_names_header (FILE* out, nnode_t * node) {
137152 char ** names = (char **)vtr::calloc (node->num_input_pins , sizeof (char *));
138153
139- // Create an implicit buffer if there are multiple drivers to the component
140154 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);
151156 }
152157
153158 // Print the actual header
@@ -221,14 +226,13 @@ void output_blif(FILE* out, netlist_t* netlist) {
221226 fprintf (out, " \n .names gnd\n .names unconn\n .names vcc\n 1\n " );
222227 fprintf (out, " \n " );
223228
224- // TODO Uncomment this for In Outs
225229 // 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+ }
232236
233237 /* traverse the internals of the flat net-list */
234238 if (strcmp (configuration.output_type .c_str (), " blif" ) == 0 ) {
@@ -241,8 +245,7 @@ void output_blif(FILE* out, netlist_t* netlist) {
241245 for (long i = 0 ; i < netlist->num_top_output_nodes ; i++) {
242246 nnode_t * node = netlist->top_output_nodes [i];
243247
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 ) {
246249 nnet_t * net = node->input_pins [0 ]->net ;
247250 warn_undriven (node, net);
248251 for (int j = 0 ; j < net->num_driver_pins ; j++) {
@@ -541,21 +544,26 @@ void define_ff(nnode_t* node, FILE* out) {
541544 // grab the edge sensitivity of the flip flop
542545 const char * edge_type_str = edge_type_blif_str (node);
543546
544- std::string input;
545- std::string output;
546- std::string clock_driver;
547+ char * input_driver = buffer_multi_drivers (out, node, 0 );
547548
548549 fprintf (out, " .latch" );
549550
550551 /* 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+ }
552559
553560 /* output */
554561 print_output_pin (out, node);
555562
556563 /* sensitivity */
557564 fprintf (out, " %s" , edge_type_str);
558565
566+ // TODO Should clocks support mutliple drivers?
559567 /* clock */
560568 print_input_single_driver (out, node, 1 );
561569
0 commit comments