Skip to content

Commit c93941d

Browse files
authored
Merge pull request #1508 from verilog-to-routing/refactor_rt_node
Refactor rt node
2 parents 9a13433 + 45f5623 commit c93941d

16 files changed

+191
-165
lines changed

utils/route_diag/src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static void do_one_route(int source_node, int sink_node,
112112
if (found_path) {
113113
VTR_ASSERT(cheapest.index == sink_node);
114114

115-
t_rt_node* rt_node_of_sink = update_route_tree(&cheapest, nullptr);
115+
t_rt_node* rt_node_of_sink = update_route_tree(&cheapest, OPEN, nullptr);
116116

117117
//find delay
118118
float net_delay = rt_node_of_sink->Tdel;

vpr/src/base/read_route.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
216216

217217
/*remember the position of the last line in order to go back*/
218218
std::streampos oldpos = fp.tellg();
219-
int inode, x, y, x2, y2, ptc, switch_id, offset;
219+
int inode, x, y, x2, y2, ptc, switch_id, net_pin_index, offset;
220220
std::string prev_type;
221221
int node_count = 0;
222222
std::string input;
@@ -348,10 +348,26 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
348348
switch_id = atoi(tokens[7 + offset].c_str());
349349
}
350350

351+
/* Process net pin index for sinks *
352+
* If you have an old .route file, it may not have this information *
353+
* Please check your .route file to see if it contains Net_pin_index *
354+
* information for sinks. If not, plrase re-generate the routing. */
355+
if (tokens[2] == "SINK") {
356+
if (tokens[8 + offset] == "Net_pin_index:") {
357+
net_pin_index = atoi(tokens[9 + offset].c_str());
358+
} else {
359+
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
360+
"%d (sink) node does not have net pin index. If you are using an old .route file without this information, please re-generate the routing.", inode);
361+
}
362+
} else {
363+
net_pin_index = OPEN; //net pin index is invalid for non-SINKs
364+
}
365+
351366
/* Allocate and load correct values to trace.head*/
352367
if (node_count == 0) {
353368
route_ctx.trace[inet].head = alloc_trace_data();
354369
route_ctx.trace[inet].head->index = inode;
370+
route_ctx.trace[inet].head->net_pin_index = net_pin_index;
355371
route_ctx.trace[inet].head->iswitch = switch_id;
356372
route_ctx.trace[inet].head->next = nullptr;
357373
tptr = route_ctx.trace[inet].head;
@@ -360,6 +376,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
360376
tptr->next = alloc_trace_data();
361377
tptr = tptr->next;
362378
tptr->index = inode;
379+
tptr->net_pin_index = net_pin_index;
363380
tptr->iswitch = switch_id;
364381
tptr->next = nullptr;
365382
node_count++;

vpr/src/base/vpr_types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,16 @@ typedef std::array<vtr::NdMatrix<std::vector<int>, 3>, NUM_RR_TYPES> t_rr_node_i
13441344
* @brief Basic element used to store the traceback (routing) of each net.
13451345
*
13461346
* @param index Array index (ID) of this routing resource node.
1347+
* @param net_pin_index: Net pin index associated with the node. This value
1348+
* ranges from 1 to fanout [1..num_pins-1]. For cases when
1349+
* different speed paths are taken to the same SINK for
1350+
* different pins, node index cannot uniquely identify
1351+
* each SINK, so the net pin index guarantees an unique
1352+
* identification for each SINK node. For non-SINK nodes
1353+
* and for SINK nodes with no associated net pin index
1354+
* (i.e. special SINKs like the source of a clock tree
1355+
* which do not correspond to an actual netlist connection),
1356+
* the value for this member should be set to OPEN (-1).
13471357
* @param iswitch Index of the switch type used to go from this rr_node to
13481358
* the next one in the routing. OPEN if there is no next node
13491359
* (i.e. this node is the last one (a SINK) in a branch of the
@@ -1353,6 +1363,7 @@ typedef std::array<vtr::NdMatrix<std::vector<int>, 3>, NUM_RR_TYPES> t_rr_node_i
13531363
struct t_trace {
13541364
t_trace* next;
13551365
int index;
1366+
int net_pin_index = OPEN;
13561367
short iswitch;
13571368
};
13581369

vpr/src/route/check_route.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,7 @@ static void check_sink(int inode, ClusterNetId net_id, bool* pin_done) {
190190
int ptc_num = device_ctx.rr_nodes[inode].ptc_num();
191191
int ifound = 0;
192192

193-
for (int iblk = 0; iblk < type->capacity; iblk++) {
194-
ClusterBlockId bnum = place_ctx.grid_blocks[i][j].blocks[iblk]; /* Hardcoded to one cluster_ctx block*/
193+
for (auto bnum : place_ctx.grid_blocks[i][j].blocks) {
195194
unsigned int ipin = 1;
196195
for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
197196
if (cluster_ctx.clb_nlist.pin_block(pin_id) == bnum) {
@@ -203,17 +202,15 @@ static void check_sink(int inode, ClusterNetId net_id, bool* pin_done) {
203202
if (pin_done[ipin] == false) {
204203
ifound++;
205204
pin_done[ipin] = true;
205+
break;
206206
}
207207
}
208208
}
209209
ipin++;
210210
}
211211
}
212212

213-
if (ifound > 1 && is_io_type(type)) {
214-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
215-
"in check_sink: found %d terminals of net %d of pad %d at location (%d, %d).\n", ifound, size_t(net_id), ptc_num, i, j);
216-
}
213+
VTR_ASSERT(ifound <= 1);
217214

218215
if (ifound < 1) {
219216
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,

vpr/src/route/connection_based_routing.cpp

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ Connection_based_routing_resources::Connection_based_routing_resources()
1212
, connection_criticality_tolerance{0.9f}
1313
, connection_delay_optimality_tolerance{1.1f} {
1414
/* Initialize the persistent data structures for incremental rerouting
15-
* this includes rr_sink_node_to_pin, which provides pin lookup given a
16-
* sink node for a specific net.
1715
*
1816
* remaining_targets will reserve enough space to ensure it won't need
1917
* to grow while storing the sinks that still need routing after pruning
@@ -31,89 +29,26 @@ Connection_based_routing_resources::Connection_based_routing_resources()
3129
reached_rt_sinks.reserve(max_sink_pins_per_net);
3230

3331
size_t routing_num_nets = cluster_ctx.clb_nlist.nets().size();
34-
rr_sink_node_to_pin.resize(routing_num_nets);
3532
lower_bound_connection_delay.resize(routing_num_nets);
3633
forcible_reroute_connection_flag.resize(routing_num_nets);
3734

3835
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
39-
// unordered_map<int,int> net_node_to_pin;
40-
auto& net_node_to_pin = rr_sink_node_to_pin[net_id];
4136
auto& net_lower_bound_connection_delay = lower_bound_connection_delay[net_id];
4237
auto& net_forcible_reroute_connection_flag = forcible_reroute_connection_flag[net_id];
4338

44-
unsigned int num_pins = cluster_ctx.clb_nlist.net_pins(net_id).size();
45-
net_node_to_pin.reserve(num_pins); // not looking up on the SOURCE pin
39+
unsigned int num_pins = cluster_ctx.clb_nlist.net_pins(net_id).size(); // not looking up on the SOURCE pin
4640
net_lower_bound_connection_delay.resize(num_pins, std::numeric_limits<float>::infinity()); // will be filled in after the 1st iteration's
4741
net_forcible_reroute_connection_flag.reserve(num_pins); // all false to begin with
4842

4943
for (unsigned int ipin = 1; ipin < num_pins; ++ipin) {
5044
// rr sink node index corresponding to this connection terminal
5145
auto rr_sink_node = route_ctx.net_rr_terminals[net_id][ipin];
5246

53-
net_node_to_pin.insert({rr_sink_node, ipin});
5447
net_forcible_reroute_connection_flag.insert({rr_sink_node, false});
5548
}
5649
}
5750
}
5851

59-
void Connection_based_routing_resources::convert_sink_nodes_to_net_pins(std::vector<int>& rr_sink_nodes) const {
60-
/* Turn a vector of device_ctx.rr_nodes indices, assumed to be of sinks for a net *
61-
* into the pin indices of the same net. */
62-
63-
VTR_ASSERT(current_inet != ClusterNetId::INVALID()); // not uninitialized
64-
65-
const auto& node_to_pin_mapping = rr_sink_node_to_pin[current_inet];
66-
67-
for (size_t s = 0; s < rr_sink_nodes.size(); ++s) {
68-
auto mapping = node_to_pin_mapping.find(rr_sink_nodes[s]);
69-
if (mapping != node_to_pin_mapping.end()) {
70-
rr_sink_nodes[s] = mapping->second;
71-
} else {
72-
VTR_ASSERT_SAFE_MSG(false, "Should always expect it find a pin mapping for its own net");
73-
}
74-
}
75-
}
76-
77-
void Connection_based_routing_resources::put_sink_rt_nodes_in_net_pins_lookup(const std::vector<t_rt_node*>& sink_rt_nodes,
78-
t_rt_node** rt_node_of_sink) const {
79-
/* Load rt_node_of_sink (which maps a PIN index to a route tree node)
80-
* with a vector of route tree sink nodes. */
81-
82-
VTR_ASSERT(current_inet != ClusterNetId::INVALID());
83-
84-
// a net specific mapping from node index to pin index
85-
const auto& node_to_pin_mapping = rr_sink_node_to_pin[current_inet];
86-
87-
for (t_rt_node* rt_node : sink_rt_nodes) {
88-
auto mapping = node_to_pin_mapping.find(rt_node->inode);
89-
90-
if (mapping != node_to_pin_mapping.end()) {
91-
rt_node_of_sink[mapping->second] = rt_node;
92-
} else {
93-
VTR_ASSERT_SAFE_MSG(false, "element should be able to find itself");
94-
}
95-
}
96-
}
97-
98-
bool Connection_based_routing_resources::sanity_check_lookup() const {
99-
auto& cluster_ctx = g_vpr_ctx.clustering();
100-
auto& route_ctx = g_vpr_ctx.routing();
101-
102-
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
103-
const auto& net_node_to_pin = rr_sink_node_to_pin[net_id];
104-
105-
for (auto mapping : net_node_to_pin) {
106-
auto sanity = net_node_to_pin.find(mapping.first);
107-
if (sanity == net_node_to_pin.end()) {
108-
VTR_LOG("%d cannot find itself (net %lu)\n", mapping.first, size_t(net_id));
109-
return false;
110-
}
111-
VTR_ASSERT(route_ctx.net_rr_terminals[net_id][mapping.second] == mapping.first);
112-
}
113-
}
114-
return true;
115-
}
116-
11752
void Connection_based_routing_resources::set_lower_bound_connection_delays(ClbNetPinsMatrix<float>& net_delay) {
11853
/* Set the lower bound connection delays after first iteration, which only optimizes for timing delay.
11954
* This will be used later to judge the optimality of a connection, with suboptimal ones being candidates

vpr/src/route/connection_based_routing.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515
// reroute only the connections to the ones that did not have a legal connection the previous time
1616
class Connection_based_routing_resources {
1717
// Incremental reroute resources --------------
18-
// conceptually works like rr_sink_node_to_pin[inet][sink_rr_node_index] to get the pin index for that net
19-
// each net maps SINK node index -> PIN index for net
20-
// only need to be built once at the start since the SINK nodes never change
21-
// the reverse lookup of route_ctx.net_rr_terminals
22-
vtr::vector<ClusterNetId, std::unordered_map<int, int>> rr_sink_node_to_pin;
2318

2419
// a property of each net, but only valid after pruning the previous route tree
2520
// the "targets" in question can be either rr_node indices or pin indices, the
@@ -43,11 +38,6 @@ class Connection_based_routing_resources {
4338
std::vector<int>& get_remaining_targets() { return remaining_targets; }
4439
std::vector<t_rt_node*>& get_reached_rt_sinks() { return reached_rt_sinks; }
4540

46-
void convert_sink_nodes_to_net_pins(std::vector<int>& rr_sink_nodes) const;
47-
48-
void put_sink_rt_nodes_in_net_pins_lookup(const std::vector<t_rt_node*>& sink_rt_nodes,
49-
t_rt_node** rt_node_of_sink) const;
50-
5141
bool sanity_check_lookup() const;
5242

5343
void set_connection_criticality_tolerance(float val) { connection_criticality_tolerance = val; }

vpr/src/route/route_breadth_first.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ static bool breadth_first_route_net(BinaryHeap& heap, ClusterNetId net_id, float
265265

266266
route_ctx.rr_node_route_inf[inode].target_flag--; /* Connected to this SINK. */
267267
remaining_connections_to_sink = route_ctx.rr_node_route_inf[inode].target_flag;
268-
tptr = update_traceback(current, net_id);
268+
size_t ipin = cluster_ctx.clb_nlist.pin_net_index(pin_id);
269+
tptr = update_traceback(current, ipin, net_id);
269270
heap.free(current);
270271
}
271272

vpr/src/route/route_common.cpp

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static int num_linked_f_pointer_allocated = 0;
8686
* */
8787

8888
/******************** Subroutines local to route_common.c *******************/
89-
static t_trace_branch traceback_branch(int node, std::unordered_set<int>& main_branch_visited);
89+
static t_trace_branch traceback_branch(int node, int target_net_pin_index, std::unordered_set<int>& main_branch_visited);
9090
static std::pair<t_trace*, t_trace*> add_trace_non_configurable(t_trace* head, t_trace* tail, int node, std::unordered_set<int>& visited);
9191
static std::pair<t_trace*, t_trace*> add_trace_non_configurable_recurr(int node, std::unordered_set<int>& visited, int depth = 0);
9292

@@ -484,26 +484,28 @@ void init_route_structs(int bb_factor) {
484484
route_ctx.net_status.resize(cluster_ctx.clb_nlist.nets().size());
485485
}
486486

487-
t_trace* update_traceback(t_heap* hptr, ClusterNetId net_id) {
488-
/* This routine adds the most recently finished wire segment to the *
489-
* traceback linked list. The first connection starts with the net SOURCE *
490-
* and begins at the structure pointed to by route_ctx.trace[net_id].head. *
491-
* Each connection ends with a SINK. After each SINK, the next connection *
492-
* begins (if the net has more than 2 pins). The first element after the *
493-
* SINK gives the routing node on a previous piece of the routing, which is *
494-
* the link from the existing net to this new piece of the net. *
495-
* In each traceback I start at the end of a path and trace back through *
496-
* its predecessors to the beginning. I have stored information on the *
497-
* predecesser of each node to make traceback easy -- this sacrificies some *
498-
* memory for easier code maintenance. This routine returns a pointer to *
499-
* the first "new" node in the traceback (node not previously in trace). */
487+
/* This routine adds the most recently finished wire segment to the *
488+
* traceback linked list. The first connection starts with the net SOURCE *
489+
* and begins at the structure pointed to by route_ctx.trace[net_id].head. *
490+
* Each connection ends with a SINK. After each SINK, the next connection *
491+
* begins (if the net has more than 2 pins). The first element after the *
492+
* SINK gives the routing node on a previous piece of the routing, which is *
493+
* the link from the existing net to this new piece of the net. *
494+
* In each traceback I start at the end of a path, which is a SINK with *
495+
* target_net_pin_index (net pin index corresponding to the SINK, ranging *
496+
* from 1 to fanout), and trace back through its predecessors to the *
497+
* beginning. I have stored information on the predecesser of each node to *
498+
* make traceback easy -- this sacrificies some memory for easier code *
499+
* maintenance. This routine returns a pointer to the first "new" node in *
500+
* the traceback (node not previously in trace). */
501+
t_trace* update_traceback(t_heap* hptr, int target_net_pin_index, ClusterNetId net_id) {
500502
auto& route_ctx = g_vpr_ctx.mutable_routing();
501503

502504
auto& trace_nodes = route_ctx.trace_nodes[net_id];
503505

504506
VTR_ASSERT_SAFE(validate_trace_nodes(route_ctx.trace[net_id].head, trace_nodes));
505507

506-
t_trace_branch branch = traceback_branch(hptr->index, trace_nodes);
508+
t_trace_branch branch = traceback_branch(hptr->index, target_net_pin_index, trace_nodes);
507509

508510
VTR_ASSERT_SAFE(validate_trace_nodes(branch.head, trace_nodes));
509511

@@ -520,9 +522,10 @@ t_trace* update_traceback(t_heap* hptr, ClusterNetId net_id) {
520522
return (ret_ptr);
521523
}
522524

523-
//Traces back a new routing branch starting from the specified 'node' and working backwards to any existing routing.
525+
//Traces back a new routing branch starting from the specified SINK 'node' with target_net_pin_index, which is the
526+
//net pin index corresponding to the SINK (ranging from 1 to fanout), and working backwards to any existing routing.
524527
//Returns the new branch, and also updates trace_nodes for any new nodes which are included in the branches traceback.
525-
static t_trace_branch traceback_branch(int node, std::unordered_set<int>& trace_nodes) {
528+
static t_trace_branch traceback_branch(int node, int target_net_pin_index, std::unordered_set<int>& trace_nodes) {
526529
auto& device_ctx = g_vpr_ctx.device();
527530
auto& route_ctx = g_vpr_ctx.routing();
528531

@@ -537,6 +540,7 @@ static t_trace_branch traceback_branch(int node, std::unordered_set<int>& trace_
537540
t_trace* branch_head = alloc_trace_data();
538541
t_trace* branch_tail = branch_head;
539542
branch_head->index = node;
543+
branch_head->net_pin_index = target_net_pin_index; //The first node is the SINK node, so store its net pin index
540544
branch_head->iswitch = OPEN;
541545
branch_head->next = nullptr;
542546

@@ -551,6 +555,7 @@ static t_trace_branch traceback_branch(int node, std::unordered_set<int>& trace_
551555
//Add the current node to the head of traceback
552556
t_trace* prev_ptr = alloc_trace_data();
553557
prev_ptr->index = inode;
558+
prev_ptr->net_pin_index = OPEN; //Net pin index is invalid for Non-SINK nodes
554559
prev_ptr->iswitch = device_ctx.rr_nodes.edge_switch(iedge);
555560
prev_ptr->next = branch_head;
556561
branch_head = prev_ptr;
@@ -731,11 +736,16 @@ void mark_ends(ClusterNetId net_id) {
731736
}
732737
}
733738

734-
void mark_remaining_ends(const std::vector<int>& remaining_sinks) {
739+
void mark_remaining_ends(ClusterNetId net_id, const std::vector<int>& remaining_sinks) {
735740
// like mark_ends, but only performs it for the remaining sinks of a net
741+
int inode;
742+
736743
auto& route_ctx = g_vpr_ctx.mutable_routing();
737-
for (int sink_node : remaining_sinks)
738-
++route_ctx.rr_node_route_inf[sink_node].target_flag;
744+
745+
for (int sink_pin : remaining_sinks) {
746+
inode = route_ctx.net_rr_terminals[net_id][sink_pin];
747+
++route_ctx.rr_node_route_inf[inode].target_flag;
748+
}
739749
}
740750

741751
void drop_traceback_tail(ClusterNetId net_id) {
@@ -1182,6 +1192,7 @@ alloc_trace_data() {
11821192
trace_free_head->next = nullptr;
11831193
}
11841194
temp_ptr = trace_free_head;
1195+
temp_ptr->net_pin_index = OPEN; //default
11851196
trace_free_head = trace_free_head->next;
11861197
num_trace_allocated++;
11871198
return (temp_ptr);
@@ -1276,6 +1287,11 @@ void print_route(FILE* fp, const vtr::vector<ClusterNetId, t_traceback>& traceba
12761287
* used in the routing. */
12771288
fprintf(fp, "Switch: %d", tptr->iswitch);
12781289

1290+
//Save net pin index for sinks
1291+
if (rr_type == SINK) {
1292+
fprintf(fp, " Net_pin_index: %d", tptr->net_pin_index);
1293+
}
1294+
12791295
fprintf(fp, "\n");
12801296

12811297
tptr = tptr->next;

0 commit comments

Comments
 (0)