Skip to content

Commit e73e889

Browse files
authored
Merge pull request #1779 from verilog-to-routing/rr_spatial_lookup_client_functions
Deploy ``RRGraphBuilder`` in Client Functions to replace the use of ``rr_node_indices``
2 parents f473d09 + 2107cb1 commit e73e889

7 files changed

+160
-70
lines changed

vpr/src/device/rr_spatial_lookup.cpp

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ RRNodeId RRSpatialLookup::find_node(int x,
2929
}
3030

3131
/* Pre-check: the x, y, side and ptc should be non negative numbers! Otherwise, return an invalid id */
32-
if ((0 > x) || (0 > y) || (NUM_SIDES == node_side) || (0 > ptc)) {
32+
if ((x < 0) || (y < 0) || (node_side == NUM_SIDES) || (ptc < 0)) {
3333
return RRNodeId::INVALID();
3434
}
3535

@@ -41,7 +41,7 @@ RRNodeId RRSpatialLookup::find_node(int x,
4141
*/
4242
size_t node_x = x;
4343
size_t node_y = y;
44-
if (CHANX == type) {
44+
if (type == CHANX) {
4545
std::swap(node_x, node_y);
4646
}
4747

@@ -74,6 +74,90 @@ RRNodeId RRSpatialLookup::find_node(int x,
7474
return RRNodeId(rr_node_indices_[type][node_x][node_y][node_side][ptc]);
7575
}
7676

77+
std::vector<RRNodeId> RRSpatialLookup::find_channel_nodes(int x,
78+
int y,
79+
t_rr_type type) const {
80+
/* TODO: The implementation of this API should be worked
81+
* when rr_node_indices adapts RRNodeId natively!
82+
*/
83+
std::vector<RRNodeId> channel_nodes;
84+
85+
/* Pre-check: the x, y, type are valid! Otherwise, return an empty vector */
86+
if ((x < 0 || y < 0) && (type == CHANX || type == CHANY)) {
87+
return channel_nodes;
88+
}
89+
90+
/* Currently need to swap x and y for CHANX because of chan, seg convention
91+
* This is due to that the fast look-up builders uses (y, x) coordinate when
92+
* registering a CHANX node in the look-up
93+
* TODO: Once the builders is reworked for use consistent (x, y) convention,
94+
* the following swapping can be removed
95+
*/
96+
size_t node_x = x;
97+
size_t node_y = y;
98+
if (type == CHANX) {
99+
std::swap(node_x, node_y);
100+
}
101+
102+
VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims());
103+
104+
/* Sanity check to ensure the x, y, side are in range
105+
* - Return a list of valid ids by searching in look-up when all the parameters are in range
106+
* - Return an empty list if any out-of-range is detected
107+
*/
108+
if (size_t(type) >= rr_node_indices_.size()) {
109+
return channel_nodes;
110+
}
111+
112+
if (node_x >= rr_node_indices_[type].dim_size(0)) {
113+
return channel_nodes;
114+
}
115+
116+
if (node_y >= rr_node_indices_[type].dim_size(1)) {
117+
return channel_nodes;
118+
}
119+
120+
/* By default, we always added the channel nodes to the TOP side (to save memory) */
121+
e_side node_side = TOP;
122+
if (node_side >= rr_node_indices_[type].dim_size(2)) {
123+
return channel_nodes;
124+
}
125+
126+
for (const auto& node : rr_node_indices_[type][node_x][node_y][node_side]) {
127+
if (RRNodeId(node)) {
128+
channel_nodes.push_back(RRNodeId(node));
129+
}
130+
}
131+
132+
return channel_nodes;
133+
}
134+
135+
std::vector<RRNodeId> RRSpatialLookup::find_nodes_at_all_sides(int x,
136+
int y,
137+
t_rr_type rr_type,
138+
int ptc) const {
139+
std::vector<RRNodeId> indices;
140+
141+
/* TODO: Consider to access the raw data like find_node() rather than calling find_node() many times, which hurts runtime */
142+
if (rr_type == IPIN || rr_type == OPIN) {
143+
//For pins we need to look at all the sides of the current grid tile
144+
for (e_side side : SIDES) {
145+
RRNodeId rr_node_index = find_node(x, y, rr_type, ptc, side);
146+
if (rr_node_index) {
147+
indices.push_back(rr_node_index);
148+
}
149+
}
150+
} else {
151+
//Sides do not effect non-pins so there should only be one per ptc
152+
RRNodeId rr_node_index = find_node(x, y, rr_type, ptc);
153+
if (rr_node_index) {
154+
indices.push_back(rr_node_index);
155+
}
156+
}
157+
158+
return indices;
159+
}
160+
77161
void RRSpatialLookup::add_node(RRNodeId node,
78162
int x,
79163
int y,
@@ -112,8 +196,8 @@ void RRSpatialLookup::resize_nodes(int x,
112196
* should ensure the fast look-up well organized
113197
*/
114198
VTR_ASSERT(type < rr_node_indices_.size());
115-
VTR_ASSERT(0 <= x);
116-
VTR_ASSERT(0 <= y);
199+
VTR_ASSERT(x >= 0);
200+
VTR_ASSERT(y >= 0);
117201

118202
if ((x >= int(rr_node_indices_[type].dim_size(0)))
119203
|| (y >= int(rr_node_indices_[type].dim_size(1)))

vpr/src/device/rr_spatial_lookup.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,34 @@ class RRSpatialLookup {
6363
int ptc,
6464
e_side side = NUM_SIDES) const;
6565

66+
/**
67+
* Returns the indices of the specified routing resource nodes,
68+
* representing routing tracks in a channel.
69+
* - (x, y) are the coordinate of the routing channel within the FPGA
70+
* - rr_type specifies the type of routing channel, either x-direction or y-direction
71+
*
72+
* Note:
73+
* - Return an empty list if there are no routing channel at the given (x, y) location
74+
* - The node list returned only contain valid ids
75+
* For example, if the 2nd routing track does not exist in a routing channel at (x, y) location,
76+
* while the 3rd routing track does exist in a routing channel at (x, y) location,
77+
* the node list will not contain the node for the 2nd routing track, but the 2nd element in the list
78+
* will be the node for the 3rd routing track
79+
*/
80+
std::vector<RRNodeId> find_channel_nodes(int x,
81+
int y,
82+
t_rr_type type) const;
83+
84+
/**
85+
* Like find_node() but returns all matching nodes on all the sides.
86+
* This is particularly useful for getting all instances
87+
* of a specific IPIN/OPIN at a specific gird tile (x,y) location.
88+
*/
89+
std::vector<RRNodeId> find_nodes_at_all_sides(int x,
90+
int y,
91+
t_rr_type rr_type,
92+
int ptc) const;
93+
6694
/* -- Mutators -- */
6795
public:
6896
/**

vpr/src/pack/post_routing_pb_pin_fixup.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static void update_cluster_pin_with_post_routing_results(const DeviceContext& de
5555
const int& sub_tile_z,
5656
size_t& num_mismatches,
5757
const bool& verbose) {
58+
const auto& node_lookup = device_ctx.rr_graph.node_lookup();
5859
/* Handle each pin */
5960
auto logical_block = clustering_ctx.clb_nlist.block_type(blk_id);
6061
auto physical_tile = device_ctx.grid[grid_coord.x()][grid_coord.y()].type;
@@ -152,12 +153,10 @@ static void update_cluster_pin_with_post_routing_results(const DeviceContext& de
152153
short valid_routing_net_cnt = 0;
153154
for (const e_side& pin_side : pin_sides) {
154155
/* Find the net mapped to this pin in routing results */
155-
const int& rr_node = get_rr_node_index(device_ctx.rr_node_indices,
156-
grid_coord.x(), grid_coord.y(),
157-
rr_node_type, physical_pin, pin_side);
156+
RRNodeId rr_node = node_lookup.find_node(grid_coord.x(), grid_coord.y(), rr_node_type, physical_pin, pin_side);
158157

159158
/* Bypass invalid nodes, after that we must have a valid rr_node id */
160-
if (OPEN == rr_node) {
159+
if (!rr_node) {
161160
continue;
162161
}
163162
VTR_ASSERT((size_t)rr_node < device_ctx.rr_nodes.size());
@@ -179,19 +178,19 @@ static void update_cluster_pin_with_post_routing_results(const DeviceContext& de
179178
* - A invalid net id (others should be all invalid as well)
180179
* assume that this pin is not used by router
181180
*/
182-
if (rr_node_nets[RRNodeId(rr_node)]) {
181+
if (rr_node_nets[rr_node]) {
183182
if (routing_net_id) {
184-
if (routing_net_id != rr_node_nets[RRNodeId(rr_node)]) {
183+
if (routing_net_id != rr_node_nets[rr_node]) {
185184
VTR_LOG_ERROR("Pin '%s' is mapped to two nets: '%s' and '%s'\n",
186185
pb_graph_pin->to_string().c_str(),
187186
clustering_ctx.clb_nlist.net_name(routing_net_id).c_str(),
188-
clustering_ctx.clb_nlist.net_name(rr_node_nets[RRNodeId(rr_node)]).c_str());
187+
clustering_ctx.clb_nlist.net_name(rr_node_nets[rr_node]).c_str());
189188
}
190-
VTR_ASSERT(routing_net_id == rr_node_nets[RRNodeId(rr_node)]);
189+
VTR_ASSERT(routing_net_id == rr_node_nets[rr_node]);
191190
}
192-
routing_net_id = rr_node_nets[RRNodeId(rr_node)];
191+
routing_net_id = rr_node_nets[rr_node];
193192
valid_routing_net_cnt++;
194-
visited_rr_nodes.push_back(RRNodeId(rr_node));
193+
visited_rr_nodes.push_back(rr_node);
195194
}
196195
}
197196

vpr/src/place/timing_place_lookup.cpp

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct,
143143
int to_pin_class,
144144
int* src_rr,
145145
int* sink_rr,
146-
std::vector<int>* scratch);
146+
std::vector<RRNodeId>* scratch);
147147

148148
static bool verify_delta_delays(const vtr::Matrix<float>& delta_delays);
149149

@@ -956,12 +956,13 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct,
956956
int to_pin_class,
957957
int* src_rr,
958958
int* sink_rr,
959-
std::vector<int>* scratch) {
959+
std::vector<RRNodeId>* scratch) {
960960
VTR_ASSERT(from_type != nullptr);
961961
VTR_ASSERT(to_type != nullptr);
962962

963963
auto& device_ctx = g_vpr_ctx.device();
964964
auto& grid = device_ctx.grid;
965+
const auto& node_lookup = device_ctx.rr_graph.node_lookup();
965966

966967
//Search the grid for an instance of from/to blocks which satisfy this direct connect offsets,
967968
//and which has the appropriate pins
@@ -979,12 +980,11 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct,
979980
//(with multi-width/height blocks pins may not exist at all locations)
980981
bool from_pin_found = false;
981982
if (direct->from_side != NUM_SIDES) {
982-
RRNodeId from_pin_rr = device_ctx.rr_graph.node_lookup().find_node(from_x, from_y, OPIN, from_pin, direct->from_side);
983+
RRNodeId from_pin_rr = node_lookup.find_node(from_x, from_y, OPIN, from_pin, direct->from_side);
983984
from_pin_found = (from_pin_rr != RRNodeId::INVALID());
984985
} else {
985-
std::vector<int>& from_pin_rrs = *scratch;
986-
get_rr_node_indices(device_ctx.rr_node_indices, from_x, from_y, OPIN, from_pin, &from_pin_rrs);
987-
from_pin_found = !from_pin_rrs.empty();
986+
(*scratch) = node_lookup.find_nodes_at_all_sides(from_x, from_y, OPIN, from_pin);
987+
from_pin_found = !(*scratch).empty();
988988
}
989989
if (!from_pin_found) continue;
990990

@@ -997,12 +997,11 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct,
997997
//(with multi-width/height blocks pins may not exist at all locations)
998998
bool to_pin_found = false;
999999
if (direct->to_side != NUM_SIDES) {
1000-
RRNodeId to_pin_rr = device_ctx.rr_graph.node_lookup().find_node(to_x, to_y, IPIN, to_pin, direct->to_side);
1000+
RRNodeId to_pin_rr = node_lookup.find_node(to_x, to_y, IPIN, to_pin, direct->to_side);
10011001
to_pin_found = (to_pin_rr != RRNodeId::INVALID());
10021002
} else {
1003-
std::vector<int>& to_pin_rrs = *scratch;
1004-
get_rr_node_indices(device_ctx.rr_node_indices, to_x, to_y, IPIN, to_pin, &to_pin_rrs);
1005-
to_pin_found = !to_pin_rrs.empty();
1003+
(*scratch) = node_lookup.find_nodes_at_all_sides(to_x, to_y, IPIN, to_pin);
1004+
to_pin_found = !(*scratch).empty();
10061005
}
10071006
if (!to_pin_found) continue;
10081007

@@ -1039,17 +1038,15 @@ static bool find_direct_connect_sample_locations(const t_direct_inf* direct,
10391038
//
10401039

10411040
{
1042-
std::vector<int>& source_rr_nodes = *scratch;
1043-
get_rr_node_indices(device_ctx.rr_node_indices, from_x, from_y, SOURCE, from_pin_class, &source_rr_nodes);
1044-
VTR_ASSERT(source_rr_nodes.size() > 0);
1045-
*src_rr = source_rr_nodes[0];
1041+
(*scratch) = node_lookup.find_nodes_at_all_sides(from_x, from_y, SOURCE, from_pin_class);
1042+
VTR_ASSERT((*scratch).size() > 0);
1043+
*src_rr = size_t((*scratch)[0]);
10461044
}
10471045

10481046
{
1049-
std::vector<int>& sink_rr_nodes = *scratch;
1050-
get_rr_node_indices(device_ctx.rr_node_indices, to_x, to_y, SINK, to_pin_class, &sink_rr_nodes);
1051-
VTR_ASSERT(sink_rr_nodes.size() > 0);
1052-
*sink_rr = sink_rr_nodes[0];
1047+
(*scratch) = node_lookup.find_nodes_at_all_sides(to_x, to_y, SINK, to_pin_class);
1048+
VTR_ASSERT((*scratch).size() > 0);
1049+
*sink_rr = size_t((*scratch)[0]);
10531050
}
10541051

10551052
return true;
@@ -1082,7 +1079,7 @@ void OverrideDelayModel::compute_override_delay_model(
10821079

10831080
//Look at all the direct connections that exist, and add overrides to delay model
10841081
auto& device_ctx = g_vpr_ctx.device();
1085-
std::vector<int> scratch;
1082+
std::vector<RRNodeId> scratch;
10861083
for (int idirect = 0; idirect < device_ctx.arch->num_directs; ++idirect) {
10871084
const t_direct_inf* direct = &device_ctx.arch->Directs[idirect];
10881085

vpr/src/route/route_common.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ static t_trace_branch traceback_branch(int node, int target_net_pin_index, std::
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

93-
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t_rr_node_indices& L_rr_node_indices);
94-
static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const t_rr_node_indices& L_rr_node_indices);
93+
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const RRGraphView& rr_graph);
94+
static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const RRGraphView& rr_graph);
9595

9696
static t_clb_opins_used alloc_and_load_clb_opins_used_locally();
9797
static void adjust_one_rr_occ_and_acc_cost(int inode, int add_or_sub, float acc_fac);
@@ -480,10 +480,10 @@ void init_route_structs(int bb_factor) {
480480
route_ctx.trace_nodes.resize(cluster_ctx.clb_nlist.nets().size());
481481

482482
//Various look-ups
483-
route_ctx.net_rr_terminals = load_net_rr_terminals(device_ctx.rr_node_indices);
483+
route_ctx.net_rr_terminals = load_net_rr_terminals(device_ctx.rr_graph);
484484
route_ctx.is_clock_net = load_is_clock_net();
485485
route_ctx.route_bb = load_route_bb(bb_factor);
486-
route_ctx.rr_blk_source = load_rr_clb_sources(device_ctx.rr_node_indices);
486+
route_ctx.rr_blk_source = load_rr_clb_sources(device_ctx.rr_graph);
487487
route_ctx.clb_opins_used_locally = alloc_and_load_clb_opins_used_locally();
488488
route_ctx.net_status.resize(cluster_ctx.clb_nlist.nets().size());
489489
}
@@ -969,7 +969,7 @@ void reset_rr_node_route_structs() {
969969
/* Allocates and loads the route_ctx.net_rr_terminals data structure. For each net it stores the rr_node *
970970
* index of the SOURCE of the net and all the SINKs of the net [clb_nlist.nets()][clb_nlist.net_pins()]. *
971971
* Entry [inet][pnum] stores the rr index corresponding to the SOURCE (opin) or SINK (ipin) of the pin. */
972-
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t_rr_node_indices& L_rr_node_indices) {
972+
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const RRGraphView& rr_graph) {
973973
vtr::vector<ClusterNetId, std::vector<int>> net_rr_terminals;
974974

975975
auto& cluster_ctx = g_vpr_ctx.clustering();
@@ -996,9 +996,9 @@ static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t
996996

997997
int iclass = type->pin_class[phys_pin];
998998

999-
int inode = get_rr_node_index(L_rr_node_indices, i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
1000-
iclass);
1001-
net_rr_terminals[net_id][pin_count] = inode;
999+
RRNodeId inode = rr_graph.node_lookup().find_node(i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
1000+
iclass);
1001+
net_rr_terminals[net_id][pin_count] = size_t(inode);
10021002
pin_count++;
10031003
}
10041004
}
@@ -1011,10 +1011,10 @@ static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t
10111011
* they are used only to reserve pins for locally used OPINs in the router. *
10121012
* [0..cluster_ctx.clb_nlist.blocks().size()-1][0..num_class-1]. *
10131013
* The values for blocks that are padsare NOT valid. */
1014-
static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const t_rr_node_indices& L_rr_node_indices) {
1014+
static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const RRGraphView& rr_graph) {
10151015
vtr::vector<ClusterBlockId, std::vector<int>> rr_blk_source;
10161016

1017-
int i, j, iclass, inode;
1017+
int i, j, iclass;
10181018
t_rr_type rr_type;
10191019

10201020
auto& cluster_ctx = g_vpr_ctx.clustering();
@@ -1039,8 +1039,8 @@ static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const t
10391039
else
10401040
rr_type = SINK;
10411041

1042-
inode = get_rr_node_index(L_rr_node_indices, i, j, rr_type, iclass);
1043-
rr_blk_source[blk_id][iclass] = inode;
1042+
RRNodeId inode = rr_graph.node_lookup().find_node(i, j, rr_type, iclass);
1043+
rr_blk_source[blk_id][iclass] = size_t(inode);
10441044
} else {
10451045
rr_blk_source[blk_id][iclass] = OPEN;
10461046
}

0 commit comments

Comments
 (0)