From 189f991ea78c0b8d4fda7c18d4e95d218813debd Mon Sep 17 00:00:00 2001 From: Duck Deux Date: Tue, 15 Oct 2024 12:07:03 -0700 Subject: [PATCH] Enable bitstream generation with flat routing --- openfpga/src/annotation/annotate_rr_graph.cpp | 6 + .../annotation/openfpga_annotate_routing.cpp | 120 +++--------------- .../annotation/openfpga_annotate_routing.h | 1 - .../src/base/openfpga_link_arch_template.h | 1 - openfpga/src/mux_lib/mux_library_builder.cpp | 9 +- 5 files changed, 30 insertions(+), 107 deletions(-) diff --git a/openfpga/src/annotation/annotate_rr_graph.cpp b/openfpga/src/annotation/annotate_rr_graph.cpp index 5f325d0a73..79b0db6330 100644 --- a/openfpga/src/annotation/annotate_rr_graph.cpp +++ b/openfpga/src/annotation/annotate_rr_graph.cpp @@ -554,6 +554,12 @@ static void annotate_rr_switch_circuit_models( rr_switch_id++) { std::string switch_name( vpr_device_ctx.rr_graph.rr_switch()[RRSwitchId(rr_switch_id)].name); + + /* Skip flat router-generated internal switches */ + if (switch_name.rfind(VPR_INTERNAL_SWITCH_NAME, 0) == 0) { + continue; + } + /* Skip the delayless switch, which is only used by the edges between * - SOURCE and OPIN * - IPIN and SINK diff --git a/openfpga/src/annotation/openfpga_annotate_routing.cpp b/openfpga/src/annotation/openfpga_annotate_routing.cpp index 48c8d732f2..cc96513578 100644 --- a/openfpga/src/annotation/openfpga_annotate_routing.cpp +++ b/openfpga/src/annotation/openfpga_annotate_routing.cpp @@ -5,7 +5,7 @@ #include "openfpga_annotate_routing.h" #include "annotate_routing.h" -#include "old_traceback.h" +#include "route_utils.h" #include "vtr_assert.h" #include "vtr_log.h" #include "vtr_time.h" @@ -123,80 +123,6 @@ void annotate_vpr_rr_node_nets(const DeviceContext& device_ctx, VTR_LOG("Loaded node-to-net mapping\n"); } -/******************************************************************** - * This function will find a previous node for a given rr_node - * from the routing traces - * - * It requires a candidate which provided by upstream functions - * Try to validate a candidate by searching it from driving node list - * If not validated, try to find a right one in the routing traces - *******************************************************************/ -static RRNodeId find_previous_node_from_routing_traces( - const RRGraphView& rr_graph, t_trace* routing_trace_head, - const RRNodeId& prev_node_candidate, const RRNodeId& cur_rr_node) { - RRNodeId prev_node = prev_node_candidate; - - /* For a valid prev_node, ensure prev node is one of the driving nodes for - * this rr_node! */ - if (prev_node) { - /* Try to spot the previous node in the incoming node list of this rr_node - */ - bool valid_prev_node = false; - for (const RREdgeId& in_edge : rr_graph.node_in_edges(cur_rr_node)) { - if (prev_node == rr_graph.edge_src_node(in_edge)) { - valid_prev_node = true; - break; - } - } - - /* Early exit if we already validate the node */ - if (true == valid_prev_node) { - return prev_node; - } - - /* If we cannot find one, it could be possible that this rr_node branches - * from an earlier point in the routing tree - * - * +----- ... --->prev_node - * | - * src_node->+ - * | - * +-----+ rr_node - * - * Our job now is to start from the head of the traces and find the - * prev_node that drives this rr_node - * - * This search will find the first-fit and finish. - * This is reasonable because if there is a second-fit, it should be a - * longer path which should be considered in routing optimization - */ - if (false == valid_prev_node) { - t_trace* tptr = routing_trace_head; - while (tptr != nullptr) { - RRNodeId cand_prev_node = RRNodeId(tptr->index); - bool is_good_cand = false; - for (const RREdgeId& in_edge : rr_graph.node_in_edges(cur_rr_node)) { - if (cand_prev_node == rr_graph.edge_src_node(in_edge)) { - is_good_cand = true; - break; - } - } - - if (true == is_good_cand) { - /* Update prev_node */ - prev_node = cand_prev_node; - break; - } - - /* Move on to the next */ - tptr = tptr->next; - } - } - } - - return prev_node; -} - /******************************************************************** * Create a mapping between each rr_node and its previous node * based on VPR routing results @@ -204,49 +130,35 @@ static RRNodeId find_previous_node_from_routing_traces( *******************************************************************/ void annotate_rr_node_previous_nodes( const DeviceContext& device_ctx, const ClusteringContext& clustering_ctx, - const RoutingContext& routing_ctx, VprRoutingAnnotation& vpr_routing_annotation, const bool& verbose) { size_t counter = 0; VTR_LOG("Annotating previous nodes for rr_node..."); VTR_LOGV(verbose, "\n"); - for (auto net_id : clustering_ctx.clb_nlist.nets()) { + auto& netlist = clustering_ctx.clb_nlist; + + for (auto net_id : netlist.nets()) { /* Ignore nets that are not routed */ - if (true == clustering_ctx.clb_nlist.net_is_ignored(net_id)) { + if (true == netlist.net_is_ignored(net_id)) { continue; } /* Ignore used in local cluster only, reserved one CLB pin */ - if (false == clustering_ctx.clb_nlist.net_sinks(net_id).size()) { + if (false == netlist.net_sinks(net_id).size()) { continue; } - /* Cache Previous nodes */ - RRNodeId prev_node = RRNodeId::INVALID(); - - t_trace* tptr = TracebackCompat::traceback_from_route_tree( - routing_ctx.route_trees[net_id].value()); - t_trace* head = tptr; - while (tptr != nullptr) { - RRNodeId rr_node = RRNodeId(tptr->index); - - /* Find the right previous node */ - prev_node = find_previous_node_from_routing_traces( - device_ctx.rr_graph, head, prev_node, rr_node); - - /* Only update mapped nodes */ - if (prev_node) { - vpr_routing_annotation.set_rr_node_prev_node(device_ctx.rr_graph, - rr_node, prev_node); - counter++; - } - - /* Update prev_node */ - prev_node = rr_node; + auto& tree = get_route_tree_from_cluster_net_id(net_id); + if (!tree) { + continue; + } - /* Move on to the next */ - tptr = tptr->next; + for (auto& rt_node : tree->all_nodes()) { + RRNodeId rr_node = rt_node.inode; + auto parent = rt_node.parent(); + vpr_routing_annotation.set_rr_node_prev_node( + device_ctx.rr_graph, rr_node, + parent ? parent->inode : RRNodeId::INVALID()); } - free_traceback(head); } VTR_LOG("Done with %d nodes mapping\n", counter); diff --git a/openfpga/src/annotation/openfpga_annotate_routing.h b/openfpga/src/annotation/openfpga_annotate_routing.h index b8f5a83e7b..2c81a82d50 100644 --- a/openfpga/src/annotation/openfpga_annotate_routing.h +++ b/openfpga/src/annotation/openfpga_annotate_routing.h @@ -28,7 +28,6 @@ void annotate_vpr_rr_node_nets(const DeviceContext& device_ctx, void annotate_rr_node_previous_nodes( const DeviceContext& device_ctx, const ClusteringContext& clustering_ctx, - const RoutingContext& routing_ctx, VprRoutingAnnotation& vpr_routing_annotation, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_link_arch_template.h b/openfpga/src/base/openfpga_link_arch_template.h index eb289c471d..52ebb78c43 100644 --- a/openfpga/src/base/openfpga_link_arch_template.h +++ b/openfpga/src/base/openfpga_link_arch_template.h @@ -94,7 +94,6 @@ int link_arch_template(T& openfpga_ctx, const Command& cmd, cmd_context.option_enable(cmd, opt_verbose)); annotate_rr_node_previous_nodes(g_vpr_ctx.device(), g_vpr_ctx.clustering(), - g_vpr_ctx.routing(), openfpga_ctx.mutable_vpr_routing_annotation(), cmd_context.option_enable(cmd, opt_verbose)); diff --git a/openfpga/src/mux_lib/mux_library_builder.cpp b/openfpga/src/mux_lib/mux_library_builder.cpp index 6b5b7bc77d..a21c67f7d8 100644 --- a/openfpga/src/mux_lib/mux_library_builder.cpp +++ b/openfpga/src/mux_lib/mux_library_builder.cpp @@ -52,11 +52,18 @@ static void build_routing_arch_mux_library( VTR_ASSERT(1 == driver_switches.size()); const CircuitModelId& rr_switch_circuit_model = vpr_device_annotation.rr_switch_circuit_model(driver_switches[0]); + + /* Skip flat router-generated internal switches (not relevant) */ + auto switch_name = rr_graph.rr_switch_inf(driver_switches[0]).name; + if (switch_name.rfind(VPR_INTERNAL_SWITCH_NAME, 0) == 0) { + continue; + } + /* we should select a circuit model for the routing resource switch */ if (CircuitModelId::INVALID() == rr_switch_circuit_model) { VTR_LOG_ERROR( "Unable to find the circuit model for rr_switch '%s'!\n", - rr_graph.rr_switch_inf(driver_switches[0]).name.c_str()); + switch_name.c_str()); VTR_LOG("Node type: %s\n", rr_graph.node_type_string(node)); VTR_LOG("Node coordinate: %s\n", rr_graph.node_coordinate_to_string(node).c_str());