From 29450f34726c0dc5e8593443ab6357e8fe3f7bd4 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 12 Mar 2020 20:42:41 -0600 Subject: [PATCH] debugging multi-source lb router --- openfpga/src/repack/lb_router.cpp | 104 ++++++++++-------- openfpga/src/repack/lb_router.h | 4 +- .../test_script/and_latch_k6_frac.openfpga | 4 +- 3 files changed, 61 insertions(+), 51 deletions(-) diff --git a/openfpga/src/repack/lb_router.cpp b/openfpga/src/repack/lb_router.cpp index 7cc6d080e..70b8e67b0 100644 --- a/openfpga/src/repack/lb_router.cpp +++ b/openfpga/src/repack/lb_router.cpp @@ -209,7 +209,7 @@ bool LbRouter::try_route_net(const LbRRGraph& lb_rr_graph, const NetId& net_idx, t_expansion_node& exp_node, std::unordered_map& mode_map, - const int& verbosity) { + const bool& verbosity) { std::vector sink_routed(lb_net_sinks_[net_idx].size(), false); @@ -226,18 +226,15 @@ bool LbRouter::try_route_net(const LbRRGraph& lb_rr_graph, /* Route each sink of net */ for (size_t isink = 0; isink < lb_net_sinks_[net_idx].size(); ++isink) { - /* Check if last sink failed in routing - * If failed, the routing is not possible for this net - */ - if (0 < isink) { - if (false == sink_routed[isink - 1]) { - break; - } + + /* Skip routed nets */ + if (true == sink_routed[isink]) { + continue; } pq_.clear(); - /* Get lowest cost next node, repeat until a path is found or if it is impossible to route */ + /* Get lowest cost next node, repeat until a path is found or if it is impossible to route */ expand_rt(net_idx, net_idx, isrc); /* If we managed to expand the nodes to the sink, routing for this sink is done. @@ -246,10 +243,17 @@ bool LbRouter::try_route_net(const LbRRGraph& lb_rr_graph, */ sink_routed[isink] = !try_expand_nodes(atom_nlist, lb_rr_graph, net_idx, exp_node, isrc, isink, mode_status_.expand_all_modes, verbosity); + if (true == sink_routed[isink]) { + VTR_LOGV(verbosity, + "Succeed to expand routing tree from source pin '%s' to sink pin '%s'!\n", + lb_rr_graph.node_pb_graph_pin(lb_net_sources_[net_idx][isrc])->to_string().c_str(), + lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[net_idx][isink])->to_string().c_str()); + } + if (false == sink_routed[isink] && false == mode_status_.expand_all_modes) { mode_status_.try_expand_all_modes = true; mode_status_.expand_all_modes = true; - break; + continue; } if (exp_node.node_index == lb_net_sinks_[net_idx][isink]) { @@ -258,14 +262,25 @@ bool LbRouter::try_route_net(const LbRRGraph& lb_rr_graph, } if (false == sink_routed[isink]) { - VTR_LOG("Routing was impossible!\n"); + VTR_LOGV(verbosity, + "Routing was impossible from source pin '%s' to sink pin '%s'!\n", + lb_rr_graph.node_pb_graph_pin(lb_net_sources_[net_idx][isrc])->to_string().c_str(), + lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[net_idx][isink])->to_string().c_str()); } else if (mode_status_.expand_all_modes) { sink_routed[isink] = !route_has_conflict(lb_rr_graph, lb_net_rt_trees_[net_idx][isrc]); if (false == sink_routed[isink]) { - VTR_LOG("Routing was impossible due to modes!\n"); + VTR_LOGV(verbosity, + "Routing was impossible due to modes!\n"); } } + if (true == sink_routed[isink]) { + VTR_LOGV(verbosity, + "Routing succeeded from source pin '%s' to sink pin '%s'!\n", + lb_rr_graph.node_pb_graph_pin(lb_net_sources_[net_idx][isrc])->to_string().c_str(), + lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[net_idx][isink])->to_string().c_str()); + } + explore_id_index_++; if (explore_id_index_ > 2000000000) { /* overflow protection */ @@ -275,39 +290,40 @@ bool LbRouter::try_route_net(const LbRRGraph& lb_rr_graph, explore_id_index_ = 1; } } + + /* If routing succeed so far, we will try to save(commit) results + * to route tree. + * During this process, we will check if there is any + * nodes using different modes under the same pb_type + * If so, we have conflicts and routing is considered to be failure + */ + if (true == sink_routed[isink]) { + commit_remove_rt(lb_rr_graph, lb_net_rt_trees_[net_idx][isrc], RT_COMMIT, mode_map); + if (true == mode_status_.is_mode_conflict) { + sink_routed[isink] = false; + } + } } } /* Check the routing status for all the sinks */ bool route_succeed = true; - for (const bool& sink_status : sink_routed) { - if (false == sink_status) { + for (size_t isink = 0; isink < sink_routed.size(); ++isink) { + if (false == sink_routed[isink]) { route_succeed = false; + VTR_LOGV(verbosity, + "Routing failed for sink pin '%s'!\n", + lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[net_idx][isink])->to_string().c_str()); break; } } - /* If routing succeed so far, we will try to save(commit) results - * to route tree. - * During this process, we will check if there is any - * nodes using different modes under the same pb_type - * If so, we have conflicts and routing is considered to be failure - */ - if (true == route_succeed) { - for (size_t isrc = 1; isrc < lb_net_sources_[net_idx].size(); ++isrc) { - commit_remove_rt(lb_rr_graph, lb_net_rt_trees_[net_idx][isrc], RT_COMMIT, mode_map); - if (true == mode_status_.is_mode_conflict) { - route_succeed = false; - } - } - } - return route_succeed; } bool LbRouter::try_route(const LbRRGraph& lb_rr_graph, const AtomNetlist& atom_nlist, - const int& verbosity) { + const bool& verbosity) { /* Validate if the rr_graph is the one we used to initialize the router */ VTR_ASSERT(true == matched_lb_rr_graph(lb_rr_graph)); @@ -351,27 +367,21 @@ bool LbRouter::try_route(const LbRRGraph& lb_rr_graph, is_routed_ = is_route_success(lb_rr_graph); } else { --inet; - VTR_LOGV(verbosity < 3, - "Net %lu '%s' is impossible to route within proposed %s cluster\n", - inet, - atom_nlist.net_name(lb_net_atom_net_ids_[NetId(inet)]).c_str(), - lb_type_->name); - VTR_LOGV(verbosity < 3, - "\tNet source pin:\n"); + VTR_LOG("Net %lu '%s' is impossible to route within proposed %s cluster\n", + inet, + atom_nlist.net_name(lb_net_atom_net_ids_[NetId(inet)]).c_str(), + lb_type_->name); + VTR_LOG("\tNet source pin:\n"); for (size_t isrc = 0; isrc < lb_net_sources_[NetId(inet)].size(); ++isrc) { - VTR_LOGV(verbosity < 3, - "\t\t%s\n", - lb_rr_graph.node_pb_graph_pin(lb_net_sources_[NetId(inet)][isrc])->to_string().c_str()); + VTR_LOG("\t\t%s\n", + lb_rr_graph.node_pb_graph_pin(lb_net_sources_[NetId(inet)][isrc])->to_string().c_str()); } - VTR_LOGV(verbosity < 3, - "\tNet sink pins:\n"); + VTR_LOG("\tNet sink pins:\n"); for (size_t isink = 0; isink < lb_net_sinks_[NetId(inet)].size(); ++isink) { - VTR_LOGV(verbosity < 3, - "\t\t%s\n", - lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[NetId(inet)][isink])->to_string().c_str()); + VTR_LOG("\t\t%s\n", + lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[NetId(inet)][isink])->to_string().c_str()); } - VTR_LOGV(verbosity < 3, - "Please check your architecture XML to see if it is routable\n"); + VTR_LOG("Please check your architecture XML to see if it is routable\n"); is_routed_ = false; } diff --git a/openfpga/src/repack/lb_router.h b/openfpga/src/repack/lb_router.h index dcd0dc610..d865c75b9 100644 --- a/openfpga/src/repack/lb_router.h +++ b/openfpga/src/repack/lb_router.h @@ -256,7 +256,7 @@ class LbRouter { */ bool try_route(const LbRRGraph& lb_rr_graph, const AtomNetlist& atom_nlist, - const int& verbosity); + const bool& verbosity); private : /* Private accessors */ /** @@ -328,7 +328,7 @@ class LbRouter { const NetId& net_idx, t_expansion_node& exp_node, std::unordered_map& mode_map, - const int& verbosity); + const bool& verbosity); private : /* Private validators */ /** diff --git a/openfpga/test_script/and_latch_k6_frac.openfpga b/openfpga/test_script/and_latch_k6_frac.openfpga index 210bdcf28..b41ac4450 100644 --- a/openfpga/test_script/and_latch_k6_frac.openfpga +++ b/openfpga/test_script/and_latch_k6_frac.openfpga @@ -27,7 +27,7 @@ build_fabric --compress_routing --duplicate_grid_pin #--verbose # Repack the netlist to physical pbs # This must be done before bitstream generator and testbench generation # Strongly recommend it is done after all the fix-up have been applied -repack #--verbose +repack --verbose # Build the bitstream # - Output the fabric-independent bitstream to a file @@ -46,7 +46,7 @@ write_fabric_verilog --file /var/tmp/xtang/openfpga_test_src/SRC --explicit_port # - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA # - Enable pre-configured top-level testbench which is a fast verification skipping programming phase # - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts -write_verilog_testbench --file /var/tmp/xtang/openfpga_test_src/SRC --reference_benchmark_file_path /var/tmp/xtang/and.v --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini /var/tmp/xtang/openfpga_test_src/simulation_deck.ini +write_verilog_testbench --file /var/tmp/xtang/openfpga_test_src/SRC --reference_benchmark_file_path /var/tmp/xtang/and_latch.v --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini /var/tmp/xtang/openfpga_test_src/simulation_deck.ini # Write the SDC files for PnR backend # - Turn on every options here