diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index f0e8e6f4b16..87c3155c752 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -264,6 +264,18 @@ static void connect_tile_src_sink_to_pins(RRGraphBuilder& rr_graph_builder, const int delayless_switch, t_physical_tile_type_ptr physical_type_ptr); +/** + * Add the edges between IPIN to SINK and SOURCE to OPIN to rr_edges_to_create + * @param rr_graph_builder RR Graph Bulder object which contain the RR Graph storage + * @param class_num_vec Class physical numbers to add the edges connected to them + * @param layer The layer number of the block to add the SINK/SRC connections of it. + * @param i The x location of the block to add the SINK/SRC connections of it. + * @param j The y location of the block to add the SINK/SRC connections of it + * @param rr_edges_to_create An object which store all of the edges created in this function. + * @param delayless_switch Switch ID of the delayless switch. + * @param physical_type_ptr A pointer to the physical type of the block for which the edges are created. + * @param switches_remapped A flag to indicate whether edge switch IDs are remapped + */ static void connect_src_sink_to_pins(RRGraphBuilder& rr_graph_builder, const std::vector& class_num_vec, const int layer, @@ -271,7 +283,8 @@ static void connect_src_sink_to_pins(RRGraphBuilder& rr_graph_builder, const int j, t_rr_edge_info_set& rr_edges_to_create, const int delayless_switch, - t_physical_tile_type_ptr physical_type_ptr); + t_physical_tile_type_ptr physical_type_ptr, + bool switches_remapped); static void alloc_and_load_tile_rr_graph(RRGraphBuilder& rr_graph_builder, std::map& arch_sw_inf_map, @@ -374,11 +387,13 @@ static void add_pb_edges(RRGraphBuilder& rr_graph_builder, t_logical_block_type_ptr logical_block, const t_pb* pb, const t_cluster_pin_chain& nodes_to_collapse, + float R_minW_nmos, + float R_minW_pmos, int rel_cap, int layer, int i, int j, - bool is_remapped); + bool switches_remapped); /** * 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, bool is_flat, bool load_rr_graph); +/** + * Return the ID for delayess switch. If the RR graph is loaded from a file, then the assumption + * is that the returned ID should be a RR switch ID not architecture ID. + * @param det_routing_arch Contain the information from architecture file + * @param load_rr_graph Indicate whether the RR graph is loaded from a file + */ +static int get_delayless_switch_id(t_det_routing_arch* det_routing_arch, + bool load_rr_graph); + /******************* Subroutine definitions *******************************/ void create_rr_graph(const t_graph_type graph_type, @@ -741,11 +765,13 @@ void create_rr_graph(const t_graph_type graph_type, } if (is_flat) { + int delayless_switch = get_delayless_switch_id(det_routing_arch, load_rr_graph); + VTR_ASSERT(delayless_switch != OPEN); build_intra_cluster_rr_graph(graph_type, grid, block_types, device_ctx.rr_graph, - det_routing_arch->delayless_switch, + delayless_switch, det_routing_arch->R_minW_nmos, det_routing_arch->R_minW_pmos, mutable_device_ctx.rr_graph_builder, @@ -1512,6 +1538,26 @@ static void build_intra_cluster_rr_graph(const t_graph_type graph_type, is_flat); } +static int get_delayless_switch_id(t_det_routing_arch* det_routing_arch, + bool load_rr_graph) { + const auto& device_ctx = g_vpr_ctx.device(); + int delayless_switch = OPEN; + if (load_rr_graph) { + const auto& rr_switches = device_ctx.rr_graph.rr_switch(); + for (size_t switch_id = 0; switch_id < rr_switches.size(); switch_id++){ + const auto& rr_switch = rr_switches[RRSwitchId(switch_id)]; + if (rr_switch.name.find("delayless") != std::string::npos) { + delayless_switch = static_cast(switch_id); + break; + } + } + } else { + delayless_switch = static_cast(det_routing_arch->delayless_switch); + } + + return delayless_switch; +} + void build_tile_rr_graph(RRGraphBuilder& rr_graph_builder, const t_det_routing_arch& det_routing_arch, t_physical_tile_type_ptr physical_tile, @@ -2021,6 +2067,10 @@ static std::function alloc_and_load_rr_graph(RRGraphBuilder /* If Fc gets clipped, this will be flagged to true */ *Fc_clipped = false; + /* This function is called to build the general routing graph resoruces. Thus, + the edges are not remapped yet.*/ + bool switches_remapped = false; + int num_edges = 0; /* Connection SINKS and SOURCES to their pins - Initializing IPINs/OPINs. */ for (int layer = 0; layer < grid.get_num_layers(); ++layer) { @@ -2053,7 +2103,8 @@ static std::function alloc_and_load_rr_graph(RRGraphBuilder j, rr_edges_to_create, delayless_switch, - physical_tile); + physical_tile, + switches_remapped); //Create the actual SOURCE->OPIN, IPIN->SINK edges uniquify_edges(rr_edges_to_create); @@ -2270,7 +2321,8 @@ static void alloc_and_load_intra_cluster_rr_graph(RRGraphBuilder& rr_graph_build j, rr_edges_to_create, delayless_switch, - physical_tile); + physical_tile, + load_rr_graph); //Create the actual SOURCE->OPIN, IPIN->SINK edges uniquify_edges(rr_edges_to_create); @@ -2424,17 +2476,6 @@ static void connect_tile_src_sink_to_pins(RRGraphBuilder& rr_graph_builder, continue; } auto pin_type = get_pin_type_from_pin_physical_num(physical_type_ptr, pin_num); - /*int sw_id = -1; - * if (is_primitive || pin_type == RECEIVER) { - * VTR_ASSERT(logical_block != nullptr); - * float primitive_comb_delay = get_pin_primitive_comb_delay(physical_type_ptr, - * logical_block, - * pin_num); - * sw_id = find_create_intra_cluster_sw_arch_idx(arch_sw_inf_map, - * primitive_comb_delay); - * } else { - * sw_id = delayless_switch; - * }*/ if (class_type == DRIVER) { VTR_ASSERT(pin_type == DRIVER); 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, const int j, t_rr_edge_info_set& rr_edges_to_create, const int delayless_switch, - t_physical_tile_type_ptr physical_type_ptr) { + t_physical_tile_type_ptr physical_type_ptr, + bool switches_remapped) { for (auto class_num : class_num_vec) { const auto& pin_list = get_pin_list_from_class_physical_num(physical_type_ptr, class_num); 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, auto pin_type = get_pin_type_from_pin_physical_num(physical_type_ptr, pin_num); if (class_type == DRIVER) { VTR_ASSERT(pin_type == DRIVER); - rr_edges_to_create.emplace_back(class_rr_node_id, pin_rr_node_id, delayless_switch, false); + rr_edges_to_create.emplace_back(class_rr_node_id, pin_rr_node_id, delayless_switch, switches_remapped); } else { VTR_ASSERT(class_type == RECEIVER); VTR_ASSERT(pin_type == RECEIVER); - rr_edges_to_create.emplace_back(pin_rr_node_id, class_rr_node_id, delayless_switch, false); + rr_edges_to_create.emplace_back(pin_rr_node_id, class_rr_node_id, delayless_switch, switches_remapped); } } } @@ -2682,6 +2724,8 @@ static void build_cluster_internal_edges(RRGraphBuilder& rr_graph_builder, logical_block, pb, nodes_to_collapse, + R_minW_nmos, + R_minW_pmos, rel_cap, layer, i, @@ -2714,11 +2758,13 @@ static void add_pb_edges(RRGraphBuilder& rr_graph_builder, t_logical_block_type_ptr logical_block, const t_pb* pb, const t_cluster_pin_chain& nodes_to_collapse, + float R_minW_nmos, + float R_minW_pmos, int rel_cap, int layer, int i, int j, - bool is_remapped) { + bool switches_remapped) { auto pin_num_range = get_pb_pins(physical_type, sub_tile, logical_block, @@ -2772,26 +2818,18 @@ static void add_pb_edges(RRGraphBuilder& rr_graph_builder, pin_physical_num, conn_pin_physical_num); - if (is_remapped) { - bool found = false; + if (switches_remapped) { + auto& all_sw_inf = g_vpr_ctx.mutable_device().all_sw_inf; float delay = g_vpr_ctx.device().all_sw_inf.at(sw_idx).Tdel(); - const auto& rr_switches = rr_graph_builder.rr_switch(); - for (int sw_id = 0; sw_id < (int)rr_switches.size(); sw_id++) { - const auto& rr_switch = rr_switches[RRSwitchId(sw_id)]; - if (rr_switch.intra_tile) { - if (rr_switch.Tdel == delay) { - sw_idx = sw_id; - found = true; - break; - } - } - } - // 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 - // Optimization. If the optimization done when the rr graph file was generated is different from the current optimization, in the case that - // these optimizations create different RR switches, this VTR ASSERT can be removed. - VTR_ASSERT(found); + bool is_new_sw; + std::tie(is_new_sw, sw_idx) = find_create_intra_cluster_sw(rr_graph_builder, + all_sw_inf, + R_minW_nmos, + R_minW_pmos, + switches_remapped, + delay); } - rr_edges_to_create.emplace_back(parent_pin_node_id, conn_pin_node_id, sw_idx, is_remapped); + rr_edges_to_create.emplace_back(parent_pin_node_id, conn_pin_node_id, sw_idx, switches_remapped); } } } @@ -2960,22 +2998,6 @@ static void add_chain_node_fan_in_edges(RRGraphBuilder& rr_graph_builder, is_rr_sw_id, delay); - if (!is_rr_sw_id && is_new_sw) { - // Currently we assume that if rr graph is read from a file, we shouldn't get into this block - VTR_ASSERT(!load_rr_graph); - // The internal edges are added after switch_fanin_remap is initialized; thus, if a new arch_sw is added, - // switch _fanin_remap should be updated. - t_rr_switch_inf rr_sw_inf = create_rr_switch_from_arch_switch(create_internal_arch_sw(delay), - R_minW_nmos, - R_minW_pmos); - auto rr_sw_id = rr_graph_builder.add_rr_switch(rr_sw_inf); - // If rr graph is loaded from a file, switch_fanin_remap is going to be empty - if (!load_rr_graph) { - auto& switch_fanin_remap = g_vpr_ctx.mutable_device().switch_fanin_remap; - switch_fanin_remap.push_back({{UNDEFINED, size_t(rr_sw_id)}}); - } - } - rr_edges_to_create.emplace_back(src_pair.first, sink_rr_node_id, sw_id, is_rr_sw_id); } } @@ -4934,6 +4956,18 @@ static std::pair find_create_intra_cluster_sw(RRGraphBuilder& rr_grap // If this assumption proven to not be accurate, the implementation needs to be changed. VTR_ASSERT(arch_sw.fixed_Tdel()); + t_rr_switch_inf new_rr_switch_inf = create_rr_switch_from_arch_switch(create_internal_arch_sw(delay), + R_minW_nmos, + R_minW_pmos); + RRSwitchId rr_switch_id = rr_graph.add_rr_switch(new_rr_switch_inf); + + /*If the switch found inside the cluster has not seen before and RR graph is not read from a file, + we need to add this switch to switch_fanin_remap data strcutre which is used later to remap switch IDs + from architecture ID to RR graph switch ID. The reason why we don't this when RR graph is read from a file + is that in that case, the switch IDs of edges are alreay RR graph switch IDs. */ + auto& switch_fanin_remap = g_vpr_ctx.mutable_device().switch_fanin_remap; + switch_fanin_remap.push_back({{UNDEFINED, size_t(rr_switch_id)}}); + return std::make_pair(true, new_key_num); } else { return std::make_pair(false, find_res->first);