Skip to content

Commit 11303fe

Browse files
committed
Add new RouteTreeNode
1 parent afcd8e2 commit 11303fe

39 files changed

+3502
-1604
lines changed

libs/libvtrutil/src/tl_optional.hpp

Lines changed: 2067 additions & 0 deletions
Large diffs are not rendered by default.

libs/libvtrutil/src/vtr_optional.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
/* std::optional with optional refs.
4+
* currently: import TartanLlama's optional into the vtr namespace
5+
* documentation at https://tl.tartanllama.xyz/en/latest/api/optional.html */
6+
7+
#include "tl_optional.hpp"
8+
9+
namespace vtr {
10+
template<class T>
11+
using optional = tl::optional<T>;
12+
13+
using nullopt_t = tl::nullopt_t;
14+
static constexpr nullopt_t nullopt = tl::nullopt;
15+
16+
using bad_optional_access = tl::bad_optional_access;
17+
}

utils/fasm/src/fasm.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -619,31 +619,29 @@ void FasmWriterVisitor::check_for_lut(const t_pb* atom) {
619619
}
620620

621621
void FasmWriterVisitor::visit_atom_impl(const t_pb* atom) {
622-
check_for_lut(atom);
623-
check_for_param(atom);
622+
check_for_lut(atom);
623+
check_for_param(atom);
624624
}
625625

626-
void FasmWriterVisitor::walk_route_tree(const RRGraphBuilder& rr_graph_builder, const t_rt_node *root) {
627-
for (t_linked_rt_edge* edge = root->u.child_list; edge != nullptr; edge = edge->next) {
628-
auto *meta = vpr::rr_edge_metadata(rr_graph_builder, root->inode, edge->child->inode, edge->iswitch, fasm_features);
626+
void FasmWriterVisitor::walk_route_tree(const RRGraphBuilder& rr_graph_builder, const RouteTreeNode& root) {
627+
for(auto& child: root.child_nodes()){
628+
auto* meta = vpr::rr_edge_metadata(rr_graph_builder, size_t(root.inode), size_t(child.inode), size_t(child.parent_switch), fasm_features);
629+
629630
if(meta != nullptr) {
630631
output_fasm_features(meta->as_string().get(strings_), "", "");
631632
}
632633

633-
walk_route_tree(rr_graph_builder, edge->child);
634+
walk_route_tree(rr_graph_builder, child);
634635
}
635636
}
636637

637638
void FasmWriterVisitor::walk_routing() {
638639
auto& route_ctx = g_vpr_ctx.mutable_routing();
639640
const auto& device_ctx = g_vpr_ctx.device();
640641

641-
for(const auto &trace : route_ctx.trace) {
642-
t_trace *head = trace.head;
643-
if (!head) continue;
644-
t_rt_node* root = traceback_to_route_tree(head, is_flat_);
645-
walk_route_tree(device_ctx.rr_graph_builder, root);
646-
free_route_tree(root);
642+
for(const auto &root : route_ctx.rt_roots) {
643+
if (!root) continue;
644+
walk_route_tree(device_ctx.rr_graph_builder, root.value());
647645
}
648646
}
649647

utils/fasm/src/fasm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class FasmWriterVisitor : public NetlistVisitor {
7373
void check_for_lut(const t_pb* atom);
7474
void output_fasm_mux(std::string fasm_mux, t_interconnect *interconnect, const t_pb_graph_pin *mux_input_pin);
7575
void walk_routing();
76-
void walk_route_tree(const RRGraphBuilder& rr_graph_builder, const t_rt_node *root);
76+
void walk_route_tree(const RRGraphBuilder& rr_graph_builder, const RouteTreeNode& root);
7777
std::string build_clb_prefix(const t_pb *pb, const t_pb_graph_node* pb_graph_node, bool* is_parent_pb_null) const;
7878
const LutOutputDefinition* find_lut(const t_pb_graph_node* pb_graph_node);
7979
void check_for_param(const t_pb *atom);

utils/fasm/test/test_fasm.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include "catch2/catch_test_macros.hpp"
22
#include "catch2/matchers/catch_matchers_all.hpp"
33

4+
#include "route_common.h"
5+
#include "route_tree_timing.h"
6+
#include "t_trace.h"
47
#include "vpr_api.h"
58
#include "vtr_util.h"
69
#include "rr_metadata.h"
@@ -23,7 +26,6 @@ namespace {
2326

2427
// ============================================================================
2528

26-
using Catch::Matchers::Equals;
2729
using Catch::Matchers::StartsWith;
2830
using Catch::Matchers::ContainsSubstring;
2931

@@ -586,21 +588,26 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
586588

587589
// Verify routes
588590
const auto & route_ctx = g_vpr_ctx.routing();
589-
for(const auto &trace : route_ctx.trace) {
590-
const t_trace *head = trace.head;
591-
while(head != nullptr) {
592-
const t_trace *next = head->next;
591+
for(const auto& root : route_ctx.rt_roots) {
592+
if(!root)
593+
continue;
594+
595+
t_trace* head = traceback_from_route_tree_recurr(NULL, NULL, root.value()).first;
596+
t_trace* tptr = head;
597+
while(tptr != nullptr) {
598+
t_trace* next = tptr->next;
593599

594-
if(next != nullptr && head->iswitch != OPEN) {
600+
if(next != nullptr && tptr->iswitch != OPEN) {
595601
const auto next_inode = next->index;
596-
auto iter = routing_edges.find(std::make_tuple(head->index, next_inode, head->iswitch));
602+
auto iter = routing_edges.find(std::make_tuple(tptr->index, next_inode, tptr->iswitch));
597603
if (iter == routing_edges.end()) {
598-
FAIL_CHECK("source: " << head->index << " sink: " << next_inode << " switch:" << head->iswitch);
604+
FAIL_CHECK("source: " << tptr->index << " sink: " << next_inode << " switch:" << tptr->iswitch);
599605
}
600606
}
601607

602-
head = next;
608+
tptr = next;
603609
}
610+
free_traceback(head);
604611
}
605612

606613
// Verify CLB crossbar mux features against routed pin features.

utils/route_diag/src/main.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static void do_one_route(const Netlist<>& net_list,
7474
const auto& rr_graph = device_ctx.rr_graph;
7575
auto& route_ctx = g_vpr_ctx.routing();
7676

77-
t_rt_node* rt_root = init_route_tree_to_source_no_net(source_node);
77+
RouteTreeRoot rt_root = init_route_tree_to_source_no_net(RRNodeId(source_node));
7878

7979
/* Update base costs according to fanout and criticality rules */
8080
update_rr_base_costs(1);
@@ -128,19 +128,19 @@ static void do_one_route(const Netlist<>& net_list,
128128
if (found_path) {
129129
VTR_ASSERT(cheapest.index == sink_node);
130130

131-
t_rt_node* rt_node_of_sink = update_route_tree(&cheapest, OPEN, nullptr, router_opts.flat_routing);
131+
vtr::optional<RouteTreeNode&> rt_node_of_sink;
132+
std::tie(std::ignore, rt_node_of_sink) = update_route_tree(rt_root, &cheapest, OPEN, nullptr, router_opts.flat_routing);
132133

133134
//find delay
134-
float net_delay = rt_node_of_sink->Tdel;
135+
float net_delay = rt_node_of_sink.value().Tdel;
135136
VTR_LOG("Routed successfully, delay = %g!\n", net_delay);
136137
VTR_LOG("\n");
137138
print_route_tree_node(rt_root);
138139
VTR_LOG("\n");
139140
print_route_tree(rt_root);
140141
VTR_LOG("\n");
141142

142-
VTR_ASSERT_MSG(route_ctx.rr_node_route_inf[rt_root->inode].occ() <= rr_graph.node_capacity(RRNodeId(rt_root->inode)), "SOURCE should never be congested");
143-
free_route_tree(rt_root);
143+
VTR_ASSERT_MSG(route_ctx.rr_node_route_inf[size_t(rt_root.inode)].occ() <= rr_graph.node_capacity(RRNodeId(rt_root.inode)), "SOURCE should never be congested");
144144
} else {
145145
VTR_LOG("Routed failed");
146146
}

vpr/src/base/place_and_route.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
6666
std::shared_ptr<SetupHoldTimingInfo> timing_info,
6767
std::shared_ptr<RoutingDelayCalculator> delay_calc,
6868
bool is_flat) {
69-
vtr::vector<ParentNetId, t_trace*> best_routing; /* Saves the best routing found so far. */
70-
69+
vtr::vector<ParentNetId, vtr::optional<RouteTreeRoot>> best_routing; /* Saves the best routing found so far. */
7170
int current, low, high, final;
7271
bool success, prev_success, prev2_success, Fc_clipped = false;
7372
bool using_minw_hint = false;
@@ -100,8 +99,6 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
10099
graph_directionality = (det_routing_arch->directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
101100
}
102101

103-
best_routing = alloc_saved_routing(router_net_list);
104-
105102
VTR_ASSERT(net_delay.size());
106103

107104
if (det_routing_arch->directionality == BI_DIRECTIONAL)
@@ -416,7 +413,6 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
416413
filename_opts.RouteFile.c_str(),
417414
is_flat);
418415

419-
free_saved_routing(router_net_list, best_routing);
420416
fflush(stdout);
421417

422418
return (final);

vpr/src/base/read_route.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
402402
}
403403

404404
/* Convert to route_tree after reading */
405-
route_ctx.current_rt[inet] = traceback_to_route_tree(head_ptr);
405+
route_ctx.rt_roots[inet] = traceback_to_route_tree(head_ptr);
406406
}
407407

408408
/**

vpr/src/base/stats.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ static void load_channel_occupancies(const Netlist<>& net_list,
247247
vtr::Matrix<int>& chanx_occ,
248248
vtr::Matrix<int>& chany_occ) {
249249
int i, j, inode;
250-
t_trace* tptr;
251250
t_rr_type rr_type;
252251

253252
auto& device_ctx = g_vpr_ctx.device();
@@ -264,7 +263,12 @@ static void load_channel_occupancies(const Netlist<>& net_list,
264263
if (net_list.net_is_ignored(net_id) && net_list.net_sinks(net_id).size() != 0)
265264
continue;
266265

267-
tptr = traceback_from_route_tree_recurr(NULL, NULL, route_ctx.current_rt[net_id]).first;
266+
auto& rt_node = route_ctx.rt_roots[net_id];
267+
if(!rt_node)
268+
continue;
269+
270+
t_trace* head = traceback_from_route_tree_recurr(NULL, NULL, rt_node.value()).first;
271+
t_trace* tptr = head;
268272
while (tptr != nullptr) {
269273
inode = tptr->index;
270274
rr_type = rr_graph.node_type(RRNodeId(inode));
@@ -289,6 +293,8 @@ static void load_channel_occupancies(const Netlist<>& net_list,
289293

290294
tptr = tptr->next;
291295
}
296+
297+
free_traceback(head);
292298
}
293299
}
294300

@@ -301,7 +307,7 @@ void get_num_bends_and_length(ParentNetId inet, int* bends_ptr, int* len_ptr, in
301307
auto& device_ctx = g_vpr_ctx.device();
302308
const auto& rr_graph = device_ctx.rr_graph;
303309

304-
t_trace *tptr, *prevptr;
310+
t_trace *tptr, *head;
305311
int inode;
306312
t_rr_type curr_type, prev_type;
307313
int bends, length, segments;
@@ -312,15 +318,17 @@ void get_num_bends_and_length(ParentNetId inet, int* bends_ptr, int* len_ptr, in
312318
length = 0;
313319
segments = 0;
314320

315-
prevptr = traceback_from_route_tree_recurr(NULL, NULL, route_ctx.current_rt[inet]).first; /* Should always be SOURCE. */
316-
if (prevptr == nullptr) {
321+
auto net_root = route_ctx.rt_roots[inet];
322+
if(!net_root){
317323
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
318324
"in get_num_bends_and_length: net #%lu has no traceback.\n", size_t(inet));
319-
}
320-
inode = prevptr->index;
325+
}
326+
327+
head = traceback_from_route_tree_recurr(NULL, NULL, net_root.value()).first; /* Should always be SOURCE. */
328+
inode = head->index;
321329
prev_type = rr_graph.node_type(RRNodeId(inode));
322330

323-
tptr = prevptr->next;
331+
tptr = head->next;
324332

325333
while (tptr != nullptr) {
326334
inode = tptr->index;
@@ -347,6 +355,8 @@ void get_num_bends_and_length(ParentNetId inet, int* bends_ptr, int* len_ptr, in
347355
tptr = tptr->next;
348356
}
349357

358+
free_traceback(head);
359+
350360
*bends_ptr = bends;
351361
*len_ptr = length;
352362
*segments_ptr = segments;

vpr/src/base/vpr_api.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ static void free_placement() {
11831183

11841184
static void free_routing() {
11851185
auto& routing_ctx = g_vpr_ctx.mutable_routing();
1186-
routing_ctx.current_rt.clear();
1186+
routing_ctx.rt_roots.clear();
11871187
routing_ctx.trace_nodes.clear();
11881188
routing_ctx.net_rr_terminals.clear();
11891189
routing_ctx.rr_blk_source.clear();
@@ -1375,7 +1375,7 @@ void vpr_analysis(const Netlist<>& net_list,
13751375

13761376
//Check the first index to see if a pointer exists
13771377
//TODO: Implement a better error check
1378-
if (route_ctx.current_rt.empty()) {
1378+
if (route_ctx.rt_roots.empty()) {
13791379
VPR_FATAL_ERROR(VPR_ERROR_ANALYSIS, "No routing loaded -- can not perform post-routing analysis");
13801380
}
13811381

vpr/src/base/vpr_context.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "vpr_types.h"
99
#include "vtr_ndmatrix.h"
10+
#include "vtr_optional.h"
1011
#include "vtr_vector.h"
1112
#include "atom_netlist.h"
1213
#include "clustered_netlist.h"
@@ -393,7 +394,7 @@ struct PlacementContext : public Context {
393394
*/
394395
struct RoutingContext : public Context {
395396
/* [0..num_nets-1] of linked list start pointers. Defines the routing. */
396-
vtr::vector<ParentNetId, t_rt_node*> current_rt;
397+
vtr::vector<ParentNetId, vtr::optional<RouteTreeRoot>> rt_roots;
397398

398399
vtr::vector<ParentNetId, std::unordered_set<int>> trace_nodes;
399400

vpr/src/draw/draw.cpp

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -847,54 +847,43 @@ std::vector<int> trace_routed_connection_rr_nodes(
847847
bool is_flat) {
848848
auto& route_ctx = g_vpr_ctx.routing();
849849

850-
bool allocated_route_tree_structs = alloc_route_tree_timing_structs(true); //Needed for traceback_to_route_tree
850+
VTR_ASSERT(route_ctx.rt_roots[net_id]);
851+
const RouteTreeNode& net_root = route_ctx.rt_roots[net_id].value();
851852

852-
t_rt_node* rt_root = route_ctx.current_rt[net_id];
853-
854-
VTR_ASSERT(
855-
rt_root
856-
&& rt_root->inode
857-
== route_ctx.net_rr_terminals[ParentNetId(size_t(net_id))][driver_pin]);
853+
VTR_ASSERT(net_root.inode == RRNodeId(route_ctx.net_rr_terminals[net_id][driver_pin]));
858854

859855
int sink_rr_node = route_ctx.net_rr_terminals[ParentNetId(size_t(net_id))][sink_pin];
860856

861857
std::vector<int> rr_nodes_on_path;
862858

863859
//Collect the rr nodes
864-
trace_routed_connection_rr_nodes_recurr(rt_root, sink_rr_node,
860+
trace_routed_connection_rr_nodes_recurr(net_root, sink_rr_node,
865861
rr_nodes_on_path);
866862

867863
//Traced from sink to source, but we want to draw from source to sink
868864
std::reverse(rr_nodes_on_path.begin(), rr_nodes_on_path.end());
869865

870-
if (allocated_route_tree_structs) {
871-
free_route_tree_timing_structs();
872-
}
873866
return rr_nodes_on_path;
874867
}
875868

876869
//Helper function for trace_routed_connection_rr_nodes
877870
//Adds the rr nodes linking rt_node to sink_rr_node to rr_nodes_on_path
878871
//Returns true if rt_node is on the path
879-
bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node,
872+
bool trace_routed_connection_rr_nodes_recurr(const RouteTreeNode& rt_node,
880873
int sink_rr_node,
881874
std::vector<int>& rr_nodes_on_path) {
882875
//DFS from the current rt_node to the sink_rr_node, when the sink is found trace back the used rr nodes
883876

884-
if (rt_node->inode == sink_rr_node) {
877+
if (rt_node.inode == RRNodeId(sink_rr_node)) {
885878
rr_nodes_on_path.push_back(sink_rr_node);
886879
return true;
887880
}
888881

889-
for (t_linked_rt_edge* edge = rt_node->u.child_list; edge != nullptr; edge = edge->next) {
890-
t_rt_node* child_rt_node = edge->child;
891-
VTR_ASSERT(child_rt_node);
892-
882+
for(const RouteTreeNode& child_rt_node: rt_node.child_nodes()){
893883
bool on_path_to_sink = trace_routed_connection_rr_nodes_recurr(
894884
child_rt_node, sink_rr_node, rr_nodes_on_path);
895-
896885
if (on_path_to_sink) {
897-
rr_nodes_on_path.push_back(rt_node->inode);
886+
rr_nodes_on_path.push_back(size_t(rt_node.inode));
898887
return true;
899888
}
900889
}

0 commit comments

Comments
 (0)