Skip to content

Commit 8447e3b

Browse files
authored
Merge pull request #3164 from verilog-to-routing/verify_rr_edge_id
RR Edge ID Verification
2 parents 9d29ee2 + c933d5c commit 8447e3b

File tree

10 files changed

+219
-65
lines changed

10 files changed

+219
-65
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,16 @@ General Options
256256

257257
**Default:** ``on``
258258

259+
.. option:: --verify_route_file_switch_id {on | off}
260+
261+
Verify that the switch IDs in the routing file are consistent with those in the RR Graph.
262+
Set this to false when switch IDs in the routing file may differ from the RR Graph.
263+
For example, when analyzing different timing corners using the same netlist, placement, and routing files,
264+
the RR switch IDs in the RR Graph may differ due to changes in delays.
265+
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.
266+
267+
**Default:** ``on``
268+
259269
.. option:: --target_utilization <float>
260270

261271
Sets the target device utilization.

vpr/src/base/SetupVPR.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,8 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts)
517517
RouterOpts->custom_3d_sb_fanin_fanout = Options.custom_3d_sb_fanin_fanout;
518518
RouterOpts->with_timing_analysis = Options.timing_analysis;
519519

520+
RouterOpts->verify_route_file_switch_id = Options.verify_route_file_switch_id;
521+
520522
RouterOpts->generate_router_lookahead_report = Options.generate_router_lookahead_report.value();
521523
}
522524

vpr/src/base/old_traceback.cpp

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
#include "route_common.h"
77

88
#include <vector>
9+
#include <stack>
910

1011
std::pair<t_trace*, t_trace*> traceback_from_route_tree_recurr(t_trace* head, t_trace* tail, const RouteTreeNode& node);
11-
bool validate_traceback_recurr(t_trace* trace, std::set<int>& seen_rr_nodes);
1212
void free_trace_data(t_trace* tptr);
1313

1414
/** Build a route tree from a traceback */
@@ -109,7 +109,7 @@ t_trace* TracebackCompat::traceback_from_route_tree(const RouteTree& tree) {
109109

110110
std::tie(head, tail) = traceback_from_route_tree_recurr(nullptr, nullptr, tree.root());
111111

112-
VTR_ASSERT(validate_traceback(head));
112+
VTR_ASSERT(validate_and_update_traceback(head));
113113

114114
return head;
115115
}
@@ -141,70 +141,65 @@ void print_traceback(const t_trace* trace) {
141141
VTR_LOG("\n");
142142
}
143143

144-
bool validate_traceback(t_trace* trace) {
145-
std::set<int> seen_rr_nodes;
146-
147-
return validate_traceback_recurr(trace, seen_rr_nodes);
148-
}
149-
150-
bool validate_traceback_recurr(t_trace* trace, std::set<int>& seen_rr_nodes) {
144+
bool validate_and_update_traceback(t_trace* trace, bool verify_switch_id /* = true */) {
151145
if (!trace) {
152146
return true;
153147
}
154148

155-
seen_rr_nodes.insert(trace->index);
149+
std::set<int> seen_rr_nodes;
150+
std::stack<t_trace*> trace_stack;
151+
trace_stack.push(trace);
156152

157-
t_trace* next = trace->next;
153+
while (!trace_stack.empty()) {
154+
trace = trace_stack.top();
155+
trace_stack.pop();
156+
seen_rr_nodes.insert(trace->index);
157+
t_trace* next = trace->next;
158158

159-
if (next) {
160-
if (trace->iswitch == OPEN) { //End of a branch
159+
if (next == nullptr) {
160+
continue;
161+
}
161162

162-
//Verify that the next element (branch point) has been already seen in the traceback so far
163+
if (trace->iswitch == OPEN) { // End of a branch
164+
// Verify that the next element (branch point) has been already seen in the traceback so far
163165
if (!seen_rr_nodes.count(next->index)) {
164166
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index);
165-
} else {
166-
//Recurse along the new branch
167-
return validate_traceback_recurr(next, seen_rr_nodes);
168167
}
169-
} else { //Midway along branch
170-
171-
//Check there is an edge connecting trace and next
172-
173-
auto& device_ctx = g_vpr_ctx.device();
174-
const auto& rr_graph = device_ctx.rr_graph;
168+
} else { // Midway along branch
169+
// Check there is an edge connecting trace and next
170+
const auto& rr_graph = g_vpr_ctx.device().rr_graph;
175171
bool found = false;
176172
for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) {
177173
int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge));
178-
179174
if (to_node == next->index) {
180175
found = true;
181-
182-
//Verify that the switch matches
183176
int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge);
184-
if (trace->iswitch != rr_iswitch) {
185-
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback mismatched switch type: traceback %d rr_graph %d (RR nodes %d -> %d)\n",
186-
trace->iswitch, rr_iswitch,
187-
trace->index, to_node);
177+
if (verify_switch_id) {
178+
// Verify that the switch matches
179+
if (trace->iswitch != rr_iswitch) {
180+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback mismatched switch type: traceback %d rr_graph %d (RR nodes %d -> %d)\n",
181+
trace->iswitch, rr_iswitch,
182+
trace->index, to_node);
183+
}
184+
} else {
185+
// Update the switch ID in the traceback to match the RR Graph
186+
trace->iswitch = rr_iswitch;
188187
}
189188
break;
190189
}
191190
}
192-
193191
if (!found) {
194192
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index);
195193
}
196-
197-
//Recurse
198-
return validate_traceback_recurr(next, seen_rr_nodes);
199194
}
195+
// Recurse
196+
trace_stack.push(next);
200197
}
201198

202-
VTR_ASSERT(!next);
203-
return true; //End of traceback
199+
return true;
204200
}
205201

206-
t_trace*
207-
alloc_trace_data() {
202+
t_trace* alloc_trace_data() {
208203
return (t_trace*)malloc(sizeof(t_trace));
209204
}
210205

vpr/src/base/old_traceback.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,17 @@ class TracebackCompat {
4646
t_trace* alloc_trace_data();
4747
void free_traceback(t_trace* trace);
4848
void print_traceback(const t_trace* trace);
49-
bool validate_traceback(t_trace* trace);
49+
50+
/**
51+
* @brief Validate the integrity of the traceback rooted a trace: it should contain only valid rr nodes, branches in the routing tree
52+
* should link to existing routing, and edges in the traceback should exist in the RRGraph.
53+
* If verify_switch_id is true, this routine also checks that the switch types used in the traceback match those in the
54+
* RRGraph. If verify_switch_id is false, the switch ids (types) are remapped to those in the RRGraph. This switch remapping is
55+
* useful when an RRGraph with a more detailed delay model (and hence more switch types) is used with a prior routing.
56+
*
57+
* @param trace Pointer to the head of the routing trace of the net to validate and update.
58+
* @param verify_switch_id Whether to verify the switch IDs in the traceback.
59+
*
60+
* @return true if the traceback is valid, false otherwise.
61+
*/
62+
bool validate_and_update_traceback(t_trace* trace, bool verify_switch_id = true);

vpr/src/base/read_options.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,16 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
16371637
.default_value("on")
16381638
.show_in(argparse::ShowIn::HELP_ONLY);
16391639

1640+
gen_grp.add_argument<bool, ParseOnOff>(args.verify_route_file_switch_id, "--verify_route_file_switch_id")
1641+
.help(
1642+
"Verify that the switch IDs in the routing file are consistent with those in the RR Graph. "
1643+
"Set this to false when switch IDs in the routing file may differ from the RR Graph. "
1644+
"For example, when analyzing different timing corners using the same netlist, placement, and routing files, "
1645+
"the RR switch IDs in the RR Graph may differ due to changes in delays. "
1646+
"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")
1647+
.default_value("on")
1648+
.show_in(argparse::ShowIn::HELP_ONLY);
1649+
16401650
gen_grp.add_argument(args.target_device_utilization, "--target_utilization")
16411651
.help(
16421652
"Sets the target device utilization."

vpr/src/base/read_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct t_options {
7373
argparse::ArgValue<e_timing_update_type> timing_update_type;
7474
argparse::ArgValue<bool> CreateEchoFile;
7575
argparse::ArgValue<bool> verify_file_digests;
76+
argparse::ArgValue<bool> verify_route_file_switch_id;
7677
argparse::ArgValue<std::string> device_layout;
7778
argparse::ArgValue<float> target_device_utilization;
7879
argparse::ArgValue<e_constant_net_method> constant_net_method;

0 commit comments

Comments
 (0)