|
17 | 17 | #include <cstdio>
|
18 | 18 | #include <sstream>
|
19 | 19 | #include <string>
|
| 20 | +#include <stack> |
20 | 21 |
|
21 | 22 | #include "physical_types_util.h"
|
22 | 23 | #include "vtr_assert.h"
|
@@ -99,13 +100,9 @@ static void process_nets(const Netlist<>& net_list,
|
99 | 100 | /**
|
100 | 101 | * @brief Update the switch IDs in the routing trace to match the RR Graph.
|
101 | 102 | *
|
102 |
| - * @note This function is called recursively to update the switch IDs in the routing trace. |
103 |
| - * |
104 | 103 | * @param trace Pointer to the head of the routing trace of the net to update.
|
105 |
| - * @param seen_rr_nodes A set of seen RR nodes to avoid duplicate updates. |
106 | 104 | */
|
107 |
| -static void update_rr_switch_id(t_trace* trace, |
108 |
| - std::set<int>& seen_rr_nodes); |
| 105 | +static void update_rr_switch_id(t_trace* trace); |
109 | 106 |
|
110 | 107 | /**
|
111 | 108 | * @brief This function goes through all the blocks in a global net and verify
|
@@ -522,54 +519,61 @@ static void process_nodes(const Netlist<>& net_list,
|
522 | 519 | if (verify_route_file_switch_id ) {
|
523 | 520 | VTR_ASSERT(validate_traceback(head_ptr));
|
524 | 521 | } else {
|
525 |
| - std::set<int> seen_rr_nodes; |
526 |
| - update_rr_switch_id(head_ptr, seen_rr_nodes); |
| 522 | + update_rr_switch_id(head_ptr); |
527 | 523 | }
|
528 | 524 |
|
529 | 525 | /* Convert to route_tree after reading */
|
530 | 526 | route_ctx.route_trees[inet] = TracebackCompat::traceback_to_route_tree(head_ptr);
|
531 | 527 | free_traceback(head_ptr);
|
532 | 528 | }
|
533 | 529 |
|
534 |
| -static void update_rr_switch_id(t_trace* trace, std::set<int>& seen_rr_nodes) { |
| 530 | +static void update_rr_switch_id(t_trace* trace) { |
535 | 531 | if (trace == nullptr) {
|
536 | 532 | return;
|
537 | 533 | }
|
538 | 534 |
|
539 |
| - seen_rr_nodes.insert(trace->index); |
| 535 | + std::set<int> seen_rr_nodes; |
540 | 536 |
|
541 |
| - t_trace* next = trace->next; |
| 537 | + std::stack<t_trace*> trace_stack; |
| 538 | + trace_stack.push(trace); |
542 | 539 |
|
543 |
| - if (next == nullptr) { |
544 |
| - return; |
545 |
| - } |
546 | 540 |
|
547 |
| - if (trace->iswitch == OPEN) { // End of a branch |
548 |
| - // Verify that the next element (branch point) has been already seen in the traceback so far |
549 |
| - if (!seen_rr_nodes.count(next->index)) { |
550 |
| - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); |
| 541 | + while (!trace_stack.empty()) { |
| 542 | + trace = trace_stack.top(); |
| 543 | + trace_stack.pop(); |
| 544 | + seen_rr_nodes.insert(trace->index); |
| 545 | + t_trace* next = trace->next; |
| 546 | + |
| 547 | + if (next == nullptr) { |
| 548 | + continue; |
551 | 549 | }
|
552 |
| - } else { // Midway along branch |
553 |
| - // Check there is an edge connecting trace and next |
554 |
| - const auto& rr_graph = g_vpr_ctx.device().rr_graph; |
555 |
| - bool found = false; |
556 |
| - for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { |
557 |
| - int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); |
558 |
| - if (to_node == next->index) { |
559 |
| - found = true; |
560 |
| - |
561 |
| - // Verify that the switch matches |
562 |
| - int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); |
563 |
| - trace->iswitch = rr_iswitch; |
564 |
| - break; |
| 550 | + |
| 551 | + if (trace->iswitch == OPEN) { // End of a branch |
| 552 | + // Verify that the next element (branch point) has been already seen in the traceback so far |
| 553 | + if (!seen_rr_nodes.count(next->index)) { |
| 554 | + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback branch point %d not found", next->index); |
| 555 | + } |
| 556 | + } else { // Midway along branch |
| 557 | + // Check there is an edge connecting trace and next |
| 558 | + const auto& rr_graph = g_vpr_ctx.device().rr_graph; |
| 559 | + bool found = false; |
| 560 | + for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(trace->index)); ++iedge) { |
| 561 | + int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), iedge)); |
| 562 | + if (to_node == next->index) { |
| 563 | + found = true; |
| 564 | + |
| 565 | + // Verify that the switch matches |
| 566 | + int rr_iswitch = rr_graph.edge_switch(RRNodeId(trace->index), iedge); |
| 567 | + trace->iswitch = rr_iswitch; |
| 568 | + break; |
| 569 | + } |
| 570 | + } |
| 571 | + if (!found) { |
| 572 | + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); |
565 | 573 | }
|
566 | 574 | }
|
567 |
| - if (!found) { |
568 |
| - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Traceback no RR edge between RR nodes %d -> %d\n", trace->index, next->index); |
569 |
| - } |
| 575 | + trace_stack.push(next); |
570 | 576 | }
|
571 |
| - // Recurse |
572 |
| - update_rr_switch_id(next, seen_rr_nodes); |
573 | 577 | }
|
574 | 578 |
|
575 | 579 | static void process_global_blocks(const Netlist<>& net_list, std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, bool is_flat) {
|
|
0 commit comments