Skip to content

Commit 5704dd0

Browse files
author
djns1
committed
Added support for multiple driver pins
1 parent 9686030 commit 5704dd0

22 files changed

+509
-284
lines changed

ODIN_II/SRC/adders.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@ void define_add_function(nnode_t* node, FILE* out) {
318318

319319
/* Write the input pins*/
320320
for (i = 0; i < node->num_input_pins; i++) {
321-
npin_t* driver_pin = node->input_pins[i]->net->driver_pin;
321+
oassert(node->input_pins[i]->net->num_driver_pins == 1);
322+
npin_t* driver_pin = node->input_pins[i]->net->driver_pins[0];
322323

323324
if (i < node->input_port_sizes[0]) {
324325
if (!driver_pin->name)
@@ -1121,27 +1122,24 @@ void free_op_nodes(nnode_t* node) {
11211122
* (function: match_pins)
11221123
*-------------------------------------------------------------------------*/
11231124
int match_pins(nnode_t* node, nnode_t* next_node) {
1124-
int flag = 0;
1125-
int i, j;
1126-
long id;
1127-
for (i = 0; i < node->num_input_pins; i++) {
1128-
flag = 0;
1129-
id = node->input_pins[i]->net->driver_pin->unique_id;
1130-
for (j = 0; j < next_node->num_input_pins; j++) {
1131-
if (id == next_node->input_pins[j]->net->driver_pin->unique_id) {
1132-
flag = 1;
1133-
break;
1134-
}
1135-
if (j == next_node->num_input_pins - 1) {
1136-
flag = -1;
1137-
break;
1125+
for (int i = 0; i < node->num_input_pins; i++) {
1126+
for (int j = 0; j < node->input_pins[i]->net->num_driver_pins; j++) {
1127+
bool found = false;
1128+
long id = node->input_pins[i]->net->driver_pins[i]->unique_id;
1129+
for (int k = 0; k < next_node->num_input_pins && !found; k++) {
1130+
for (int l = 0; l < next_node->input_pins[i]->net->num_driver_pins; l++) {
1131+
if (id == next_node->input_pins[k]->net->driver_pins[l]->unique_id) {
1132+
found = true;
1133+
break;
1134+
}
1135+
}
11381136
}
1137+
if (!found)
1138+
return -1;
11391139
}
1140-
if (flag == -1)
1141-
break;
11421140
}
11431141

1144-
return flag;
1142+
return 1;
11451143
}
11461144

11471145
/*---------------------------------------------------------------------------------------------
@@ -1196,10 +1194,11 @@ static nnode_t* make_adder(operation_list funct, nnode_t* current_adder, nnode_t
11961194
//connect input a
11971195
if (current_pin < width[1]) {
11981196
npin_t* temp_pin = node->input_pins[current_pin];
1199-
if (temp_pin->net->driver_pin == NULL || temp_pin->net->driver_pin->node->type == GND_NODE) {
1197+
oassert(temp_pin->net->num_driver_pins <= 1);
1198+
if (!temp_pin->net->num_driver_pins || temp_pin->net->driver_pins[0]->node->type == GND_NODE) {
12001199
connect_nodes(netlist->gnd_node, 0, new_funct, 0 + is_three_port_gate);
12011200
remove_fanout_pins_from_net(temp_pin->net, temp_pin, temp_pin->pin_net_idx);
1202-
} else if (temp_pin->net->driver_pin->node->type == VCC_NODE) {
1201+
} else if (temp_pin->net->driver_pins[0]->node->type == VCC_NODE) {
12031202
connect_nodes(netlist->vcc_node, 0, new_funct, 0 + is_three_port_gate);
12041203
remove_fanout_pins_from_net(temp_pin->net, temp_pin, temp_pin->pin_net_idx);
12051204
} else {
@@ -1213,11 +1212,12 @@ static nnode_t* make_adder(operation_list funct, nnode_t* current_adder, nnode_t
12131212
if (current_pin < width[2]) {
12141213
//pin a is neighbor to pin b
12151214
npin_t* temp_pin = node->input_pins[current_pin + width[1]];
1216-
if (temp_pin->net->driver_pin == NULL || temp_pin->net->driver_pin->node->type == GND_NODE) {
1215+
oassert(temp_pin->net->num_driver_pins <= 1);
1216+
if (temp_pin->net->num_driver_pins == 0 || temp_pin->net->driver_pins[0]->node->type == GND_NODE) {
12171217
nnode_t* attach_to = (subtraction) ? netlist->vcc_node : netlist->gnd_node;
12181218
connect_nodes(attach_to, 0, new_funct, 1 + is_three_port_gate);
12191219
remove_fanout_pins_from_net(temp_pin->net, temp_pin, temp_pin->pin_net_idx);
1220-
} else if (temp_pin->net->driver_pin->node->type == VCC_NODE) {
1220+
} else if (temp_pin->net->driver_pins[0]->node->type == VCC_NODE) {
12211221
nnode_t* attach_to = (subtraction) ? netlist->gnd_node : netlist->vcc_node;
12221222
connect_nodes(attach_to, 0, new_funct, 1 + is_three_port_gate);
12231223
remove_fanout_pins_from_net(temp_pin->net, temp_pin, temp_pin->pin_net_idx);

ODIN_II/SRC/hard_blocks.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,21 +144,23 @@ void define_hard_block(nnode_t* node, FILE* out) {
144144
port = index = 0;
145145
for (i = 0; i < node->num_input_pins; i++) {
146146
/* Check that the input pin is driven */
147-
if (node->input_pins[i]->net->driver_pin == NULL
147+
if (node->input_pins[i]->net->num_driver_pins == 0
148148
&& node->input_pins[i]->net != verilog_netlist->zero_net
149149
&& node->input_pins[i]->net != verilog_netlist->one_net
150150
&& node->input_pins[i]->net != verilog_netlist->pad_net) {
151151
warning_message(NETLIST, -1, -1, "Signal %s is not driven. padding with ground\n", node->input_pins[i]->name);
152152
add_fanout_pin_to_net(verilog_netlist->zero_net, node->input_pins[i]);
153+
} else if (node->input_pins[i]->net->num_driver_pins > 1) {
154+
error_message(NETLIST, -1, -1, "Multiple (%d) driver pins not supported in hard block definition\n", node->input_pins[i]->net->num_driver_pins);
153155
}
154156

155157
if (node->input_port_sizes[port] == 1)
156-
j = odin_sprintf(buffer, " %s=%s", node->input_pins[i]->mapping, node->input_pins[i]->net->driver_pin->node->name);
158+
j = odin_sprintf(buffer, " %s=%s", node->input_pins[i]->mapping, node->input_pins[i]->net->driver_pins[0]->name);
157159
else {
158-
if (node->input_pins[i]->net->driver_pin->name != NULL)
159-
j = odin_sprintf(buffer, " %s[%d]=%s", node->input_pins[i]->mapping, index, node->input_pins[i]->net->driver_pin->name);
160+
if (node->input_pins[i]->net->driver_pins[0]->name != NULL)
161+
j = odin_sprintf(buffer, " %s[%d]=%s", node->input_pins[i]->mapping, index, node->input_pins[i]->net->driver_pins[0]->name);
160162
else
161-
j = odin_sprintf(buffer, " %s[%d]=%s", node->input_pins[i]->mapping, index, node->input_pins[i]->net->driver_pin->node->name);
163+
j = odin_sprintf(buffer, " %s[%d]=%s", node->input_pins[i]->mapping, index, node->input_pins[i]->net->driver_pins[0]->node->name);
162164
}
163165

164166
if (count + j > 79) {

ODIN_II/SRC/include/node_creation_library.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ npin_t* get_zero_pin();
1919
npin_t* get_one_pin();
2020

2121
char* node_name(nnode_t* node, char* instance_prefix_name);
22+
char* op_node_name(operation_list op, char* instance_prefix_name);
2223
char* hard_node_name(nnode_t* node, char* instance_name_prefix, char* hb_name, char* hb_inst);
2324
nnode_t* make_mult_block(nnode_t* node, short mark);
2425

ODIN_II/SRC/include/odin_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,8 @@ struct nnet_t {
513513
char* name; // name for the net
514514
short combined;
515515

516-
npin_t* driver_pin; // the pin that drives the net
516+
int num_driver_pins;
517+
npin_t** driver_pins; // the pin that drives the net
517518

518519
npin_t** fanout_pins; // the pins pointed to by the net
519520
int num_fanout_pins; // the list size of pins

ODIN_II/SRC/memories.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ void instantiate_soft_single_port_ram(nnode_t* node, short mark, netlist_t* netl
14311431
npin_t* address_pin = decoder->pins[i];
14321432
/* Check that the input pin is driven */
14331433
oassert(
1434-
address_pin->net->driver_pin != NULL
1434+
address_pin->net->num_driver_pins
14351435
|| address_pin->net == verilog_netlist->zero_net
14361436
|| address_pin->net == verilog_netlist->one_net
14371437
|| address_pin->net == verilog_netlist->pad_net);
@@ -1459,7 +1459,7 @@ void instantiate_soft_single_port_ram(nnode_t* node, short mark, netlist_t* netl
14591459
npin_t* address_pin = decoder->pins[j];
14601460
/* Check that the input pin is driven */
14611461
oassert(
1462-
address_pin->net->driver_pin != NULL
1462+
address_pin->net->num_driver_pins
14631463
|| address_pin->net == verilog_netlist->zero_net
14641464
|| address_pin->net == verilog_netlist->one_net
14651465
|| address_pin->net == verilog_netlist->pad_net);
@@ -1544,12 +1544,12 @@ void instantiate_soft_dual_port_ram(nnode_t* node, short mark, netlist_t* netlis
15441544
npin_t* addr2_pin = decoder2->pins[i];
15451545

15461546
oassert(
1547-
addr1_pin->net->driver_pin != NULL
1547+
addr1_pin->net->num_driver_pins
15481548
|| addr1_pin->net == verilog_netlist->zero_net
15491549
|| addr1_pin->net == verilog_netlist->one_net
15501550
|| addr1_pin->net == verilog_netlist->pad_net);
15511551
oassert(
1552-
addr2_pin->net->driver_pin != NULL
1552+
addr2_pin->net->num_driver_pins
15531553
|| addr2_pin->net == verilog_netlist->zero_net
15541554
|| addr2_pin->net == verilog_netlist->one_net
15551555
|| addr2_pin->net == verilog_netlist->pad_net);
@@ -1597,12 +1597,12 @@ void instantiate_soft_dual_port_ram(nnode_t* node, short mark, netlist_t* netlis
15971597
npin_t* addr2_pin = decoder2->pins[j];
15981598

15991599
oassert(
1600-
addr1_pin->net->driver_pin != NULL
1600+
addr1_pin->net->num_driver_pins
16011601
|| addr1_pin->net == verilog_netlist->zero_net
16021602
|| addr1_pin->net == verilog_netlist->one_net
16031603
|| addr1_pin->net == verilog_netlist->pad_net);
16041604
oassert(
1605-
addr2_pin->net->driver_pin != NULL
1605+
addr2_pin->net->num_driver_pins
16061606
|| addr2_pin->net == verilog_netlist->zero_net
16071607
|| addr2_pin->net == verilog_netlist->one_net
16081608
|| addr2_pin->net == verilog_netlist->pad_net);
@@ -1698,7 +1698,7 @@ signal_list_t* create_decoder(nnode_t* node, short mark, signal_list_t* input_li
16981698
// Create NOT gates for all inputs and put the outputs in their own signal list.
16991699
signal_list_t* not_gates = init_signal_list();
17001700
for (long i = 0; i < num_inputs; i++) {
1701-
if (input_list->pins[i]->net->driver_pin == NULL
1701+
if (!input_list->pins[i]->net->num_driver_pins
17021702
&& input_list->pins[i]->net != verilog_netlist->zero_net
17031703
&& input_list->pins[i]->net != verilog_netlist->one_net
17041704
&& input_list->pins[i]->net != verilog_netlist->pad_net) {

ODIN_II/SRC/multipliers.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -491,18 +491,20 @@ void define_mult_function(nnode_t* node, FILE* out) {
491491

492492
for (i = 0; i < node->num_input_pins; i++) {
493493
if (i < node->input_port_sizes[flip ? 1 : 0]) {
494-
npin_t* driver_pin = flip
495-
? node->input_pins[i + node->input_port_sizes[0]]->net->driver_pin
496-
: node->input_pins[i]->net->driver_pin;
494+
int input_index = flip ? i + node->input_port_sizes[0] : i;
495+
nnet_t* net = node->input_pins[input_index]->net;
496+
oassert(net->num_driver_pins == 1);
497+
npin_t* driver_pin = net->driver_pins[0];
497498

498499
if (!driver_pin->name)
499500
j = odin_sprintf(buffer, " %s[%ld]=%s", hard_multipliers->inputs->next->name, i, driver_pin->node->name);
500501
else
501502
j = odin_sprintf(buffer, " %s[%ld]=%s", hard_multipliers->inputs->next->name, i, driver_pin->name);
502503
} else {
503-
npin_t* driver_pin = flip
504-
? node->input_pins[i - node->input_port_sizes[1]]->net->driver_pin
505-
: node->input_pins[i]->net->driver_pin;
504+
int input_index = flip ? i - node->input_port_sizes[1] : i;
505+
nnet_t* net = node->input_pins[input_index]->net;
506+
oassert(net->num_driver_pins == 1);
507+
npin_t* driver_pin = net->driver_pins[0];
506508

507509
long index = flip
508510
? i - node->input_port_sizes[1]

ODIN_II/SRC/netlist_check.cpp

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ void levelize_backwards(netlist_t* netlist) {
566566
}
567567

568568
/* mark this entry as visited */
569-
if (fanout_net->driver_pin != NULL) {
569+
if (fanout_net->num_driver_pins != 0) {
570570
fanouts_visited[current_node->input_pins[j]->pin_net_idx] = cur_back_level;
571571
}
572572

@@ -579,19 +579,20 @@ void levelize_backwards(netlist_t* netlist) {
579579
&& fanouts_visited[k] == -1));
580580
}
581581

582-
if (all_visited
583-
&& fanout_net->driver_pin
584-
&& fanout_net->driver_pin->node
585-
&& fanout_net->driver_pin->node->type != FF_NODE) {
586-
/* This one has been visited by everyone */
587-
if (fanout_net->driver_pin->node->backward_level == -1) {
588-
/* already added to a list...this means that we won't have the correct ordering */
589-
netlist->backward_levels[cur_back_level + 1] = (nnode_t**)vtr::realloc(netlist->backward_levels[cur_back_level + 1], sizeof(nnode_t*) * (netlist->num_at_backward_level[cur_back_level + 1] + 1));
590-
netlist->backward_levels[cur_back_level + 1][netlist->num_at_backward_level[cur_back_level + 1]] = fanout_net->driver_pin->node;
591-
netlist->num_at_backward_level[cur_back_level + 1]++;
582+
if (all_visited) {
583+
for (k = 0; k < fanout_net->num_driver_pins; k++) {
584+
if (!fanout_net->driver_pins[k]->node || fanout_net->driver_pins[k]->node->type == FF_NODE)
585+
continue;
586+
/* This one has been visited by everyone */
587+
if (fanout_net->driver_pins[k]->node->backward_level == -1) {
588+
/* already added to a list...this means that we won't have the correct ordering */
589+
netlist->backward_levels[cur_back_level + 1] = (nnode_t**)vtr::realloc(netlist->backward_levels[cur_back_level + 1], sizeof(nnode_t*) * (netlist->num_at_backward_level[cur_back_level + 1] + 1));
590+
netlist->backward_levels[cur_back_level + 1][netlist->num_at_backward_level[cur_back_level + 1]] = fanout_net->driver_pins[k]->node;
591+
netlist->num_at_backward_level[cur_back_level + 1]++;
592+
}
593+
594+
fanout_net->driver_pins[k]->node->backward_level = cur_back_level + 1;
592595
}
593-
594-
fanout_net->driver_pin->node->backward_level = cur_back_level + 1;
595596
}
596597
}
597598
}
@@ -685,35 +686,43 @@ void levelize_backwards_clean_checking_for_liveness(short ast_based, netlist_t*
685686
* (function: find_node_at_top_of_combo_loop)
686687
*-------------------------------------------------------------------------------------------*/
687688
nnode_t* find_node_at_top_of_combo_loop(nnode_t* start_node) {
688-
int i;
689-
int idx_missed;
690-
nnode_t* next_node = start_node;
691-
int* fanouts_visited;
692-
short all_visited;
689+
int stack_size = 1;
690+
nnode_t** stack = (nnode_t**)vtr::calloc(stack_size, sizeof(nnode_t*));
691+
stack[0] = start_node;
693692

694693
while (true) {
694+
nnode_t* next_node = stack[--stack_size];
695695
oassert(next_node->unique_node_data_id == LEVELIZE);
696-
fanouts_visited = (int*)next_node->node_data;
696+
int* fanouts_visited = (int*)next_node->node_data;
697697
next_node->node_data = NULL;
698698

699699
/* check if they've all been marked */
700-
all_visited = true;
701-
for (i = 0; i < next_node->num_input_pins; i++) {
700+
bool all_visited = true;
701+
int idx_missed = -1;
702+
for (int i = 0; i < next_node->num_input_pins; i++) {
702703
if (fanouts_visited[i] == -1) {
703704
all_visited = false;
704705
idx_missed = i;
705706
break;
706707
}
707708
}
708709

709-
if (all_visited == false) {
710-
if (next_node->input_pins[idx_missed]->net->driver_pin->node->backward_level < next_node->backward_level)
711-
/* IF - the next node has a lower backward level than this node suggests that it is
712-
* closer to primary outputs and not in the combo loop */
713-
return next_node;
710+
if (!all_visited) {
711+
for (int i = 0; i < next_node->input_pins[idx_missed]->net->num_driver_pins; i++) {
712+
if (next_node->input_pins[idx_missed]->net->driver_pins[i]->node->backward_level < next_node->backward_level) {
713+
/* IF - the next node has a lower backward level than this node suggests that it is
714+
* closer to primary outputs and not in the combo loop */
715+
vtr::free(stack);
716+
return next_node;
717+
}
714718

715-
next_node = next_node->input_pins[idx_missed]->net->driver_pin->node;
719+
stack_size++;
720+
stack = (nnode_t**)vtr::realloc(stack, sizeof(nnode_t*) * stack_size);
721+
stack[stack_size - 1] = next_node->input_pins[idx_missed]->net->driver_pins[i]->node;
722+
stack_size++;
723+
}
716724
} else {
725+
vtr::free(stack);
717726
return next_node;
718727
}
719728
}

ODIN_II/SRC/netlist_cleanup.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ void traverse_backward(nnode_t* node) {
7171
node->node_data = VISITED_BACKWARD; // Mark as visited
7272
int i;
7373
for (i = 0; i < node->num_input_pins; i++) {
74-
if (node->input_pins[i]->net->driver_pin) { // ensure this net has a driver (i.e. skip undriven outputs)
75-
traverse_backward(node->input_pins[i]->net->driver_pin->node); // Visit the drivers of this node
74+
for (int j = 0; j < node->input_pins[i]->net->num_driver_pins; j++) { // ensure this net has a driver (i.e. skip undriven outputs)
75+
traverse_backward(node->input_pins[i]->net->driver_pins[j]->node); // Visit the drivers of this node
7676
}
7777
}
7878
}
@@ -109,8 +109,9 @@ void traverse_forward(nnode_t* node, int toplevel, int remove_me) {
109109
else
110110
ADDER_START_NODE = VCC_NODE;
111111
}
112+
oassert(node->input_pins[node->num_input_pins - 1]->net->num_driver_pins == 1);
112113
/* Check if we've found the head of an adder or subtractor chain */
113-
if (node->input_pins[node->num_input_pins - 1]->net->driver_pin->node->type == ADDER_START_NODE) {
114+
if (node->input_pins[node->num_input_pins - 1]->net->driver_pins[0]->node->type == ADDER_START_NODE) {
114115
addsub_list_next = insert_node_list(addsub_list_next, node);
115116
}
116117
}

0 commit comments

Comments
 (0)