Skip to content

Commit d62ad56

Browse files
authored
Merge pull request #2343 from verilog-to-routing/read_flat_router
Read flat router .route file
2 parents 83dc3c4 + 6f291c7 commit d62ad56

File tree

4 files changed

+66
-57
lines changed

4 files changed

+66
-57
lines changed

vpr/src/base/read_route.cpp

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@
5151
#include "old_traceback.h"
5252

5353
/*************Functions local to this module*************/
54-
static void process_route(std::ifstream& fp, const char* filename, int& lineno);
55-
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
56-
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno);
57-
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
54+
static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, bool is_flat);
55+
static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
56+
static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno, bool is_flat);
57+
static void process_global_blocks(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, bool is_flat);
5858
static void format_coordinates(int& layer_num, int& x, int& y, std::string coord, ClusterNetId net, const char* filename, const int lineno);
5959
static void format_pin_info(std::string& pb_name, std::string& port_name, int& pb_pin_num, std::string input);
6060
static std::string format_name(std::string name);
@@ -69,7 +69,7 @@ void print_route(const Netlist<>& net_list, FILE* fp, bool is_flat);
6969
* Perform a series of verification tests to ensure the netlist,
7070
* placement, and routing files match
7171
*/
72-
bool read_route(const char* route_file, const t_router_opts& router_opts, bool verify_file_digests) {
72+
bool read_route(const char* route_file, const t_router_opts& router_opts, bool verify_file_digests, bool is_flat) {
7373
auto& device_ctx = g_vpr_ctx.mutable_device();
7474
auto& place_ctx = g_vpr_ctx.placement();
7575
bool flat_router = router_opts.flat_routing;
@@ -124,7 +124,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
124124
}
125125

126126
/* Read in every net */
127-
process_route(fp, route_file, lineno);
127+
process_route(router_net_list, fp, route_file, lineno, is_flat);
128128

129129
fp.close();
130130

@@ -157,7 +157,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
157157
}
158158

159159
///@brief Walks through every net and add the routing appropriately
160-
static void process_route(std::ifstream& fp, const char* filename, int& lineno) {
160+
static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, bool is_flat) {
161161
std::string input;
162162
std::vector<std::string> tokens;
163163
while (std::getline(fp, input)) {
@@ -170,59 +170,55 @@ static void process_route(std::ifstream& fp, const char* filename, int& lineno)
170170
continue; //Skip commented lines
171171
} else if (tokens[0] == "Net") {
172172
ClusterNetId inet(atoi(tokens[1].c_str()));
173-
process_nets(fp, inet, tokens[2], tokens, filename, lineno);
173+
process_nets(net_list, fp, inet, tokens[2], tokens, filename, lineno, is_flat);
174174
}
175175
}
176176

177177
tokens.clear();
178178
}
179179

180180
///@brief Check if the net is global or not, and process appropriately
181-
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno) {
182-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
183-
181+
static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno, bool is_flat) {
184182
if (input_tokens.size() > 3 && input_tokens[3] == "global"
185183
&& input_tokens[4] == "net" && input_tokens[5] == "connecting:") {
186184
/* Global net. Never routed. */
187-
if (!cluster_ctx.clb_nlist.net_is_ignored(inet)) {
185+
if (!net_list.net_is_ignored(inet)) {
188186
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
189187
"Net %lu should be a global net", size_t(inet));
190188
}
191189
/*erase an extra colon for global nets*/
192190
name.erase(name.end() - 1);
193191
name = format_name(name);
194192

195-
if (0 != cluster_ctx.clb_nlist.net_name(inet).compare(name)) {
193+
if (0 != net_list.net_name(inet).compare(name)) {
196194
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
197-
"Net name %s for net number %lu specified in the routing file does not match given %s",
198-
name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
195+
"Net name %s for net number %lu specified in the routing file does not match given %s. Running without flat routing; if this file was created with flat routing, re-run vpr with the --flat_routing option",
196+
name.c_str(), size_t(inet), net_list.net_name(inet).c_str());
199197
}
200198

201-
process_global_blocks(fp, inet, filename, lineno);
199+
process_global_blocks(net_list, fp, inet, filename, lineno, is_flat);
202200
} else {
203201
/* Not a global net */
204-
if (cluster_ctx.clb_nlist.net_is_ignored(inet)) {
205-
VTR_LOG_WARN("Net %lu (%s) is marked as global in the netlist, but is non-global in the .route file\n", size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
202+
if (net_list.net_is_ignored(inet)) {
203+
VTR_LOG_WARN("Net %lu (%s) is marked as global in the netlist, but is non-global in the .route file\n", size_t(inet), net_list.net_name(inet).c_str());
206204
}
207205

208206
name = format_name(name);
209207

210-
if (0 != cluster_ctx.clb_nlist.net_name(inet).compare(name)) {
208+
if (0 != net_list.net_name(inet).compare(name)) {
211209
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
212-
"Net name %s for net number %lu specified in the routing file does not match given %s",
213-
name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
210+
"Net name %s for net number %lu specified in the routing file does not match given %s. Running without flat routing; if this file was created with flat routing, re-run vpr with the --flat_routing option",
211+
name.c_str(), size_t(inet), net_list.net_name(inet).c_str());
214212
}
215213

216-
process_nodes(fp, inet, filename, lineno);
214+
process_nodes(net_list, fp, inet, filename, lineno);
217215
}
218216
input_tokens.clear();
219217
return;
220218
}
221219

222-
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
220+
static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
223221
/* Not a global net. Goes through every node and add it into trace.head*/
224-
225-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
226222
auto& device_ctx = g_vpr_ctx.mutable_device();
227223
const auto& rr_graph = device_ctx.rr_graph;
228224
auto& route_ctx = g_vpr_ctx.mutable_routing();
@@ -257,7 +253,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
257253
fp.seekg(oldpos);
258254
break;
259255
} else if (input == "\n\nUsed in local cluster only, reserved one CLB pin\n\n") {
260-
if (cluster_ctx.clb_nlist.net_sinks(inet).size() != 0) {
256+
if (net_list.net_sinks(inet).size() != 0) {
261257
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
262258
"Net %d should be used in local cluster only, reserved one CLB pin");
263259
}
@@ -327,7 +323,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
327323
ptc = atoi(tokens[5 + offset].c_str());
328324
if (rr_graph.node_ptc_num(RRNodeId(inode)) != ptc) {
329325
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
330-
"The ptc num of node %d does not match the rr graph", inode);
326+
"The ptc num of node %d does not match the rr graph, Running without flat routing; if this file was created with flat routing, re-run vpr with the --flat_routing option", inode);
331327
}
332328

333329
/*Process switches and pb pin info if it is ipin or opin type*/
@@ -336,17 +332,25 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
336332
auto type = device_ctx.grid.get_physical_type({x, y, layer_num});
337333
if (!is_io_type(type) && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
338334
int pin_num = rr_graph.node_pin_num(RRNodeId(inode));
339-
335+
int width_offset = device_ctx.grid.get_width_offset({x, y, layer_num});
340336
int height_offset = device_ctx.grid.get_height_offset({x, y, layer_num});
337+
auto physical_tile = device_ctx.grid.get_physical_type({x, y, layer_num});
338+
const t_sub_tile* sub_tile;
339+
int sub_tile_rel_cap;
340+
std::tie(sub_tile, sub_tile_rel_cap) = get_sub_tile_from_pin_physical_num(physical_tile, pin_num);
341+
int sub_tile_offset = sub_tile->capacity.low + sub_tile_rel_cap;
341342

342-
int capacity, relative_pin;
343-
std::tie(capacity, relative_pin) = get_capacity_location_from_physical_pin(type, pin_num);
343+
ClusterBlockId iblock = place_ctx.grid_blocks.block_at_location({x - width_offset, y - height_offset, sub_tile_offset, layer_num});
344+
VTR_ASSERT(iblock);
344345

345-
ClusterBlockId iblock = place_ctx.grid_blocks.block_at_location({x, y - height_offset, capacity, layer_num});
346+
const t_pb_graph_pin* pb_pin;
346347

347-
t_pb_graph_pin* pb_pin;
348+
if (is_pin_on_tile(physical_tile, pin_num)) {
349+
pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
350+
} else {
351+
pb_pin = get_pb_pin_from_pin_physical_num(physical_tile, pin_num);
352+
}
348353

349-
pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
350354
t_pb_type* pb_type = pb_pin->parent_node->pb_type;
351355

352356
std::string pb_name, port_name;
@@ -415,14 +419,10 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
415419
* @brief This function goes through all the blocks in a global net and verify
416420
* it with the clustered netlist and the placement
417421
*/
418-
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
419-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
420-
auto& place_ctx = g_vpr_ctx.placement();
421-
422+
static void process_global_blocks(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, bool is_flat) {
422423
std::string block, bnum_str;
423424
int layer_num, x, y;
424425
std::vector<std::string> tokens;
425-
int pin_counter = 0;
426426

427427
std::streampos oldpos = fp.tellg();
428428
/*Walk through every block line*/
@@ -446,27 +446,29 @@ static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const ch
446446
bnum_str = format_name(tokens[2]);
447447
/*remove #*/
448448
bnum_str.erase(bnum_str.begin());
449-
ClusterBlockId bnum(atoi(bnum_str.c_str()));
449+
ParentBlockId bnum(atoi(bnum_str.c_str()));
450450

451451
/*Check for name, coordinate, and pins*/
452-
if (0 != cluster_ctx.clb_nlist.block_name(bnum).compare(tokens[1])) {
452+
if (0 != net_list.block_name(bnum).compare(tokens[1])) {
453453
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
454454
"Block %s for block number %lu specified in the routing file does not match given %s",
455-
tokens[1].c_str(), size_t(bnum), cluster_ctx.clb_nlist.block_name(bnum).c_str());
455+
tokens[1].c_str(), size_t(bnum), net_list.block_name(bnum).c_str());
456456
}
457-
if (place_ctx.block_locs[bnum].loc.x != x || place_ctx.block_locs[bnum].loc.y != y) {
457+
458+
auto block_loc = get_block_loc(bnum, is_flat);
459+
460+
if (block_loc.loc.x != x || block_loc.loc.y != y) {
458461
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
459462
"The placement coordinates (%d, %d) of %d block does not match given (%d, %d)",
460-
x, y, place_ctx.block_locs[bnum].loc.x, place_ctx.block_locs[bnum].loc.y);
463+
x, y, block_loc.loc.x, block_loc.loc.y);
461464
}
462465

463-
int pin_index = net_pin_to_tile_pin_index(inet, pin_counter);
464-
if (physical_tile_type(bnum)->pin_class[pin_index] != atoi(tokens[7].c_str())) {
466+
auto pin_class = get_class_range_for_block(bnum, is_flat);
467+
if (pin_class.low > atoi(tokens[7].c_str()) || pin_class.high < atoi(tokens[7].c_str())) {
465468
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
466469
"The pin class %d of %lu net does not match given ",
467-
atoi(tokens[7].c_str()), size_t(inet), physical_tile_type(bnum)->pin_class[pin_index]);
470+
atoi(tokens[7].c_str()), size_t(inet));
468471
}
469-
pin_counter++;
470472
}
471473
oldpos = fp.tellg();
472474
}

vpr/src/base/read_route.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "netlist.h"
1212
#include "vpr_types.h"
1313

14-
bool read_route(const char* route_file, const t_router_opts& RouterOpts, bool verify_file_digests);
14+
bool read_route(const char* route_file, const t_router_opts& RouterOpts, bool verify_file_digests, bool is_flat);
1515
void print_route(const Netlist<>& net_list, const char* placement_file, const char* route_file, bool is_flat);
1616

1717
#endif /* READ_ROUTE_H */

vpr/src/base/vpr_api.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -819,14 +819,20 @@ RouteStatus vpr_route_flow(const Netlist<>& net_list,
819819
is_flat);
820820
} else {
821821
VTR_ASSERT(router_opts.doRouting == STAGE_LOAD);
822-
823822
//Load a previous routing
824-
// TODO: flat routing is not implemented for this part
823+
//if the previous load file is generated using flat routing,
824+
//we need to create rr_graph with is_flat flag to add additional
825+
//internal nodes/edges.
826+
if (is_flat) {
827+
vpr_create_rr_graph(vpr_setup, arch, chan_width, is_flat);
828+
}
829+
825830
route_status = vpr_load_routing(vpr_setup,
826831
arch,
827832
chan_width,
828833
timing_info,
829-
net_delay);
834+
net_delay,
835+
is_flat);
830836
}
831837

832838
//Post-implementation
@@ -969,7 +975,8 @@ RouteStatus vpr_load_routing(t_vpr_setup& vpr_setup,
969975
const t_arch& /*arch*/,
970976
int fixed_channel_width,
971977
std::shared_ptr<SetupHoldTimingInfo> timing_info,
972-
NetPinsMatrix<float>& net_delay) {
978+
NetPinsMatrix<float>& net_delay,
979+
bool is_flat) {
973980
vtr::ScopedStartFinishTimer timer("Load Routing");
974981
if (NO_FIXED_CHANNEL_WIDTH == fixed_channel_width) {
975982
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Fixed channel width must be specified when loading routing (was %d)", fixed_channel_width);
@@ -978,13 +985,12 @@ RouteStatus vpr_load_routing(t_vpr_setup& vpr_setup,
978985
auto& filename_opts = vpr_setup.FileNameOpts;
979986

980987
//Load the routing from a file
981-
bool is_legal = read_route(filename_opts.RouteFile.c_str(), vpr_setup.RouterOpts, filename_opts.verify_file_digests);
982-
988+
bool is_legal = read_route(filename_opts.RouteFile.c_str(), vpr_setup.RouterOpts, filename_opts.verify_file_digests, is_flat);
989+
const Netlist<>& router_net_list = is_flat ? (const Netlist<>&)g_vpr_ctx.atom().nlist : (const Netlist<>&)g_vpr_ctx.clustering().clb_nlist;
983990
if (vpr_setup.Timing.timing_analysis_enabled) {
984991
//Update timing info
985-
load_net_delay_from_routing((const Netlist<>&)g_vpr_ctx.clustering().clb_nlist,
992+
load_net_delay_from_routing(router_net_list,
986993
net_delay);
987-
988994
timing_info->update();
989995
}
990996
init_draw_coords(fixed_channel_width);

vpr/src/base/vpr_api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ RouteStatus vpr_load_routing(t_vpr_setup& vpr_setup,
108108
const t_arch& arch,
109109
int fixed_channel_width,
110110
std::shared_ptr<SetupHoldTimingInfo> timing_info,
111-
NetPinsMatrix<float>& net_delay);
111+
NetPinsMatrix<float>& net_delay,
112+
bool is_flat);
112113

113114
/* Analysis */
114115

0 commit comments

Comments
 (0)