From 44b1948ac235a791f598e3a4993d55940af65610 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 24 Jun 2025 17:18:03 -0400 Subject: [PATCH 01/11] [vpr][CLI] add verify_rr_switch_id option --- vpr/src/base/SetupVPR.cpp | 2 ++ vpr/src/base/read_options.cpp | 10 ++++++++++ vpr/src/base/read_options.h | 1 + vpr/src/base/vpr_types.h | 2 ++ 4 files changed, 15 insertions(+) diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index 651ae5ccd1..2054dedf8d 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -516,6 +516,8 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) RouterOpts->has_choke_point = Options.router_opt_choke_points; RouterOpts->custom_3d_sb_fanin_fanout = Options.custom_3d_sb_fanin_fanout; RouterOpts->with_timing_analysis = Options.timing_analysis; + + RouterOpts->verify_rr_switch_id = Options.verify_rr_switch_id; } static void SetupAnnealSched(const t_options& Options, diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 3c6b206764..90e899a6cc 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1637,6 +1637,16 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .default_value("on") .show_in(argparse::ShowIn::HELP_ONLY); + gen_grp.add_argument(args.verify_rr_switch_id, "--verify_rr_switch_id") + .help( + "Verify that the switch IDs in the routing file are consistent with those in the RR Graph." + "Set this to false when switch IDs in the routing file may differ from the RR Graph." + "For example, when analyzing different timing corners using the same netlist, placement, and routing files," + "the RR switch IDs in the RR Graph may differ due to changes in delays." + "In such cases, set this option to false so that the switch IDs from the RR Graph are used, and those in the routing file are ignored.") + .default_value("on") + .show_in(argparse::ShowIn::HELP_ONLY); + gen_grp.add_argument(args.target_device_utilization, "--target_utilization") .help( "Sets the target device utilization." diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index 9485c0b765..5ac14df8ae 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -73,6 +73,7 @@ struct t_options { argparse::ArgValue timing_update_type; argparse::ArgValue CreateEchoFile; argparse::ArgValue verify_file_digests; + argparse::ArgValue verify_rr_switch_id; argparse::ArgValue device_layout; argparse::ArgValue target_device_utilization; argparse::ArgValue constant_net_method; diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 71bf0c3458..377a935fdc 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1343,6 +1343,8 @@ struct t_router_opts { bool with_timing_analysis; + bool verify_rr_switch_id; + // Options related to rr_node reordering, for testing and possible cache optimization e_rr_node_reorder_algorithm reorder_rr_graph_nodes_algorithm = DONT_REORDER; int reorder_rr_graph_nodes_threshold = 0; From c1f697e916620ed3bcdae64218b223c43d7c52b7 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 24 Jun 2025 17:26:11 -0400 Subject: [PATCH 02/11] [vpr][route] pass verify_rr_switch_id to relevant functions --- vpr/src/base/read_route.cpp | 44 +++++++++++++++++++++++++++++-------- vpr/src/base/read_route.h | 11 ++++++++-- vpr/src/base/vpr_api.cpp | 5 ++++- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index 28c15debac..1f38fdff5d 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -39,9 +39,30 @@ #include "old_traceback.h" /*************Functions local to this module*************/ -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 input_tokens, const char* filename, int& lineno, bool is_flat); +static void process_route(const Netlist<>& net_list, + std::ifstream& fp, + const char* filename, + int& lineno, + bool verify_rr_switch_id, + bool is_flat); + +static void process_nodes(const Netlist<>& net_list, + std::ifstream& fp, + ClusterNetId inet, + const char* filename, + bool verify_rr_switch_id, + int& lineno); + +static void process_nets(const Netlist<>& net_list, + std::ifstream& fp, + ClusterNetId inet, + std::string name, + std::vector input_tokens, + const char* filename, + int& lineno, + bool verify_rr_switch_id, + 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, const std::string& input); @@ -112,7 +133,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v } /* Read in every net */ - process_route(router_net_list, fp, route_file, lineno, is_flat); + process_route(router_net_list, fp, route_file, lineno, router_opts.verify_rr_switch_id, is_flat); fp.close(); @@ -145,7 +166,12 @@ 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(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, bool is_flat) { +static void process_route(const Netlist<>& net_list, + std::ifstream& fp, + const char* filename, + int& lineno, + bool verify_rr_switch_id, + bool is_flat) { std::string input; std::vector tokens; while (std::getline(fp, input)) { @@ -158,7 +184,7 @@ static void process_route(const Netlist<>& net_list, std::ifstream& fp, const ch continue; //Skip commented lines } else if (tokens[0] == "Net") { ClusterNetId inet(atoi(tokens[1].c_str())); - process_nets(net_list, fp, inet, tokens[2], tokens, filename, lineno, is_flat); + process_nets(net_list, fp, inet, tokens[2], tokens, filename, lineno, verify_rr_switch_id, is_flat); } } @@ -166,7 +192,7 @@ static void process_route(const Netlist<>& net_list, std::ifstream& fp, const ch } ///@brief Check if the net is global or not, and process appropriately -static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, std::string name, std::vector input_tokens, const char* filename, int& lineno, bool is_flat) { +static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, std::string name, std::vector input_tokens, const char* filename, int& lineno, bool verify_rr_switch_id, bool is_flat) { if (input_tokens.size() > 3 && input_tokens[3] == "global" && input_tokens[4] == "net" && input_tokens[5] == "connecting:") { /* Global net. Never routed. */ @@ -199,12 +225,12 @@ static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNe name.c_str(), size_t(inet), net_list.net_name(inet).c_str()); } - process_nodes(net_list, fp, inet, filename, lineno); + process_nodes(net_list, fp, inet, filename, verify_rr_switch_id, lineno); } input_tokens.clear(); } -static void process_nodes(const Netlist<>& net_list, 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, bool verify_rr_switch_id, int& lineno) { /* Not a global net. Goes through every node and add it into trace.head*/ auto& device_ctx = g_vpr_ctx.mutable_device(); const auto& rr_graph = device_ctx.rr_graph; diff --git a/vpr/src/base/read_route.h b/vpr/src/base/read_route.h index 95f9c51649..34b5d65c30 100644 --- a/vpr/src/base/read_route.h +++ b/vpr/src/base/read_route.h @@ -9,5 +9,12 @@ #include "netlist.h" #include "vpr_types.h" -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); +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); diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index a40c759787..648d6b740e 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -1152,7 +1152,10 @@ 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, is_flat); + 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().netlist() : (const Netlist<>&)g_vpr_ctx.clustering().clb_nlist; if (vpr_setup.Timing.timing_analysis_enabled) { //Update timing info From a5899e3080a1cd82a874cb60941e6310d52f4e0c Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 24 Jun 2025 18:27:01 -0400 Subject: [PATCH 03/11] [vpr][base] add update_rr_switch_id --- vpr/src/base/read_route.cpp | 59 ++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index 1f38fdff5d..beb6149559 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -63,6 +63,8 @@ static void process_nets(const Netlist<>& net_list, bool verify_rr_switch_id, bool is_flat); +static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes); + 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, const std::string& input); @@ -422,12 +424,67 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN oldpos = fp.tellg(); } + if (verify_rr_switch_id) { + VTR_ASSERT(validate_traceback(head_ptr)); + } else { + std::set seen_rr_nodes; + update_rr_switch_id(head_ptr, seen_rr_nodes); + } + /* Convert to route_tree after reading */ - VTR_ASSERT(validate_traceback(head_ptr)); route_ctx.route_trees[inet] = TracebackCompat::traceback_to_route_tree(head_ptr); free_traceback(head_ptr); } +static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes) { + if (!trace) { + return; + } + + seen_rr_nodes.insert(trace->index); + + t_trace* next = trace->next; + + if (next) { + if (trace->iswitch == OPEN) { //End of a branch + + //Verify that the next element (branch point) has been already seen in the traceback so far + if (!seen_rr_nodes.count(next->index)) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); + } else { + //Recurse along the new branch + update_rr_switch_id(next, seen_rr_nodes); + return; + } + } else { //Midway along branch + + //Check there is an edge connecting trace and next + + auto& device_ctx = g_vpr_ctx.device(); + const auto& rr_graph = device_ctx.rr_graph; + bool found = false; + for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { + int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); + if (to_node == next->index) { + found = true; + + //Verify that the switch matches + int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); + trace->iswitch = rr_iswitch; + break; + } + } + if (!found) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); + } + //Recurse + update_rr_switch_id(next, seen_rr_nodes); + return; + } + } + VTR_ASSERT(!next); +} + /** * @brief This function goes through all the blocks in a global net and verify * it with the clustered netlist and the placement From 4d9b098d63489646c2a7537b1fec7fa984b153b6 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 11:29:17 -0400 Subject: [PATCH 04/11] [libs] update libcatch2 and libezgl version --- libs/EXTERNAL/libcatch2 | 2 +- libs/EXTERNAL/libezgl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/EXTERNAL/libcatch2 b/libs/EXTERNAL/libcatch2 index 74fcff6e5b..ceed26842b 160000 --- a/libs/EXTERNAL/libcatch2 +++ b/libs/EXTERNAL/libcatch2 @@ -1 +1 @@ -Subproject commit 74fcff6e5b190fb833a231b7f7c1829e3c3ac54d +Subproject commit ceed26842b3b3f93523998f7adb672672c7c2d8f diff --git a/libs/EXTERNAL/libezgl b/libs/EXTERNAL/libezgl index b6beef98a3..5b1fd681c7 160000 --- a/libs/EXTERNAL/libezgl +++ b/libs/EXTERNAL/libezgl @@ -1 +1 @@ -Subproject commit b6beef98a3e51907c66fa6c7cc74933fb91faa6c +Subproject commit 5b1fd681c7bfb7ecfe7669557ab44af6f2d04667 From 438c4c84f19e208c159953ab347b79c5c18d834a Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 12:20:56 -0400 Subject: [PATCH 05/11] [vpr][base] fix formatting in read_route.cpp and simplify the logic in update_rr_switch_id --- vpr/src/base/read_options.cpp | 10 +- vpr/src/base/read_route.cpp | 188 ++++++++++++++++++++++++---------- 2 files changed, 141 insertions(+), 57 deletions(-) diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index f45f12c9c8..b600e9842d 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1639,11 +1639,11 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio gen_grp.add_argument(args.verify_rr_switch_id, "--verify_rr_switch_id") .help( - "Verify that the switch IDs in the routing file are consistent with those in the RR Graph." - "Set this to false when switch IDs in the routing file may differ from the RR Graph." - "For example, when analyzing different timing corners using the same netlist, placement, and routing files," - "the RR switch IDs in the RR Graph may differ due to changes in delays." - "In such cases, set this option to false so that the switch IDs from the RR Graph are used, and those in the routing file are ignored.") + "Verify that the switch IDs in the routing file are consistent with those in the RR Graph. " + "Set this to false when switch IDs in the routing file may differ from the RR Graph. " + "For example, when analyzing different timing corners using the same netlist, placement, and routing files, " + "the RR switch IDs in the RR Graph may differ due to changes in delays. " + "In such cases, set this option to false so that the switch IDs from the RR Graph are used, and those in the routing file are ignored.\n") .default_value("on") .show_in(argparse::ShowIn::HELP_ONLY); diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index beb6149559..f5f0ada50b 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -39,6 +39,17 @@ #include "old_traceback.h" /*************Functions local to this module*************/ + +/** + * @brief Read the routing file and create the routing tree for each net. + * + * @param net_list The netlist to process. + * @param fp The file stream to read from. + * @param filename The name of the file to read from. + * @param lineno The line number currently being processed. + * @param verify_rr_switch_id Whether to verify the RR switch IDs in the routing file. + * @param is_flat Whether flat-router is enabled. + */ static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, @@ -46,6 +57,15 @@ static void process_route(const Netlist<>& net_list, bool verify_rr_switch_id, bool is_flat); +/** + * @brief Create the routing tree for the net at the given line number in the routing file. + * + * @param net_list The netlist to process. + * @param fp The file stream to read from. + * @param inet The net ID to process. + * @param filename The name of the file to read from. + * @param verify_rr_switch_id Whether to verify the RR switch IDs in the routing file. + */ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, @@ -53,6 +73,19 @@ static void process_nodes(const Netlist<>& net_list, bool verify_rr_switch_id, int& lineno); +/** + * @brief Process the net at the given line number in the routing file. + * + * @param net_list The netlist to process. + * @param fp The file stream to read from. + * @param inet The net ID to process. + * @param name The name of the net. + * @param input_tokens The tokens of the net. + * @param filename The name of the file to read from. + * @param lineno The line number currently being processed. + * @param verify_rr_switch_id Whether to verify the RR switch IDs in the routing file. + * @param is_flat Whether flat-router is enabled. + */ static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, @@ -63,14 +96,49 @@ static void process_nets(const Netlist<>& net_list, bool verify_rr_switch_id, bool is_flat); -static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes); +/** + * @brief Update the switch IDs in the routing trace to match the RR Graph. + * + * @note This function is called recursively to update the switch IDs in the routing trace. + * + * @param trace Pointer to the head of the routing trace of the net to update. + * @param seen_rr_nodes A set of seen RR nodes to avoid duplicate updates. + */ +static void update_rr_switch_id(t_trace* trace, + std::set& seen_rr_nodes); + +/** + * @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(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, + const std::string& input); -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, const std::string& input); static std::string format_name(std::string name); -static bool check_rr_graph_connectivity(RRNodeId prev_node, RRNodeId node); -void print_route(const Netlist<>& net_list, FILE* fp, bool is_flat); + +static bool check_rr_graph_connectivity(RRNodeId prev_node, + RRNodeId node); + +void print_route(const Netlist<>& net_list, + FILE* fp, + bool is_flat); /*************Global Functions****************************/ @@ -80,7 +148,10 @@ 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 is_flat) { +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; @@ -167,7 +238,6 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v return is_feasible; } -///@brief Walks through every net and add the routing appropriately static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, @@ -186,15 +256,30 @@ static void process_route(const Netlist<>& net_list, continue; //Skip commented lines } else if (tokens[0] == "Net") { ClusterNetId inet(atoi(tokens[1].c_str())); - process_nets(net_list, fp, inet, tokens[2], tokens, filename, lineno, verify_rr_switch_id, is_flat); + process_nets(net_list, + fp, + inet, + tokens[2], + tokens, + filename, + lineno, + verify_rr_switch_id, + is_flat); } } tokens.clear(); } -///@brief Check if the net is global or not, and process appropriately -static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, std::string name, std::vector input_tokens, const char* filename, int& lineno, bool verify_rr_switch_id, bool is_flat) { +static void process_nets(const Netlist<>& net_list, + std::ifstream& fp, + ClusterNetId inet, + std::string name, + std::vector input_tokens, + const char* filename, + int& lineno, + bool verify_rr_switch_id, + bool is_flat) { if (input_tokens.size() > 3 && input_tokens[3] == "global" && input_tokens[4] == "net" && input_tokens[5] == "connecting:") { /* Global net. Never routed. */ @@ -227,12 +312,22 @@ static void process_nets(const Netlist<>& net_list, std::ifstream& fp, ClusterNe name.c_str(), size_t(inet), net_list.net_name(inet).c_str()); } - process_nodes(net_list, fp, inet, filename, verify_rr_switch_id, lineno); + process_nodes(net_list, + fp, + inet, + filename, + verify_rr_switch_id, + lineno); } input_tokens.clear(); } -static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, bool verify_rr_switch_id, int& lineno) { +static void process_nodes(const Netlist<>& net_list, + std::ifstream& fp, + ClusterNetId inet, + const char* filename, + bool verify_rr_switch_id, + int& lineno) { /* Not a global net. Goes through every node and add it into trace.head*/ auto& device_ctx = g_vpr_ctx.mutable_device(); const auto& rr_graph = device_ctx.rr_graph; @@ -437,7 +532,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN } static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes) { - if (!trace) { + if (trace == nullptr) { return; } @@ -445,50 +540,39 @@ static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes) { t_trace* next = trace->next; - if (next) { - if (trace->iswitch == OPEN) { //End of a branch + if (next == nullptr) { + return; + } - //Verify that the next element (branch point) has been already seen in the traceback so far - if (!seen_rr_nodes.count(next->index)) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); - } else { - //Recurse along the new branch - update_rr_switch_id(next, seen_rr_nodes); - return; - } - } else { //Midway along branch - - //Check there is an edge connecting trace and next - - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; - bool found = false; - for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { - int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); - if (to_node == next->index) { - found = true; - - //Verify that the switch matches - int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); - trace->iswitch = rr_iswitch; - break; - } - } - if (!found) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); + if (trace->iswitch == OPEN) { //End of a branch + //Verify that the next element (branch point) has been already seen in the traceback so far + if (!seen_rr_nodes.count(next->index)) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); + } + } else { //Midway along branch + //Check there is an edge connecting trace and next + auto& device_ctx = g_vpr_ctx.device(); + const auto& rr_graph = device_ctx.rr_graph; + bool found = false; + for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { + int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); + if (to_node == next->index) { + found = true; + + //Verify that the switch matches + int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); + trace->iswitch = rr_iswitch; + break; } - //Recurse - update_rr_switch_id(next, seen_rr_nodes); - return; + } + if (!found) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); } } - VTR_ASSERT(!next); + //Recurse + update_rr_switch_id(next, seen_rr_nodes); } -/** - * @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(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; From 536d0099d05eebc611a3f7a48ca37c1c14a1e6f6 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 12:30:36 -0400 Subject: [PATCH 06/11] [CLI] rename verify_rr_switch_id to verify_route_file_switch_id --- vpr/src/base/SetupVPR.cpp | 2 +- vpr/src/base/read_options.cpp | 2 +- vpr/src/base/read_options.h | 2 +- vpr/src/base/read_route.cpp | 41 +++++++++++++++++------------------ vpr/src/base/vpr_types.h | 5 +++-- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index 5e639ab24e..d9b8c9c819 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -517,7 +517,7 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) RouterOpts->custom_3d_sb_fanin_fanout = Options.custom_3d_sb_fanin_fanout; RouterOpts->with_timing_analysis = Options.timing_analysis; - RouterOpts->verify_rr_switch_id = Options.verify_rr_switch_id; + RouterOpts->verify_route_file_switch_id = Options.verify_route_file_switch_id ; RouterOpts->generate_router_lookahead_report = Options.generate_router_lookahead_report.value(); } diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index b600e9842d..bd7eec74a5 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1637,7 +1637,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .default_value("on") .show_in(argparse::ShowIn::HELP_ONLY); - gen_grp.add_argument(args.verify_rr_switch_id, "--verify_rr_switch_id") + gen_grp.add_argument(args.verify_route_file_switch_id , "--verify_route_file_switch_id") .help( "Verify that the switch IDs in the routing file are consistent with those in the RR Graph. " "Set this to false when switch IDs in the routing file may differ from the RR Graph. " diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index f4c00dc53c..11d6bd7a6e 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -73,7 +73,7 @@ struct t_options { argparse::ArgValue timing_update_type; argparse::ArgValue CreateEchoFile; argparse::ArgValue verify_file_digests; - argparse::ArgValue verify_rr_switch_id; + argparse::ArgValue verify_route_file_switch_id ; argparse::ArgValue device_layout; argparse::ArgValue target_device_utilization; argparse::ArgValue constant_net_method; diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index f5f0ada50b..7710fbc9b3 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -47,14 +47,14 @@ * @param fp The file stream to read from. * @param filename The name of the file to read from. * @param lineno The line number currently being processed. - * @param verify_rr_switch_id Whether to verify the RR switch IDs in the routing file. + * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. * @param is_flat Whether flat-router is enabled. */ static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, - bool verify_rr_switch_id, + bool verify_route_file_switch_id , bool is_flat); /** @@ -64,13 +64,13 @@ static void process_route(const Netlist<>& net_list, * @param fp The file stream to read from. * @param inet The net ID to process. * @param filename The name of the file to read from. - * @param verify_rr_switch_id Whether to verify the RR switch IDs in the routing file. + * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. */ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, - bool verify_rr_switch_id, + bool verify_route_file_switch_id , int& lineno); /** @@ -83,7 +83,7 @@ static void process_nodes(const Netlist<>& net_list, * @param input_tokens The tokens of the net. * @param filename The name of the file to read from. * @param lineno The line number currently being processed. - * @param verify_rr_switch_id Whether to verify the RR switch IDs in the routing file. + * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. * @param is_flat Whether flat-router is enabled. */ static void process_nets(const Netlist<>& net_list, @@ -93,7 +93,7 @@ static void process_nets(const Netlist<>& net_list, std::vector input_tokens, const char* filename, int& lineno, - bool verify_rr_switch_id, + bool verify_route_file_switch_id , bool is_flat); /** @@ -206,7 +206,7 @@ bool read_route(const char* route_file, } /* Read in every net */ - process_route(router_net_list, fp, route_file, lineno, router_opts.verify_rr_switch_id, is_flat); + process_route(router_net_list, fp, route_file, lineno, router_opts.verify_route_file_switch_id , is_flat); fp.close(); @@ -242,7 +242,7 @@ static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, - bool verify_rr_switch_id, + bool verify_route_file_switch_id , bool is_flat) { std::string input; std::vector tokens; @@ -263,7 +263,7 @@ static void process_route(const Netlist<>& net_list, tokens, filename, lineno, - verify_rr_switch_id, + verify_route_file_switch_id , is_flat); } } @@ -278,7 +278,7 @@ static void process_nets(const Netlist<>& net_list, std::vector input_tokens, const char* filename, int& lineno, - bool verify_rr_switch_id, + bool verify_route_file_switch_id , bool is_flat) { if (input_tokens.size() > 3 && input_tokens[3] == "global" && input_tokens[4] == "net" && input_tokens[5] == "connecting:") { @@ -316,7 +316,7 @@ static void process_nets(const Netlist<>& net_list, fp, inet, filename, - verify_rr_switch_id, + verify_route_file_switch_id , lineno); } input_tokens.clear(); @@ -326,7 +326,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, - bool verify_rr_switch_id, + bool verify_route_file_switch_id , int& lineno) { /* Not a global net. Goes through every node and add it into trace.head*/ auto& device_ctx = g_vpr_ctx.mutable_device(); @@ -519,7 +519,7 @@ static void process_nodes(const Netlist<>& net_list, oldpos = fp.tellg(); } - if (verify_rr_switch_id) { + if (verify_route_file_switch_id ) { VTR_ASSERT(validate_traceback(head_ptr)); } else { std::set seen_rr_nodes; @@ -544,22 +544,21 @@ static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes) { return; } - if (trace->iswitch == OPEN) { //End of a branch - //Verify that the next element (branch point) has been already seen in the traceback so far + if (trace->iswitch == OPEN) { // End of a branch + // Verify that the next element (branch point) has been already seen in the traceback so far if (!seen_rr_nodes.count(next->index)) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); } - } else { //Midway along branch - //Check there is an edge connecting trace and next - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; + } else { // Midway along branch + // Check there is an edge connecting trace and next + const auto& rr_graph = g_vpr_ctx.device().rr_graph; bool found = false; for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); if (to_node == next->index) { found = true; - //Verify that the switch matches + // Verify that the switch matches int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); trace->iswitch = rr_iswitch; break; @@ -569,7 +568,7 @@ static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); } } - //Recurse + // Recurse update_rr_switch_id(next, seen_rr_nodes); } diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index c3ed9563dc..4a70cb3b4c 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1343,9 +1343,10 @@ struct t_router_opts { bool with_timing_analysis; - bool verify_rr_switch_id; + /// Whether to verify the switch IDs in the route file with the RR Graph. + bool verify_route_file_switch_id; - // Options related to rr_node reordering, for testing and possible cache optimization + /// Options related to rr_node reordering, for testing and possible cache optimization e_rr_node_reorder_algorithm reorder_rr_graph_nodes_algorithm = DONT_REORDER; int reorder_rr_graph_nodes_threshold = 0; int reorder_rr_graph_nodes_seed = 1; From d10f7dda69bcc9e56705cc26d6ce470b7d5d6392 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 12:44:30 -0400 Subject: [PATCH 07/11] [vpr][base] use std::set instead of having update_rr_switch_id as a recursive function --- vpr/src/base/read_route.cpp | 74 +++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index 7710fbc9b3..7e935310f1 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "physical_types_util.h" #include "vtr_assert.h" @@ -99,13 +100,9 @@ static void process_nets(const Netlist<>& net_list, /** * @brief Update the switch IDs in the routing trace to match the RR Graph. * - * @note This function is called recursively to update the switch IDs in the routing trace. - * * @param trace Pointer to the head of the routing trace of the net to update. - * @param seen_rr_nodes A set of seen RR nodes to avoid duplicate updates. */ -static void update_rr_switch_id(t_trace* trace, - std::set& seen_rr_nodes); +static void update_rr_switch_id(t_trace* trace); /** * @brief This function goes through all the blocks in a global net and verify @@ -522,8 +519,7 @@ static void process_nodes(const Netlist<>& net_list, if (verify_route_file_switch_id ) { VTR_ASSERT(validate_traceback(head_ptr)); } else { - std::set seen_rr_nodes; - update_rr_switch_id(head_ptr, seen_rr_nodes); + update_rr_switch_id(head_ptr); } /* Convert to route_tree after reading */ @@ -531,45 +527,53 @@ static void process_nodes(const Netlist<>& net_list, free_traceback(head_ptr); } -static void update_rr_switch_id(t_trace* trace, std::set& seen_rr_nodes) { +static void update_rr_switch_id(t_trace* trace) { if (trace == nullptr) { return; } - seen_rr_nodes.insert(trace->index); + std::set seen_rr_nodes; - t_trace* next = trace->next; + std::stack trace_stack; + trace_stack.push(trace); - if (next == nullptr) { - return; - } - if (trace->iswitch == OPEN) { // End of a branch - // Verify that the next element (branch point) has been already seen in the traceback so far - if (!seen_rr_nodes.count(next->index)) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); + while (!trace_stack.empty()) { + trace = trace_stack.top(); + trace_stack.pop(); + seen_rr_nodes.insert(trace->index); + t_trace* next = trace->next; + + if (next == nullptr) { + continue; } - } else { // Midway along branch - // Check there is an edge connecting trace and next - const auto& rr_graph = g_vpr_ctx.device().rr_graph; - bool found = false; - for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { - int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); - if (to_node == next->index) { - found = true; - - // Verify that the switch matches - int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); - trace->iswitch = rr_iswitch; - break; + + if (trace->iswitch == OPEN) { // End of a branch + // Verify that the next element (branch point) has been already seen in the traceback so far + if (!seen_rr_nodes.count(next->index)) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); + } + } else { // Midway along branch + // Check there is an edge connecting trace and next + const auto& rr_graph = g_vpr_ctx.device().rr_graph; + bool found = false; + for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { + int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); + if (to_node == next->index) { + found = true; + + // Verify that the switch matches + int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); + trace->iswitch = rr_iswitch; + break; + } + } + if (!found) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); } } - if (!found) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); - } + trace_stack.push(next); } - // Recurse - update_rr_switch_id(next, seen_rr_nodes); } static void process_global_blocks(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, bool is_flat) { From 4e13cb55bcdf47901f862bc4a624e73a10387483 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 13:52:29 -0400 Subject: [PATCH 08/11] [vpr][base] remove update_rr_switch_id and update validate_traceback to validate_and_update_traceback --- vpr/src/base/SetupVPR.cpp | 2 +- vpr/src/base/old_traceback.cpp | 64 ++++++++++++------------- vpr/src/base/old_traceback.h | 12 ++++- vpr/src/base/read_options.cpp | 2 +- vpr/src/base/read_route.cpp | 86 +++++----------------------------- 5 files changed, 55 insertions(+), 111 deletions(-) diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index d9b8c9c819..f81b988e7e 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -517,7 +517,7 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) RouterOpts->custom_3d_sb_fanin_fanout = Options.custom_3d_sb_fanin_fanout; RouterOpts->with_timing_analysis = Options.timing_analysis; - RouterOpts->verify_route_file_switch_id = Options.verify_route_file_switch_id ; + RouterOpts->verify_route_file_switch_id = Options.verify_route_file_switch_id; RouterOpts->generate_router_lookahead_report = Options.generate_router_lookahead_report.value(); } diff --git a/vpr/src/base/old_traceback.cpp b/vpr/src/base/old_traceback.cpp index 41bb857f59..3127f5d312 100644 --- a/vpr/src/base/old_traceback.cpp +++ b/vpr/src/base/old_traceback.cpp @@ -6,9 +6,9 @@ #include "route_common.h" #include +#include std::pair traceback_from_route_tree_recurr(t_trace* head, t_trace* tail, const RouteTreeNode& node); -bool validate_traceback_recurr(t_trace* trace, std::set& seen_rr_nodes); void free_trace_data(t_trace* tptr); /** Build a route tree from a traceback */ @@ -109,7 +109,7 @@ t_trace* TracebackCompat::traceback_from_route_tree(const RouteTree& tree) { std::tie(head, tail) = traceback_from_route_tree_recurr(nullptr, nullptr, tree.root()); - VTR_ASSERT(validate_traceback(head)); + VTR_ASSERT(validate_and_update_traceback(head)); return head; } @@ -141,70 +141,64 @@ void print_traceback(const t_trace* trace) { VTR_LOG("\n"); } -bool validate_traceback(t_trace* trace) { - std::set seen_rr_nodes; - - return validate_traceback_recurr(trace, seen_rr_nodes); -} - -bool validate_traceback_recurr(t_trace* trace, std::set& seen_rr_nodes) { +bool validate_and_update_traceback(t_trace* trace, bool verify_switch_id /* = true */) { if (!trace) { return true; } - seen_rr_nodes.insert(trace->index); + std::set seen_rr_nodes; + std::stack trace_stack; - t_trace* next = trace->next; + while (!trace_stack.empty()) { + trace = trace_stack.top(); + trace_stack.pop(); + seen_rr_nodes.insert(trace->index); + t_trace* next = trace->next; - if (next) { - if (trace->iswitch == OPEN) { //End of a branch + if (next == nullptr) { + continue; + } + if (trace->iswitch == OPEN) { //End of a branch //Verify that the next element (branch point) has been already seen in the traceback so far if (!seen_rr_nodes.count(next->index)) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); - } else { - //Recurse along the new branch - return validate_traceback_recurr(next, seen_rr_nodes); } } else { //Midway along branch - //Check there is an edge connecting trace and next - - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; + const auto& rr_graph = g_vpr_ctx.device().rr_graph; bool found = false; for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); - if (to_node == next->index) { found = true; - - //Verify that the switch matches int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); - if (trace->iswitch != rr_iswitch) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback mismatched switch type: traceback %d rr_graph %d (RR nodes %d -> %d)\n", - trace->iswitch, rr_iswitch, - trace->index, to_node); + if (verify_switch_id) { + // Verify that the switch matches + if (trace->iswitch != rr_iswitch) { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback mismatched switch type: traceback %d rr_graph %d (RR nodes %d -> %d)\n", + trace->iswitch, rr_iswitch, + trace->index, to_node); + } + } else { + // Update the switch ID in the traceback to match the RR Graph + trace->iswitch = rr_iswitch; } break; } } - if (!found) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); } - - //Recurse - return validate_traceback_recurr(next, seen_rr_nodes); } + // Recurse + trace_stack.push(next); } - VTR_ASSERT(!next); - return true; //End of traceback + return true; } -t_trace* -alloc_trace_data() { +t_trace* alloc_trace_data() { return (t_trace*)malloc(sizeof(t_trace)); } diff --git a/vpr/src/base/old_traceback.h b/vpr/src/base/old_traceback.h index 6c9a9ed258..79dea00975 100644 --- a/vpr/src/base/old_traceback.h +++ b/vpr/src/base/old_traceback.h @@ -46,4 +46,14 @@ class TracebackCompat { t_trace* alloc_trace_data(); void free_traceback(t_trace* trace); void print_traceback(const t_trace* trace); -bool validate_traceback(t_trace* trace); + +/** + * @brief Validate the routing traceback if verify_switch_id is true, otherwise update the + * switch IDs in the traceback to match the RR Graph. + * + * @param trace Pointer to the head of the routing trace of the net to validate and update. + * @param verify_switch_id Whether to verify the switch IDs in the traceback. + * + * @return true if the traceback is valid, false otherwise. + */ +bool validate_and_update_traceback(t_trace* trace, bool verify_switch_id = true); diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index bd7eec74a5..57c449b6d2 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1637,7 +1637,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .default_value("on") .show_in(argparse::ShowIn::HELP_ONLY); - gen_grp.add_argument(args.verify_route_file_switch_id , "--verify_route_file_switch_id") + gen_grp.add_argument(args.verify_route_file_switch_id, "--verify_route_file_switch_id") .help( "Verify that the switch IDs in the routing file are consistent with those in the RR Graph. " "Set this to false when switch IDs in the routing file may differ from the RR Graph. " diff --git a/vpr/src/base/read_route.cpp b/vpr/src/base/read_route.cpp index 7e935310f1..fb300b6fd4 100644 --- a/vpr/src/base/read_route.cpp +++ b/vpr/src/base/read_route.cpp @@ -48,14 +48,14 @@ * @param fp The file stream to read from. * @param filename The name of the file to read from. * @param lineno The line number currently being processed. - * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. + * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. * @param is_flat Whether flat-router is enabled. */ static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, - bool verify_route_file_switch_id , + bool verify_route_file_switch_id, bool is_flat); /** @@ -65,13 +65,13 @@ static void process_route(const Netlist<>& net_list, * @param fp The file stream to read from. * @param inet The net ID to process. * @param filename The name of the file to read from. - * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. + * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. */ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, - bool verify_route_file_switch_id , + bool verify_route_file_switch_id, int& lineno); /** @@ -84,7 +84,7 @@ static void process_nodes(const Netlist<>& net_list, * @param input_tokens The tokens of the net. * @param filename The name of the file to read from. * @param lineno The line number currently being processed. - * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. + * @param verify_route_file_switch_id Whether to verify the RR switch IDs in the routing file. * @param is_flat Whether flat-router is enabled. */ static void process_nets(const Netlist<>& net_list, @@ -94,16 +94,9 @@ static void process_nets(const Netlist<>& net_list, std::vector input_tokens, const char* filename, int& lineno, - bool verify_route_file_switch_id , + bool verify_route_file_switch_id, bool is_flat); -/** - * @brief Update the switch IDs in the routing trace to match the RR Graph. - * - * @param trace Pointer to the head of the routing trace of the net to update. - */ -static void update_rr_switch_id(t_trace* trace); - /** * @brief This function goes through all the blocks in a global net and verify * it with the clustered netlist and the placement @@ -203,7 +196,7 @@ bool read_route(const char* route_file, } /* Read in every net */ - process_route(router_net_list, fp, route_file, lineno, router_opts.verify_route_file_switch_id , is_flat); + process_route(router_net_list, fp, route_file, lineno, router_opts.verify_route_file_switch_id, is_flat); fp.close(); @@ -239,7 +232,7 @@ static void process_route(const Netlist<>& net_list, std::ifstream& fp, const char* filename, int& lineno, - bool verify_route_file_switch_id , + bool verify_route_file_switch_id, bool is_flat) { std::string input; std::vector tokens; @@ -260,7 +253,7 @@ static void process_route(const Netlist<>& net_list, tokens, filename, lineno, - verify_route_file_switch_id , + verify_route_file_switch_id, is_flat); } } @@ -275,7 +268,7 @@ static void process_nets(const Netlist<>& net_list, std::vector input_tokens, const char* filename, int& lineno, - bool verify_route_file_switch_id , + bool verify_route_file_switch_id, bool is_flat) { if (input_tokens.size() > 3 && input_tokens[3] == "global" && input_tokens[4] == "net" && input_tokens[5] == "connecting:") { @@ -313,7 +306,7 @@ static void process_nets(const Netlist<>& net_list, fp, inet, filename, - verify_route_file_switch_id , + verify_route_file_switch_id, lineno); } input_tokens.clear(); @@ -323,7 +316,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, - bool verify_route_file_switch_id , + bool verify_route_file_switch_id, int& lineno) { /* Not a global net. Goes through every node and add it into trace.head*/ auto& device_ctx = g_vpr_ctx.mutable_device(); @@ -516,66 +509,13 @@ static void process_nodes(const Netlist<>& net_list, oldpos = fp.tellg(); } - if (verify_route_file_switch_id ) { - VTR_ASSERT(validate_traceback(head_ptr)); - } else { - update_rr_switch_id(head_ptr); - } + VTR_ASSERT(validate_and_update_traceback(head_ptr, verify_route_file_switch_id)); /* Convert to route_tree after reading */ route_ctx.route_trees[inet] = TracebackCompat::traceback_to_route_tree(head_ptr); free_traceback(head_ptr); } -static void update_rr_switch_id(t_trace* trace) { - if (trace == nullptr) { - return; - } - - std::set seen_rr_nodes; - - std::stack trace_stack; - trace_stack.push(trace); - - - while (!trace_stack.empty()) { - trace = trace_stack.top(); - trace_stack.pop(); - seen_rr_nodes.insert(trace->index); - t_trace* next = trace->next; - - if (next == nullptr) { - continue; - } - - if (trace->iswitch == OPEN) { // End of a branch - // Verify that the next element (branch point) has been already seen in the traceback so far - if (!seen_rr_nodes.count(next->index)) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); - } - } else { // Midway along branch - // Check there is an edge connecting trace and next - const auto& rr_graph = g_vpr_ctx.device().rr_graph; - bool found = false; - for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { - int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); - if (to_node == next->index) { - found = true; - - // Verify that the switch matches - int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); - trace->iswitch = rr_iswitch; - break; - } - } - if (!found) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); - } - } - trace_stack.push(next); - } -} - 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; From acdafeac784a310924bdfabe23caa4612e413e06 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 13:52:58 -0400 Subject: [PATCH 09/11] make format --- vpr/src/base/SetupVPR.cpp | 2 +- vpr/src/base/read_options.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index f81b988e7e..7e1c2f8961 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -518,7 +518,7 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) RouterOpts->with_timing_analysis = Options.timing_analysis; RouterOpts->verify_route_file_switch_id = Options.verify_route_file_switch_id; - + RouterOpts->generate_router_lookahead_report = Options.generate_router_lookahead_report.value(); } diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index 11d6bd7a6e..f846867af7 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -73,7 +73,7 @@ struct t_options { argparse::ArgValue timing_update_type; argparse::ArgValue CreateEchoFile; argparse::ArgValue verify_file_digests; - argparse::ArgValue verify_route_file_switch_id ; + argparse::ArgValue verify_route_file_switch_id; argparse::ArgValue device_layout; argparse::ArgValue target_device_utilization; argparse::ArgValue constant_net_method; From 84462c2a20895afe2722cb99aa3a468158ffeaf7 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 13:54:44 -0400 Subject: [PATCH 10/11] [doc] add verify_route_file_switch_id to rst doc --- doc/src/vpr/command_line_usage.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/src/vpr/command_line_usage.rst b/doc/src/vpr/command_line_usage.rst index ea6f253365..b3d482e048 100644 --- a/doc/src/vpr/command_line_usage.rst +++ b/doc/src/vpr/command_line_usage.rst @@ -256,6 +256,16 @@ General Options **Default:** ``on`` +.. option:: --verify_route_file_switch_id {on | off} + + Verify that the switch IDs in the routing file are consistent with those in the RR Graph. + Set this to false when switch IDs in the routing file may differ from the RR Graph. + For example, when analyzing different timing corners using the same netlist, placement, and routing files, + the RR switch IDs in the RR Graph may differ due to changes in delays. + In such cases, set this option to false so that the switch IDs from the RR Graph are used, and those in the routing file are ignored. + + **Default:** ``on`` + .. option:: --target_utilization Sets the target device utilization. From c933d5c0a27765b03b4331e7b10776cc934278d8 Mon Sep 17 00:00:00 2001 From: amin1377 Date: Tue, 1 Jul 2025 14:39:49 -0400 Subject: [PATCH 11/11] [vpr][base] expand validate_and_update_traceback comment --- vpr/src/base/old_traceback.cpp | 9 +++++---- vpr/src/base/old_traceback.h | 7 +++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/vpr/src/base/old_traceback.cpp b/vpr/src/base/old_traceback.cpp index 3127f5d312..de708ca296 100644 --- a/vpr/src/base/old_traceback.cpp +++ b/vpr/src/base/old_traceback.cpp @@ -148,6 +148,7 @@ bool validate_and_update_traceback(t_trace* trace, bool verify_switch_id /* = tr std::set seen_rr_nodes; std::stack trace_stack; + trace_stack.push(trace); while (!trace_stack.empty()) { trace = trace_stack.top(); @@ -159,13 +160,13 @@ bool validate_and_update_traceback(t_trace* trace, bool verify_switch_id /* = tr continue; } - if (trace->iswitch == OPEN) { //End of a branch - //Verify that the next element (branch point) has been already seen in the traceback so far + if (trace->iswitch == OPEN) { // End of a branch + // Verify that the next element (branch point) has been already seen in the traceback so far if (!seen_rr_nodes.count(next->index)) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); } - } else { //Midway along branch - //Check there is an edge connecting trace and next + } else { // Midway along branch + // Check there is an edge connecting trace and next const auto& rr_graph = g_vpr_ctx.device().rr_graph; bool found = false; for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { diff --git a/vpr/src/base/old_traceback.h b/vpr/src/base/old_traceback.h index 79dea00975..d0c175622f 100644 --- a/vpr/src/base/old_traceback.h +++ b/vpr/src/base/old_traceback.h @@ -48,8 +48,11 @@ void free_traceback(t_trace* trace); void print_traceback(const t_trace* trace); /** - * @brief Validate the routing traceback if verify_switch_id is true, otherwise update the - * switch IDs in the traceback to match the RR Graph. + * @brief Validate the integrity of the traceback rooted a trace: it should contain only valid rr nodes, branches in the routing tree + * should link to existing routing, and edges in the traceback should exist in the RRGraph. + * If verify_switch_id is true, this routine also checks that the switch types used in the traceback match those in the + * RRGraph. If verify_switch_id is false, the switch ids (types) are remapped to those in the RRGraph. This switch remapping is + * useful when an RRGraph with a more detailed delay model (and hence more switch types) is used with a prior routing. * * @param trace Pointer to the head of the routing trace of the net to validate and update. * @param verify_switch_id Whether to verify the switch IDs in the traceback.