Skip to content

Commit 78cd631

Browse files
authored
Merge pull request #1801 from verilog-to-routing/rr_graph_clock_refactor
Deploy ``RRGraphBuilder`` in RRGraph Clock Builder to replace the use of ``rr_node_indices``
2 parents c06800f + ab9dc4e commit 78cd631

11 files changed

+148
-185
lines changed

vpr/src/device/rr_spatial_lookup.cpp

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,18 @@ 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 {
77+
std::vector<RRNodeId> RRSpatialLookup::find_nodes(int x,
78+
int y,
79+
t_rr_type type,
80+
e_side side) const {
8081
/* TODO: The implementation of this API should be worked
8182
* when rr_node_indices adapts RRNodeId natively!
8283
*/
83-
std::vector<RRNodeId> channel_nodes;
84+
std::vector<RRNodeId> nodes;
8485

8586
/* 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;
87+
if (x < 0 || y < 0) {
88+
return nodes;
8889
}
8990

9091
/* Currently need to swap x and y for CHANX because of chan, seg convention
@@ -106,30 +107,44 @@ std::vector<RRNodeId> RRSpatialLookup::find_channel_nodes(int x,
106107
* - Return an empty list if any out-of-range is detected
107108
*/
108109
if (size_t(type) >= rr_node_indices_.size()) {
109-
return channel_nodes;
110+
return nodes;
110111
}
111112

112113
if (node_x >= rr_node_indices_[type].dim_size(0)) {
113-
return channel_nodes;
114+
return nodes;
114115
}
115116

116117
if (node_y >= rr_node_indices_[type].dim_size(1)) {
117-
return channel_nodes;
118+
return nodes;
118119
}
119120

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;
121+
if (side >= rr_node_indices_[type].dim_size(2)) {
122+
return nodes;
124123
}
125124

126-
for (const auto& node : rr_node_indices_[type][node_x][node_y][node_side]) {
125+
for (const auto& node : rr_node_indices_[type][node_x][node_y][side]) {
127126
if (RRNodeId(node)) {
128-
channel_nodes.push_back(RRNodeId(node));
127+
nodes.push_back(RRNodeId(node));
129128
}
130129
}
131130

132-
return channel_nodes;
131+
return nodes;
132+
}
133+
134+
std::vector<RRNodeId> RRSpatialLookup::find_channel_nodes(int x,
135+
int y,
136+
t_rr_type type) const {
137+
/* Pre-check: node type should be routing tracks! */
138+
if (type != CHANX && type != CHANY) {
139+
return std::vector<RRNodeId>();
140+
}
141+
142+
return find_nodes(x, y, type);
143+
}
144+
145+
std::vector<RRNodeId> RRSpatialLookup::find_sink_nodes(int x,
146+
int y) const {
147+
return find_nodes(x, y, SINK);
133148
}
134149

135150
std::vector<RRNodeId> RRSpatialLookup::find_nodes_at_all_sides(int x,
@@ -167,6 +182,11 @@ void RRSpatialLookup::add_node(RRNodeId node,
167182
VTR_ASSERT(node); /* Must have a valid node id to be added */
168183
VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims());
169184

185+
/* For non-IPIN/OPIN nodes, the side should always be the TOP side which follows the convention in find_node() API! */
186+
if (type != IPIN && type != OPIN) {
187+
VTR_ASSERT(side == SIDES[0]);
188+
}
189+
170190
resize_nodes(x, y, type, side);
171191

172192
if (size_t(ptc) >= rr_node_indices_[type][x][y][side].size()) {

vpr/src/device/rr_spatial_lookup.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ class RRSpatialLookup {
8181
int y,
8282
t_rr_type type) const;
8383

84+
/**
85+
* Returns the indices of the specified routing resource nodes,
86+
* representing virtual sinks.
87+
* - (x, y) are the coordinate of the sink nodes within the FPGA
88+
*
89+
* Note:
90+
* - Return an empty list if there are no sinks at the given (x, y) location
91+
* - The node list returned only contains valid ids
92+
*/
93+
std::vector<RRNodeId> find_sink_nodes(int x,
94+
int y) const;
95+
8496
/**
8597
* Like find_node() but returns all matching nodes on all the sides.
8698
* This is particularly useful for getting all instances
@@ -118,7 +130,7 @@ class RRSpatialLookup {
118130
int y,
119131
t_rr_type type,
120132
int ptc,
121-
e_side side);
133+
e_side side = SIDES[0]);
122134

123135
/**
124136
* Mirror the last dimension of a look-up, i.e., a list of nodes, from a source coordinate to
@@ -168,6 +180,18 @@ class RRSpatialLookup {
168180
t_rr_type type,
169181
e_side side);
170182

183+
/* -- Internal data queries -- */
184+
private:
185+
/* An internal API to find all the nodes in a specific location with a given type
186+
* For OPIN/IPIN nodes that may exist on multiple sides, a specific side must be provided
187+
* This API is NOT public because its too powerful for developers with very limited sanity checks
188+
* But it is used to build the public APIs find_channel_nodes() etc., where sufficient sanity checks are applied
189+
*/
190+
std::vector<RRNodeId> find_nodes(int x,
191+
int y,
192+
t_rr_type type,
193+
e_side side = SIDES[0]) const;
194+
171195
/* -- Internal data storage -- */
172196
private:
173197
/* TODO: When the refactoring effort finishes,
@@ -179,7 +203,7 @@ class RRSpatialLookup {
179203
* or inside the data structures to be changed later.
180204
* That explains why the reference is used here temporarily
181205
*/
182-
/* Fast look-up */
206+
/* Fast look-up: TODO: Should rework the data type. Currently it is based on a 3-dimensional arrqay mater where some dimensions must always be accessed with a specific index. Such limitation should be overcome */
183207
t_rr_node_indices& rr_node_indices_;
184208
};
185209

vpr/src/route/clock_connection_builders.cpp

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,17 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
5252
std::srand(seed);
5353

5454
auto& device_ctx = g_vpr_ctx.device();
55-
auto& rr_node_indices = device_ctx.rr_node_indices;
55+
const auto& node_lookup = device_ctx.rr_graph.node_lookup();
5656

57-
int virtual_clock_network_root_idx = create_virtual_clock_network_sink_node(switch_location.x, switch_location.y);
57+
RRNodeId virtual_clock_network_root_idx = create_virtual_clock_network_sink_node(switch_location.x, switch_location.y);
5858
{
5959
auto& mut_device_ctx = g_vpr_ctx.mutable_device();
60-
mut_device_ctx.virtual_clock_network_root_idx = virtual_clock_network_root_idx;
60+
mut_device_ctx.virtual_clock_network_root_idx = size_t(virtual_clock_network_root_idx);
6161
}
6262

6363
// rr_node indices for x and y channel routing wires and clock wires to connect to
64-
auto x_wire_indices = get_rr_node_chan_wires_at_location(
65-
rr_node_indices, CHANX, switch_location.x, switch_location.y);
66-
auto y_wire_indices = get_rr_node_chan_wires_at_location(
67-
rr_node_indices, CHANY, switch_location.x, switch_location.y);
64+
auto x_wire_indices = node_lookup.find_channel_nodes(switch_location.x, switch_location.y, CHANX);
65+
auto y_wire_indices = node_lookup.find_channel_nodes(switch_location.x, switch_location.y, CHANY);
6866
auto clock_indices = clock_graph.get_rr_node_indices_at_switch_location(
6967
clock_to_connect_to, switch_point_name, switch_location.x, switch_location.y);
7068

@@ -76,52 +74,53 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
7674
// Connect to x-channel wires
7775
unsigned num_wires_x = x_wire_indices.size() * fc;
7876
for (size_t i = 0; i < num_wires_x; i++) {
79-
clock_graph.add_edge(rr_edges_to_create, x_wire_indices[i], clock_index, arch_switch_idx);
77+
clock_graph.add_edge(rr_edges_to_create, size_t(x_wire_indices[i]), clock_index, arch_switch_idx);
8078
}
8179

8280
// Connect to y-channel wires
8381
unsigned num_wires_y = y_wire_indices.size() * fc;
8482
for (size_t i = 0; i < num_wires_y; i++) {
85-
clock_graph.add_edge(rr_edges_to_create, y_wire_indices[i], clock_index, arch_switch_idx);
83+
clock_graph.add_edge(rr_edges_to_create, size_t(y_wire_indices[i]), clock_index, arch_switch_idx);
8684
}
8785

8886
// Connect to virtual clock sink node
8987
// used by the two stage router
90-
clock_graph.add_edge(rr_edges_to_create, clock_index, virtual_clock_network_root_idx, arch_switch_idx);
88+
clock_graph.add_edge(rr_edges_to_create, clock_index, size_t(virtual_clock_network_root_idx), arch_switch_idx);
9189
}
9290
}
9391

94-
int RoutingToClockConnection::create_virtual_clock_network_sink_node(
95-
int x,
96-
int y) {
92+
RRNodeId RoutingToClockConnection::create_virtual_clock_network_sink_node(int x, int y) {
9793
auto& device_ctx = g_vpr_ctx.mutable_device();
98-
auto& rr_nodes = device_ctx.rr_nodes;
99-
rr_nodes.emplace_back();
100-
auto node_index = rr_nodes.size() - 1;
94+
auto& rr_graph = device_ctx.rr_nodes;
95+
auto& node_lookup = device_ctx.rr_graph_builder.node_lookup();
96+
rr_graph.emplace_back();
97+
RRNodeId node_index = RRNodeId(rr_graph.size() - 1);
10198

10299
//Determine the a valid PTC
103-
std::vector<int> nodes_at_loc;
104-
get_rr_node_indices(device_ctx.rr_node_indices,
105-
x, y,
106-
SINK,
107-
&nodes_at_loc);
100+
std::vector<RRNodeId> nodes_at_loc = node_lookup.find_sink_nodes(x, y);
108101

109102
int max_ptc = 0;
110-
for (int inode : nodes_at_loc) {
111-
max_ptc = std::max<int>(max_ptc, device_ctx.rr_nodes[inode].ptc_num());
103+
for (RRNodeId inode : nodes_at_loc) {
104+
max_ptc = std::max<int>(max_ptc, rr_graph.node_ptc_num(inode));
112105
}
113106
int ptc = max_ptc + 1;
114107

115-
rr_nodes[node_index].set_ptc_num(ptc);
116-
rr_nodes[node_index].set_coordinates(x, y, x, y);
117-
rr_nodes[node_index].set_capacity(1);
118-
rr_nodes[node_index].set_cost_index(SINK_COST_INDEX);
119-
rr_nodes[node_index].set_type(SINK);
108+
rr_graph.set_node_ptc_num(node_index, ptc);
109+
rr_graph.set_node_coordinates(node_index, x, y, x, y);
110+
rr_graph.set_node_capacity(node_index, 1);
111+
rr_graph.set_node_cost_index(node_index, SINK_COST_INDEX);
112+
rr_graph.set_node_type(node_index, SINK);
120113
float R = 0.;
121114
float C = 0.;
122-
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(R, C));
115+
rr_graph.set_node_rc_index(node_index, find_create_rr_rc_data(R, C));
123116

124-
add_to_rr_node_indices(device_ctx.rr_node_indices, rr_nodes, node_index);
117+
// Use a generic way when adding nodes to lookup.
118+
// However, since the SINK node has the same xhigh/xlow as well as yhigh/ylow, we can probably use a shortcut
119+
for (int ix = rr_graph.node_xlow(node_index); ix <= rr_graph.node_xhigh(node_index); ++ix) {
120+
for (int iy = rr_graph.node_ylow(node_index); iy <= rr_graph.node_yhigh(node_index); ++iy) {
121+
node_lookup.add_node(node_index, ix, iy, rr_graph.node_type(node_index), rr_graph.node_ptc_num(node_index));
122+
}
123+
}
125124

126125
return node_index;
127126
}
@@ -243,7 +242,7 @@ size_t ClockToPinsConnection::estimate_additional_nodes() {
243242

244243
void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) {
245244
auto& device_ctx = g_vpr_ctx.device();
246-
auto& rr_node_indices = device_ctx.rr_node_indices;
245+
const auto& node_lookup = device_ctx.rr_graph.node_lookup();
247246
auto& grid = clock_graph.grid();
248247

249248
for (size_t x = 0; x < grid.width(); x++) {
@@ -304,13 +303,11 @@ void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_gra
304303
clock_y_offset = -1; // pick the chanx below the block
305304
}
306305

307-
auto clock_pin_node_idx = get_rr_node_index(
308-
rr_node_indices,
309-
x,
310-
y,
311-
IPIN,
312-
clock_pin_idx,
313-
side);
306+
auto clock_pin_node_idx = node_lookup.find_node(x,
307+
y,
308+
IPIN,
309+
clock_pin_idx,
310+
side);
314311

315312
auto clock_network_indices = clock_graph.get_rr_node_indices_at_switch_location(
316313
clock_to_connect_from,
@@ -320,7 +317,7 @@ void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_gra
320317

321318
//Create edges depending on Fc
322319
for (size_t i = 0; i < clock_network_indices.size() * fc; i++) {
323-
clock_graph.add_edge(rr_edges_to_create, clock_network_indices[i], clock_pin_node_idx, arch_switch_idx);
320+
clock_graph.add_edge(rr_edges_to_create, clock_network_indices[i], size_t(clock_pin_node_idx), arch_switch_idx);
324321
}
325322
}
326323
}

vpr/src/route/clock_connection_builders.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class RoutingToClockConnection : public ClockConnection {
5757
/* Connects the inter-block routing to the clock source at the specified coordinates */
5858
void create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) override;
5959
size_t estimate_additional_nodes() override;
60-
int create_virtual_clock_network_sink_node(int x, int y);
60+
RRNodeId create_virtual_clock_network_sink_node(int x, int y);
6161
};
6262

6363
class ClockToClockConneciton : public ClockConnection {

0 commit comments

Comments
 (0)