Skip to content

Commit c4107ed

Browse files
author
djns1
committed
Implemented InOuts
1 parent 9108b17 commit c4107ed

20 files changed

+353
-206
lines changed

ODIN_II/SRC/ast_elaborate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2656,11 +2656,11 @@ void create_param_table_for_scope(ast_node_t* module_items, sc_hierarchy* local_
26562656
/* symbols are already dealt with */
26572657
if (var_declare->types.variable.is_input
26582658
|| var_declare->types.variable.is_output
2659+
|| var_declare->types.variable.is_inout
26592660
|| var_declare->types.variable.is_reg
26602661
|| var_declare->types.variable.is_genvar
26612662
|| var_declare->types.variable.is_wire
26622663
|| var_declare->types.variable.is_defparam)
2663-
26642664
continue;
26652665

26662666
oassert(module_items->children[i]->children[j]->type == VAR_DECLARE);

ODIN_II/SRC/netlist_create_from_ast.cpp

Lines changed: 71 additions & 61 deletions
Large diffs are not rendered by default.

ODIN_II/SRC/netlist_utils.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ nnet_t* allocate_nnet() {
296296
*-------------------------------------------------------------------------------------------*/
297297
nnet_t* free_nnet(nnet_t* to_free) {
298298
if (to_free) {
299-
to_free->fanout_pins = (npin_t**)vtr::free(to_free->fanout_pins);
299+
if (to_free->num_fanout_pins)
300+
to_free->fanout_pins = (npin_t**)vtr::free(to_free->fanout_pins);
300301

301302
if (to_free->name)
302303
vtr::free(to_free->name);
@@ -417,13 +418,13 @@ void add_driver_pin_to_net(nnet_t* net, npin_t* pin) {
417418
* The lasting one is input, and output disappears
418419
*-------------------------------------------------------------------------------------------*/
419420
void combine_nets(nnet_t* output_net, nnet_t* input_net, netlist_t* netlist) {
421+
/* in case there are any fanouts in output net (should only be zero and one nodes) */
422+
join_nets(input_net, output_net);
420423
/* copy the driver over to the new_net */
421424
for (int i = 0; i < output_net->num_driver_pins; i++) {
422425
/* IF - there is a pin assigned to this net, then copy it */
423426
add_driver_pin_to_net(input_net, output_net->driver_pins[i]);
424427
}
425-
/* in case there are any fanouts in output net (should only be zero and one nodes) */
426-
join_nets(input_net, output_net);
427428
/* mark that this is combined */
428429
input_net->combined = true;
429430

@@ -465,11 +466,27 @@ void join_nets(nnet_t* join_to_net, nnet_t* other_net) {
465466
}
466467

467468
error_message(NETLIST, unknown_location, "%s", "Found a combinational loop");
468-
} else if (other_net->num_driver_pins > 1) {
469-
if (other_net->name && join_to_net->name)
470-
error_message(NETLIST, unknown_location, "Tried to join net %s to %s but this would lose %d drivers for net %s", other_net->name, join_to_net->name, other_net->num_driver_pins - 1, other_net->name);
471-
else
472-
error_message(NETLIST, unknown_location, "Tried to join nets but this would lose %d drivers", other_net->num_driver_pins - 1);
469+
} else if (other_net->num_driver_pins > 1 && join_to_net->num_driver_pins != 0) {
470+
bool drivers_match = true;
471+
if(other_net->num_driver_pins == join_to_net->num_driver_pins) {
472+
for (int i = 0; drivers_match && i < other_net->num_driver_pins; i++)
473+
{
474+
bool driver_match = false;
475+
for (int j = 0; !driver_match && j < join_to_net->num_driver_pins; j++)
476+
{
477+
driver_match = join_to_net->driver_pins[j] == other_net->driver_pins[i];
478+
}
479+
drivers_match &= driver_match;
480+
}
481+
}
482+
// Either we tried to eliminate a buffer into a net with multiple drivers
483+
// or we tried to combine nets that already had mismatching drivers
484+
if(!drivers_match) {
485+
if (other_net->name && join_to_net->name)
486+
error_message(NETLIST, unknown_location, "Tried to join net %s to %s but this would lose %d drivers for net %s", other_net->name, join_to_net->name, other_net->num_driver_pins - 1, other_net->name);
487+
else
488+
error_message(NETLIST, unknown_location, "Tried to join nets but this would lose %d drivers", other_net->num_driver_pins - 1);
489+
}
473490
}
474491

475492
/* copy the driver over to the new_net */

ODIN_II/SRC/output_blif.cpp

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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

8887
static 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\n1 1\n\n", name);
145+
}
146+
return name;
147+
}
148+
return NULL;
149+
}
150+
136151
static 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\n1 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\n1\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

Comments
 (0)