Skip to content

Commit 75210e1

Browse files
authored
Merge pull request #2674 from verilog-to-routing/read_rr_graph_run_flat
Fix for Handling Missing Switch Types in RR Graph Builder
2 parents 21d0150 + 814b12e commit 75210e1

File tree

1 file changed

+88
-54
lines changed

1 file changed

+88
-54
lines changed

vpr/src/route/rr_graph.cpp

Lines changed: 88 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,27 @@ static void connect_tile_src_sink_to_pins(RRGraphBuilder& rr_graph_builder,
264264
const int delayless_switch,
265265
t_physical_tile_type_ptr physical_type_ptr);
266266

267+
/**
268+
* Add the edges between IPIN to SINK and SOURCE to OPIN to rr_edges_to_create
269+
* @param rr_graph_builder RR Graph Bulder object which contain the RR Graph storage
270+
* @param class_num_vec Class physical numbers to add the edges connected to them
271+
* @param layer The layer number of the block to add the SINK/SRC connections of it.
272+
* @param i The x location of the block to add the SINK/SRC connections of it.
273+
* @param j The y location of the block to add the SINK/SRC connections of it
274+
* @param rr_edges_to_create An object which store all of the edges created in this function.
275+
* @param delayless_switch Switch ID of the delayless switch.
276+
* @param physical_type_ptr A pointer to the physical type of the block for which the edges are created.
277+
* @param switches_remapped A flag to indicate whether edge switch IDs are remapped
278+
*/
267279
static void connect_src_sink_to_pins(RRGraphBuilder& rr_graph_builder,
268280
const std::vector<int>& class_num_vec,
269281
const int layer,
270282
const int i,
271283
const int j,
272284
t_rr_edge_info_set& rr_edges_to_create,
273285
const int delayless_switch,
274-
t_physical_tile_type_ptr physical_type_ptr);
286+
t_physical_tile_type_ptr physical_type_ptr,
287+
bool switches_remapped);
275288

276289
static void alloc_and_load_tile_rr_graph(RRGraphBuilder& rr_graph_builder,
277290
std::map<int, t_arch_switch_inf>& arch_sw_inf_map,
@@ -374,11 +387,13 @@ static void add_pb_edges(RRGraphBuilder& rr_graph_builder,
374387
t_logical_block_type_ptr logical_block,
375388
const t_pb* pb,
376389
const t_cluster_pin_chain& nodes_to_collapse,
390+
float R_minW_nmos,
391+
float R_minW_pmos,
377392
int rel_cap,
378393
int layer,
379394
int i,
380395
int j,
381-
bool is_remapped);
396+
bool switches_remapped);
382397

383398
/**
384399
* Edges going in/out of collapse nodes are not added by the normal routine. This function add those edges
@@ -656,6 +671,15 @@ static void build_intra_cluster_rr_graph(const t_graph_type graph_type,
656671
bool is_flat,
657672
bool load_rr_graph);
658673

674+
/**
675+
* Return the ID for delayess switch. If the RR graph is loaded from a file, then the assumption
676+
* is that the returned ID should be a RR switch ID not architecture ID.
677+
* @param det_routing_arch Contain the information from architecture file
678+
* @param load_rr_graph Indicate whether the RR graph is loaded from a file
679+
*/
680+
static int get_delayless_switch_id(t_det_routing_arch* det_routing_arch,
681+
bool load_rr_graph);
682+
659683
/******************* Subroutine definitions *******************************/
660684

661685
void create_rr_graph(const t_graph_type graph_type,
@@ -741,11 +765,13 @@ void create_rr_graph(const t_graph_type graph_type,
741765
}
742766

743767
if (is_flat) {
768+
int delayless_switch = get_delayless_switch_id(det_routing_arch, load_rr_graph);
769+
VTR_ASSERT(delayless_switch != OPEN);
744770
build_intra_cluster_rr_graph(graph_type,
745771
grid,
746772
block_types,
747773
device_ctx.rr_graph,
748-
det_routing_arch->delayless_switch,
774+
delayless_switch,
749775
det_routing_arch->R_minW_nmos,
750776
det_routing_arch->R_minW_pmos,
751777
mutable_device_ctx.rr_graph_builder,
@@ -1512,6 +1538,26 @@ static void build_intra_cluster_rr_graph(const t_graph_type graph_type,
15121538
is_flat);
15131539
}
15141540

1541+
static int get_delayless_switch_id(t_det_routing_arch* det_routing_arch,
1542+
bool load_rr_graph) {
1543+
const auto& device_ctx = g_vpr_ctx.device();
1544+
int delayless_switch = OPEN;
1545+
if (load_rr_graph) {
1546+
const auto& rr_switches = device_ctx.rr_graph.rr_switch();
1547+
for (size_t switch_id = 0; switch_id < rr_switches.size(); switch_id++){
1548+
const auto& rr_switch = rr_switches[RRSwitchId(switch_id)];
1549+
if (rr_switch.name.find("delayless") != std::string::npos) {
1550+
delayless_switch = static_cast<int>(switch_id);
1551+
break;
1552+
}
1553+
}
1554+
} else {
1555+
delayless_switch = static_cast<int>(det_routing_arch->delayless_switch);
1556+
}
1557+
1558+
return delayless_switch;
1559+
}
1560+
15151561
void build_tile_rr_graph(RRGraphBuilder& rr_graph_builder,
15161562
const t_det_routing_arch& det_routing_arch,
15171563
t_physical_tile_type_ptr physical_tile,
@@ -2021,6 +2067,10 @@ static std::function<void(t_chan_width*)> alloc_and_load_rr_graph(RRGraphBuilder
20212067
/* If Fc gets clipped, this will be flagged to true */
20222068
*Fc_clipped = false;
20232069

2070+
/* This function is called to build the general routing graph resoruces. Thus,
2071+
the edges are not remapped yet.*/
2072+
bool switches_remapped = false;
2073+
20242074
int num_edges = 0;
20252075
/* Connection SINKS and SOURCES to their pins - Initializing IPINs/OPINs. */
20262076
for (int layer = 0; layer < grid.get_num_layers(); ++layer) {
@@ -2053,7 +2103,8 @@ static std::function<void(t_chan_width*)> alloc_and_load_rr_graph(RRGraphBuilder
20532103
j,
20542104
rr_edges_to_create,
20552105
delayless_switch,
2056-
physical_tile);
2106+
physical_tile,
2107+
switches_remapped);
20572108

20582109
//Create the actual SOURCE->OPIN, IPIN->SINK edges
20592110
uniquify_edges(rr_edges_to_create);
@@ -2270,7 +2321,8 @@ static void alloc_and_load_intra_cluster_rr_graph(RRGraphBuilder& rr_graph_build
22702321
j,
22712322
rr_edges_to_create,
22722323
delayless_switch,
2273-
physical_tile);
2324+
physical_tile,
2325+
load_rr_graph);
22742326

22752327
//Create the actual SOURCE->OPIN, IPIN->SINK edges
22762328
uniquify_edges(rr_edges_to_create);
@@ -2424,17 +2476,6 @@ static void connect_tile_src_sink_to_pins(RRGraphBuilder& rr_graph_builder,
24242476
continue;
24252477
}
24262478
auto pin_type = get_pin_type_from_pin_physical_num(physical_type_ptr, pin_num);
2427-
/*int sw_id = -1;
2428-
* if (is_primitive || pin_type == RECEIVER) {
2429-
* VTR_ASSERT(logical_block != nullptr);
2430-
* float primitive_comb_delay = get_pin_primitive_comb_delay(physical_type_ptr,
2431-
* logical_block,
2432-
* pin_num);
2433-
* sw_id = find_create_intra_cluster_sw_arch_idx(arch_sw_inf_map,
2434-
* primitive_comb_delay);
2435-
* } else {
2436-
* sw_id = delayless_switch;
2437-
* }*/
24382479
if (class_type == DRIVER) {
24392480
VTR_ASSERT(pin_type == DRIVER);
24402481
rr_edges_to_create.emplace_back(class_rr_node_id, pin_rr_node_id, delayless_switch, false);
@@ -2454,7 +2495,8 @@ static void connect_src_sink_to_pins(RRGraphBuilder& rr_graph_builder,
24542495
const int j,
24552496
t_rr_edge_info_set& rr_edges_to_create,
24562497
const int delayless_switch,
2457-
t_physical_tile_type_ptr physical_type_ptr) {
2498+
t_physical_tile_type_ptr physical_type_ptr,
2499+
bool switches_remapped) {
24582500
for (auto class_num : class_num_vec) {
24592501
const auto& pin_list = get_pin_list_from_class_physical_num(physical_type_ptr, class_num);
24602502
auto class_type = get_class_type_from_class_physical_num(physical_type_ptr, class_num);
@@ -2474,11 +2516,11 @@ static void connect_src_sink_to_pins(RRGraphBuilder& rr_graph_builder,
24742516
auto pin_type = get_pin_type_from_pin_physical_num(physical_type_ptr, pin_num);
24752517
if (class_type == DRIVER) {
24762518
VTR_ASSERT(pin_type == DRIVER);
2477-
rr_edges_to_create.emplace_back(class_rr_node_id, pin_rr_node_id, delayless_switch, false);
2519+
rr_edges_to_create.emplace_back(class_rr_node_id, pin_rr_node_id, delayless_switch, switches_remapped);
24782520
} else {
24792521
VTR_ASSERT(class_type == RECEIVER);
24802522
VTR_ASSERT(pin_type == RECEIVER);
2481-
rr_edges_to_create.emplace_back(pin_rr_node_id, class_rr_node_id, delayless_switch, false);
2523+
rr_edges_to_create.emplace_back(pin_rr_node_id, class_rr_node_id, delayless_switch, switches_remapped);
24822524
}
24832525
}
24842526
}
@@ -2682,6 +2724,8 @@ static void build_cluster_internal_edges(RRGraphBuilder& rr_graph_builder,
26822724
logical_block,
26832725
pb,
26842726
nodes_to_collapse,
2727+
R_minW_nmos,
2728+
R_minW_pmos,
26852729
rel_cap,
26862730
layer,
26872731
i,
@@ -2714,11 +2758,13 @@ static void add_pb_edges(RRGraphBuilder& rr_graph_builder,
27142758
t_logical_block_type_ptr logical_block,
27152759
const t_pb* pb,
27162760
const t_cluster_pin_chain& nodes_to_collapse,
2761+
float R_minW_nmos,
2762+
float R_minW_pmos,
27172763
int rel_cap,
27182764
int layer,
27192765
int i,
27202766
int j,
2721-
bool is_remapped) {
2767+
bool switches_remapped) {
27222768
auto pin_num_range = get_pb_pins(physical_type,
27232769
sub_tile,
27242770
logical_block,
@@ -2772,26 +2818,18 @@ static void add_pb_edges(RRGraphBuilder& rr_graph_builder,
27722818
pin_physical_num,
27732819
conn_pin_physical_num);
27742820

2775-
if (is_remapped) {
2776-
bool found = false;
2821+
if (switches_remapped) {
2822+
auto& all_sw_inf = g_vpr_ctx.mutable_device().all_sw_inf;
27772823
float delay = g_vpr_ctx.device().all_sw_inf.at(sw_idx).Tdel();
2778-
const auto& rr_switches = rr_graph_builder.rr_switch();
2779-
for (int sw_id = 0; sw_id < (int)rr_switches.size(); sw_id++) {
2780-
const auto& rr_switch = rr_switches[RRSwitchId(sw_id)];
2781-
if (rr_switch.intra_tile) {
2782-
if (rr_switch.Tdel == delay) {
2783-
sw_idx = sw_id;
2784-
found = true;
2785-
break;
2786-
}
2787-
}
2788-
}
2789-
// If the graph is loaded from a file, we expect that all sw types are already listed there since currently, we are not doing any further
2790-
// Optimization. If the optimization done when the rr graph file was generated is different from the current optimization, in the case that
2791-
// these optimizations create different RR switches, this VTR ASSERT can be removed.
2792-
VTR_ASSERT(found);
2824+
bool is_new_sw;
2825+
std::tie(is_new_sw, sw_idx) = find_create_intra_cluster_sw(rr_graph_builder,
2826+
all_sw_inf,
2827+
R_minW_nmos,
2828+
R_minW_pmos,
2829+
switches_remapped,
2830+
delay);
27932831
}
2794-
rr_edges_to_create.emplace_back(parent_pin_node_id, conn_pin_node_id, sw_idx, is_remapped);
2832+
rr_edges_to_create.emplace_back(parent_pin_node_id, conn_pin_node_id, sw_idx, switches_remapped);
27952833
}
27962834
}
27972835
}
@@ -2960,22 +2998,6 @@ static void add_chain_node_fan_in_edges(RRGraphBuilder& rr_graph_builder,
29602998
is_rr_sw_id,
29612999
delay);
29623000

2963-
if (!is_rr_sw_id && is_new_sw) {
2964-
// Currently we assume that if rr graph is read from a file, we shouldn't get into this block
2965-
VTR_ASSERT(!load_rr_graph);
2966-
// The internal edges are added after switch_fanin_remap is initialized; thus, if a new arch_sw is added,
2967-
// switch _fanin_remap should be updated.
2968-
t_rr_switch_inf rr_sw_inf = create_rr_switch_from_arch_switch(create_internal_arch_sw(delay),
2969-
R_minW_nmos,
2970-
R_minW_pmos);
2971-
auto rr_sw_id = rr_graph_builder.add_rr_switch(rr_sw_inf);
2972-
// If rr graph is loaded from a file, switch_fanin_remap is going to be empty
2973-
if (!load_rr_graph) {
2974-
auto& switch_fanin_remap = g_vpr_ctx.mutable_device().switch_fanin_remap;
2975-
switch_fanin_remap.push_back({{UNDEFINED, size_t(rr_sw_id)}});
2976-
}
2977-
}
2978-
29793001
rr_edges_to_create.emplace_back(src_pair.first, sink_rr_node_id, sw_id, is_rr_sw_id);
29803002
}
29813003
}
@@ -4934,6 +4956,18 @@ static std::pair<bool, int> find_create_intra_cluster_sw(RRGraphBuilder& rr_grap
49344956
// If this assumption proven to not be accurate, the implementation needs to be changed.
49354957
VTR_ASSERT(arch_sw.fixed_Tdel());
49364958

4959+
t_rr_switch_inf new_rr_switch_inf = create_rr_switch_from_arch_switch(create_internal_arch_sw(delay),
4960+
R_minW_nmos,
4961+
R_minW_pmos);
4962+
RRSwitchId rr_switch_id = rr_graph.add_rr_switch(new_rr_switch_inf);
4963+
4964+
/*If the switch found inside the cluster has not seen before and RR graph is not read from a file,
4965+
we need to add this switch to switch_fanin_remap data strcutre which is used later to remap switch IDs
4966+
from architecture ID to RR graph switch ID. The reason why we don't this when RR graph is read from a file
4967+
is that in that case, the switch IDs of edges are alreay RR graph switch IDs. */
4968+
auto& switch_fanin_remap = g_vpr_ctx.mutable_device().switch_fanin_remap;
4969+
switch_fanin_remap.push_back({{UNDEFINED, size_t(rr_switch_id)}});
4970+
49374971
return std::make_pair(true, new_key_num);
49384972
} else {
49394973
return std::make_pair(false, find_res->first);

0 commit comments

Comments
 (0)