Skip to content

Commit 81a4a8e

Browse files
authored
Merge pull request #2324 from verilog-to-routing/flat_router_test
Flat router test
2 parents b029235 + d61831e commit 81a4a8e

File tree

34 files changed

+864
-414
lines changed

34 files changed

+864
-414
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1713,7 +1713,11 @@ struct t_arch_switch_inf {
17131713
* mux_trans_size: The area of each transistor in the segment's driving mux *
17141714
* measured in minimum width transistor units *
17151715
* buf_size: The area of the buffer. If set to zero, area should be *
1716-
* calculated from R */
1716+
* calculated from R
1717+
* intra_tile: Indicate whether this rr_switch is a switch type used inside *
1718+
* clusters. These switch types are not specified in the *
1719+
* architecture description file and are added when flat router *
1720+
* is enabled */
17171721
struct t_rr_switch_inf {
17181722
float R = 0.;
17191723
float Cin = 0.;
@@ -1726,6 +1730,8 @@ struct t_rr_switch_inf {
17261730
e_power_buffer_type power_buffer_type = POWER_BUFFER_TYPE_UNDEFINED;
17271731
float power_buffer_size = 0.;
17281732

1733+
bool intra_tile = false;
1734+
17291735
public:
17301736
//Returns the type of switch
17311737
SwitchType type() const;

libs/librrgraph/src/base/rr_edge.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33

44
#include "rr_graph_fwd.h"
55

6-
/* TODO: MUST change the node id to RRNodeId before refactoring is finished! */
76
struct t_rr_edge_info {
8-
t_rr_edge_info(RRNodeId from, RRNodeId to, short type, bool is_remapped = false) noexcept
7+
t_rr_edge_info(RRNodeId from, RRNodeId to, short type, bool is_remapped) noexcept
98
: from_node(from)
109
, to_node(to)
1110
, switch_type(type)

libs/librrgraph/src/base/rr_graph_builder.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ void RRGraphBuilder::add_node_to_all_locs(RRNodeId node) {
6060
}
6161
}
6262

63+
void RRGraphBuilder::init_edge_remap(bool val) {
64+
node_storage_.init_edge_remap(val);
65+
}
66+
67+
void RRGraphBuilder::clear_temp_storage() {
68+
node_storage_.clear_temp_storage();
69+
}
70+
6371
void RRGraphBuilder::clear() {
6472
node_lookup_.clear();
6573
node_storage_.clear();

libs/librrgraph/src/base/rr_graph_builder.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ class RRGraphBuilder {
129129
*/
130130
void add_node_to_all_locs(RRNodeId node);
131131

132+
void init_edge_remap(bool val);
133+
134+
void clear_temp_storage();
135+
132136
/** @brief Clear all the underlying data storage */
133137
void clear();
134138
/** @brief reorder all the nodes
@@ -216,10 +220,14 @@ class RRGraphBuilder {
216220
node_storage_.reserve_edges(num_edges);
217221
}
218222

219-
/** @brief emplace_back_edge; It add one edge. This method is efficient if reserve_edges was called with
220-
* the number of edges present in the graph. */
221-
inline void emplace_back_edge(RRNodeId src, RRNodeId dest, short edge_switch) {
222-
node_storage_.emplace_back_edge(src, dest, edge_switch);
223+
/** @brief emplace_back_edge It adds one edge. This method is efficient if reserve_edges was called with
224+
* the number of edges present in the graph.
225+
* @param remapped If true, it means the switch id (edge_switch) corresponds to rr switch id. Thus, when the remapped function is called to
226+
* remap the arch switch id to rr switch id, the edge switch id of this edge shouldn't be changed. For example, when the intra-cluster graph
227+
* is built and the rr-graph related to global resources are read from a file, this parameter is true since the intra-cluster switches are
228+
* also listed in rr-graph file. So, we use that list to use the rr switch id instead of passing arch switch id for intra-cluster edges.*/
229+
inline void emplace_back_edge(RRNodeId src, RRNodeId dest, short edge_switch, bool remapped) {
230+
node_storage_.emplace_back_edge(src, dest, edge_switch, remapped);
223231
}
224232
/** @brief Append 1 more RR node to the RR graph. */
225233
inline void emplace_back() {

libs/librrgraph/src/base/rr_graph_storage.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ void t_rr_graph_storage::reserve_edges(size_t num_edges) {
1111
edge_remapped_.reserve(num_edges);
1212
}
1313

14-
void t_rr_graph_storage::emplace_back_edge(RRNodeId src, RRNodeId dest, short edge_switch) {
14+
void t_rr_graph_storage::emplace_back_edge(RRNodeId src, RRNodeId dest, short edge_switch, bool remapped) {
1515
// Cannot mutate edges once edges have been read!
1616
VTR_ASSERT(!edges_read_);
1717
edge_src_node_.emplace_back(src);
1818
edge_dest_node_.emplace_back(dest);
1919
edge_switch_.emplace_back(edge_switch);
20-
edge_remapped_.emplace_back(false);
20+
edge_remapped_.emplace_back(remapped);
2121
}
2222

2323
// Typical node to edge ratio. This allows a preallocation guess for the edges
@@ -48,7 +48,8 @@ void t_rr_graph_storage::alloc_and_load_edges(const t_rr_edge_info_set* rr_edges
4848
emplace_back_edge(
4949
new_edge.from_node,
5050
new_edge.to_node,
51-
new_edge.switch_type);
51+
new_edge.switch_type,
52+
new_edge.remapped);
5253
}
5354
}
5455

@@ -398,17 +399,10 @@ void t_rr_graph_storage::init_fan_in() {
398399
//Reset all fan-ins to zero
399400
edges_read_ = true;
400401
node_fan_in_.resize(node_storage_.size(), 0);
401-
// This array is used to avoid initializing fan-in of the nodes which are already seen.
402-
// This would reduce the run-time of flat rr graph generation since this function is called twice.
403-
seen_edge_.resize(edge_dest_node_.size(), false);
404402
node_fan_in_.shrink_to_fit();
405-
seen_edge_.shrink_to_fit();
406403
//Walk the graph and increment fanin on all downstream nodes
407404
for(const auto& edge_id : edge_dest_node_.keys()) {
408-
if(!seen_edge_[edge_id]) {
409-
node_fan_in_[edge_dest_node_[edge_id]] += 1;
410-
seen_edge_[edge_id] = true;
411-
}
405+
node_fan_in_[edge_dest_node_[edge_id]] += 1;
412406
}
413407
}
414408

@@ -829,7 +823,6 @@ void t_rr_graph_storage::reorder(const vtr::vector<RRNodeId, RRNodeId>& order,
829823
auto old_edge_dest_node = edge_dest_node_;
830824
auto old_edge_switch = edge_switch_;
831825
auto old_edge_remapped = edge_remapped_;
832-
auto old_seen_edge = seen_edge_;
833826
RREdgeId cur_edge(0);
834827

835828
// Reorder edges by source node
@@ -843,7 +836,6 @@ void t_rr_graph_storage::reorder(const vtr::vector<RRNodeId, RRNodeId>& order,
843836
edge_dest_node_[cur_edge] = order[old_edge_dest_node[e]];
844837
edge_switch_[cur_edge] = old_edge_switch[e];
845838
edge_remapped_[cur_edge] = old_edge_remapped[e];
846-
seen_edge_[cur_edge] = old_seen_edge[e];
847839
cur_edge = RREdgeId(size_t(cur_edge) + 1);
848840
}
849841
}

libs/librrgraph/src/base/rr_graph_storage.h

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,6 @@ class t_rr_graph_storage {
442442
node_first_edge_.clear();
443443
node_fan_in_.clear();
444444
node_layer_.clear();
445-
seen_edge_.clear();
446445
edge_src_node_.clear();
447446
edge_dest_node_.clear();
448447
edge_switch_.clear();
@@ -452,6 +451,18 @@ class t_rr_graph_storage {
452451
remapped_edges_ = false;
453452
}
454453

454+
// Clear the data structures that are mainly used during RR graph construction.
455+
// After RR Graph is build, we no longer need these data structures.
456+
void clear_temp_storage() {
457+
edge_remapped_.clear();
458+
}
459+
460+
// Clear edge_remap data structure, and then initialize it with the given value
461+
void init_edge_remap(bool val) {
462+
edge_remapped_.clear();
463+
edge_remapped_.resize(edge_switch_.size(), val);
464+
}
465+
455466
// Shrink memory usage of the RR graph storage.
456467
//
457468
// Note that this will temporarily increase the amount of storage required
@@ -462,7 +473,6 @@ class t_rr_graph_storage {
462473
node_first_edge_.shrink_to_fit();
463474
node_fan_in_.shrink_to_fit();
464475
node_layer_.shrink_to_fit();
465-
seen_edge_.shrink_to_fit();
466476
edge_src_node_.shrink_to_fit();
467477
edge_dest_node_.shrink_to_fit();
468478
edge_switch_.shrink_to_fit();
@@ -561,11 +571,18 @@ class t_rr_graph_storage {
561571
// Reserve at least num_edges in the edge backing arrays.
562572
void reserve_edges(size_t num_edges);
563573

564-
// Add one edge. This method is efficient if reserve_edges was called with
565-
// the number of edges present in the graph. This method is still
566-
// amortized O(1), like std::vector::emplace_back, but both runtime and
567-
// peak memory usage will be higher if reallocation is required.
568-
void emplace_back_edge(RRNodeId src, RRNodeId dest, short edge_switch);
574+
/***
575+
* @brief Add one edge. This method is efficient if reserve_edges was called with
576+
* the number of edges present in the graph. This method is still
577+
* amortized O(1), like std::vector::emplace_back, but both runtime and
578+
* peak memory usage will be higher if reallocation is required.
579+
* @param remapped This is used later in remap_rr_node_switch_indices to check whether an
580+
* edge needs its switch ID remapped from the arch_sw_idx to rr_sw_idx.
581+
* The difference between these two ids is because some switch delays depend on the fan-in
582+
* of the node. Also, the information about switches is fly-weighted and are accessible with IDs. Thus,
583+
* the number of rr switch types can be higher than the number of arch switch types.
584+
*/
585+
void emplace_back_edge(RRNodeId src, RRNodeId dest, short edge_switch, bool remapped);
569586

570587
// Adds a batch of edges.
571588
void alloc_and_load_edges(const t_rr_edge_info_set* rr_edges_to_create);
@@ -696,10 +713,24 @@ class t_rr_graph_storage {
696713
vtr::vector<RREdgeId, RRNodeId> edge_src_node_;
697714
vtr::vector<RREdgeId, RRNodeId> edge_dest_node_;
698715
vtr::vector<RREdgeId, short> edge_switch_;
716+
/**
717+
* The delay of certain switches specified in the architecture file depends on the number of inputs of the edge's sink node (pins or tracks).
718+
* For example, in the case of a MUX switch, the delay increases as the number of inputs increases.
719+
* During the construction of the RR Graph, switch IDs are assigned to the edges according to the order specified in the architecture file.
720+
* These switch IDs are later used to retrieve information such as delay for each edge.
721+
* This allows for effective fly-weighting of edge information.
722+
*
723+
* After building the RR Graph, we iterate over the nodes once more to store their fan-in.
724+
* If a switch's characteristics depend on the fan-in of a node, a new switch ID is generated and assigned to the corresponding edge.
725+
* This process is known as remapping.
726+
* In this vector, we store information about which edges have undergone remapping.
727+
* It is necessary to store this information, especially when flat-router is enabled.
728+
* Remapping occurs when constructing global resources after placement and when adding intra-cluster resources after placement.
729+
* Without storing this information, during subsequent remappings, it would be unclear whether the stored switch ID
730+
* corresponds to the architecture ID or the RR Graph switch ID for an edge.
731+
*/
699732
vtr::vector<RREdgeId, bool> edge_remapped_;
700733

701-
vtr::vector<RREdgeId, bool> seen_edge_;
702-
703734
/***************
704735
* State flags *
705736
***************/

libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,19 +460,23 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
460460
//
461461
// If the switch name is not present in the architecture, generate an
462462
// error.
463+
// If the graph is written when flat-routing is enabled, the types of the switches inside of the rr_graph are also
464+
// added to the XML file. These types are not added to the data structure that contain arch switch types. They are added to all_sw_inf under device context.
465+
// It remains as a future work to remove the arch_switch_types and use all_sw info under device_ctx instead.
463466
bool found_arch_name = false;
464467
std::string string_name = std::string(name);
468+
// The string name has the format of "Internal Switch/delay". So, I have to use compare to specify the portion I want to be compared.
469+
bool is_internal_sw = string_name.compare(0, 15, "Internal Switch") == 0;
465470
for (const auto& arch_sw_inf: arch_switch_inf_) {
466-
if (string_name == arch_sw_inf.name) {
467-
string_name = arch_sw_inf.name;
471+
if (string_name == arch_sw_inf.name || is_internal_sw) {
468472
found_arch_name = true;
469473
break;
470474
}
471475
}
472476
if (!found_arch_name) {
473477
report_error("Switch name '%s' not found in architecture\n", string_name.c_str());
474478
}
475-
479+
sw->intra_tile = is_internal_sw;
476480
sw->name = string_name;
477481
}
478482
inline const char* get_switch_name(const t_rr_switch_inf*& sw) final {
@@ -832,6 +836,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
832836
inline void finish_rr_nodes_node(int& /*inode*/) final {
833837
}
834838
inline size_t num_rr_nodes_node(void*& /*ctx*/) final {
839+
835840
return rr_nodes_->size();
836841
}
837842
inline const t_rr_node get_rr_nodes_node(int n, void*& /*ctx*/) final {
@@ -923,7 +928,8 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
923928
bind.set_ignore();
924929
}
925930

926-
rr_graph_builder_->emplace_back_edge(RRNodeId(src_node), RRNodeId(sink_node), switch_id);
931+
// The edge ids in the rr graph file are rr edge id not architecture edge id
932+
rr_graph_builder_->emplace_back_edge(RRNodeId(src_node), RRNodeId(sink_node), switch_id, true);
927933
return bind;
928934
}
929935
inline void finish_rr_edges_edge(MetadataBind& bind) final {

0 commit comments

Comments
 (0)