Skip to content

Commit

Permalink
Merge pull request #2343 from verilog-to-routing/read_flat_router
Browse files Browse the repository at this point in the history
Read flat router .route file
  • Loading branch information
vaughnbetz committed Jun 30, 2023
2 parents 83dc3c4 + 6f291c7 commit d62ad56
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 57 deletions.
96 changes: 49 additions & 47 deletions vpr/src/base/read_route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@
#include "old_traceback.h"

/*************Functions local to this module*************/
static void process_route(std::ifstream& fp, const char* filename, int& lineno);
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno);
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, bool is_flat);
static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
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);
static void process_global_blocks(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, bool is_flat);
static void format_coordinates(int& layer_num, int& x, int& y, std::string coord, ClusterNetId net, const char* filename, const int lineno);
static void format_pin_info(std::string& pb_name, std::string& port_name, int& pb_pin_num, std::string input);
static std::string format_name(std::string name);
Expand All @@ -69,7 +69,7 @@ void print_route(const Netlist<>& net_list, FILE* fp, bool is_flat);
* Perform a series of verification tests to ensure the netlist,
* placement, and routing files match
*/
bool read_route(const char* route_file, const t_router_opts& router_opts, bool verify_file_digests) {
bool read_route(const char* route_file, const t_router_opts& router_opts, bool verify_file_digests, bool is_flat) {
auto& device_ctx = g_vpr_ctx.mutable_device();
auto& place_ctx = g_vpr_ctx.placement();
bool flat_router = router_opts.flat_routing;
Expand Down Expand Up @@ -124,7 +124,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
}

/* Read in every net */
process_route(fp, route_file, lineno);
process_route(router_net_list, fp, route_file, lineno, is_flat);

fp.close();

Expand Down Expand Up @@ -157,7 +157,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
}

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

tokens.clear();
}

///@brief Check if the net is global or not, and process appropriately
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno) {
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();

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) {
if (input_tokens.size() > 3 && input_tokens[3] == "global"
&& input_tokens[4] == "net" && input_tokens[5] == "connecting:") {
/* Global net. Never routed. */
if (!cluster_ctx.clb_nlist.net_is_ignored(inet)) {
if (!net_list.net_is_ignored(inet)) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"Net %lu should be a global net", size_t(inet));
}
/*erase an extra colon for global nets*/
name.erase(name.end() - 1);
name = format_name(name);

if (0 != cluster_ctx.clb_nlist.net_name(inet).compare(name)) {
if (0 != net_list.net_name(inet).compare(name)) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"Net name %s for net number %lu specified in the routing file does not match given %s",
name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
"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",
name.c_str(), size_t(inet), net_list.net_name(inet).c_str());
}

process_global_blocks(fp, inet, filename, lineno);
process_global_blocks(net_list, fp, inet, filename, lineno, is_flat);
} else {
/* Not a global net */
if (cluster_ctx.clb_nlist.net_is_ignored(inet)) {
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());
if (net_list.net_is_ignored(inet)) {
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());
}

name = format_name(name);

if (0 != cluster_ctx.clb_nlist.net_name(inet).compare(name)) {
if (0 != net_list.net_name(inet).compare(name)) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"Net name %s for net number %lu specified in the routing file does not match given %s",
name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
"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",
name.c_str(), size_t(inet), net_list.net_name(inet).c_str());
}

process_nodes(fp, inet, filename, lineno);
process_nodes(net_list, fp, inet, filename, lineno);
}
input_tokens.clear();
return;
}

static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
/* Not a global net. Goes through every node and add it into trace.head*/

auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
auto& device_ctx = g_vpr_ctx.mutable_device();
const auto& rr_graph = device_ctx.rr_graph;
auto& route_ctx = g_vpr_ctx.mutable_routing();
Expand Down Expand Up @@ -257,7 +253,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
fp.seekg(oldpos);
break;
} else if (input == "\n\nUsed in local cluster only, reserved one CLB pin\n\n") {
if (cluster_ctx.clb_nlist.net_sinks(inet).size() != 0) {
if (net_list.net_sinks(inet).size() != 0) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"Net %d should be used in local cluster only, reserved one CLB pin");
}
Expand Down Expand Up @@ -327,7 +323,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
ptc = atoi(tokens[5 + offset].c_str());
if (rr_graph.node_ptc_num(RRNodeId(inode)) != ptc) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"The ptc num of node %d does not match the rr graph", inode);
"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);
}

/*Process switches and pb pin info if it is ipin or opin type*/
Expand All @@ -336,17 +332,25 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
auto type = device_ctx.grid.get_physical_type({x, y, layer_num});
if (!is_io_type(type) && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
int pin_num = rr_graph.node_pin_num(RRNodeId(inode));

int width_offset = device_ctx.grid.get_width_offset({x, y, layer_num});
int height_offset = device_ctx.grid.get_height_offset({x, y, layer_num});
auto physical_tile = device_ctx.grid.get_physical_type({x, y, layer_num});
const t_sub_tile* sub_tile;
int sub_tile_rel_cap;
std::tie(sub_tile, sub_tile_rel_cap) = get_sub_tile_from_pin_physical_num(physical_tile, pin_num);
int sub_tile_offset = sub_tile->capacity.low + sub_tile_rel_cap;

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

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

t_pb_graph_pin* pb_pin;
if (is_pin_on_tile(physical_tile, pin_num)) {
pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
} else {
pb_pin = get_pb_pin_from_pin_physical_num(physical_tile, pin_num);
}

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

std::string pb_name, port_name;
Expand Down Expand Up @@ -415,14 +419,10 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
* @brief This function goes through all the blocks in a global net and verify
* it with the clustered netlist and the placement
*/
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
auto& place_ctx = g_vpr_ctx.placement();

static void process_global_blocks(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, bool is_flat) {
std::string block, bnum_str;
int layer_num, x, y;
std::vector<std::string> tokens;
int pin_counter = 0;

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

/*Check for name, coordinate, and pins*/
if (0 != cluster_ctx.clb_nlist.block_name(bnum).compare(tokens[1])) {
if (0 != net_list.block_name(bnum).compare(tokens[1])) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"Block %s for block number %lu specified in the routing file does not match given %s",
tokens[1].c_str(), size_t(bnum), cluster_ctx.clb_nlist.block_name(bnum).c_str());
tokens[1].c_str(), size_t(bnum), net_list.block_name(bnum).c_str());
}
if (place_ctx.block_locs[bnum].loc.x != x || place_ctx.block_locs[bnum].loc.y != y) {

auto block_loc = get_block_loc(bnum, is_flat);

if (block_loc.loc.x != x || block_loc.loc.y != y) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"The placement coordinates (%d, %d) of %d block does not match given (%d, %d)",
x, y, place_ctx.block_locs[bnum].loc.x, place_ctx.block_locs[bnum].loc.y);
x, y, block_loc.loc.x, block_loc.loc.y);
}

int pin_index = net_pin_to_tile_pin_index(inet, pin_counter);
if (physical_tile_type(bnum)->pin_class[pin_index] != atoi(tokens[7].c_str())) {
auto pin_class = get_class_range_for_block(bnum, is_flat);
if (pin_class.low > atoi(tokens[7].c_str()) || pin_class.high < atoi(tokens[7].c_str())) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"The pin class %d of %lu net does not match given ",
atoi(tokens[7].c_str()), size_t(inet), physical_tile_type(bnum)->pin_class[pin_index]);
atoi(tokens[7].c_str()), size_t(inet));
}
pin_counter++;
}
oldpos = fp.tellg();
}
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/read_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "netlist.h"
#include "vpr_types.h"

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

#endif /* READ_ROUTE_H */
22 changes: 14 additions & 8 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,14 +819,20 @@ RouteStatus vpr_route_flow(const Netlist<>& net_list,
is_flat);
} else {
VTR_ASSERT(router_opts.doRouting == STAGE_LOAD);

//Load a previous routing
// TODO: flat routing is not implemented for this part
//if the previous load file is generated using flat routing,
//we need to create rr_graph with is_flat flag to add additional
//internal nodes/edges.
if (is_flat) {
vpr_create_rr_graph(vpr_setup, arch, chan_width, is_flat);
}

route_status = vpr_load_routing(vpr_setup,
arch,
chan_width,
timing_info,
net_delay);
net_delay,
is_flat);
}

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

//Load the routing from a file
bool is_legal = read_route(filename_opts.RouteFile.c_str(), vpr_setup.RouterOpts, filename_opts.verify_file_digests);

bool is_legal = read_route(filename_opts.RouteFile.c_str(), vpr_setup.RouterOpts, filename_opts.verify_file_digests, is_flat);
const Netlist<>& router_net_list = is_flat ? (const Netlist<>&)g_vpr_ctx.atom().nlist : (const Netlist<>&)g_vpr_ctx.clustering().clb_nlist;
if (vpr_setup.Timing.timing_analysis_enabled) {
//Update timing info
load_net_delay_from_routing((const Netlist<>&)g_vpr_ctx.clustering().clb_nlist,
load_net_delay_from_routing(router_net_list,
net_delay);

timing_info->update();
}
init_draw_coords(fixed_channel_width);
Expand Down
3 changes: 2 additions & 1 deletion vpr/src/base/vpr_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ RouteStatus vpr_load_routing(t_vpr_setup& vpr_setup,
const t_arch& arch,
int fixed_channel_width,
std::shared_ptr<SetupHoldTimingInfo> timing_info,
NetPinsMatrix<float>& net_delay);
NetPinsMatrix<float>& net_delay,
bool is_flat);

/* Analysis */

Expand Down

0 comments on commit d62ad56

Please sign in to comment.