From f87e095558996ce51f7972c89059b9a522d32ac7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 20 Sep 2024 19:22:39 -0700 Subject: [PATCH] [core] support intermediate driver in clock routing --- .../src/annotation/append_clock_rr_graph.cpp | 12 +---- .../src/annotation/route_clock_rr_graph.cpp | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/openfpga/src/annotation/append_clock_rr_graph.cpp b/openfpga/src/annotation/append_clock_rr_graph.cpp index cc9dbe60d..6fe98875c 100644 --- a/openfpga/src/annotation/append_clock_rr_graph.cpp +++ b/openfpga/src/annotation/append_clock_rr_graph.cpp @@ -761,24 +761,14 @@ static int add_rr_graph_opin2clk_intermediate_edges( /* Get the rr node of destination spine */ Direction des_spine_direction = clk_ntwk.spine_direction(ispine); ClockLevelId des_spine_level = clk_ntwk.spine_level(ispine); - vtr::Point des_coord; + vtr::Point des_coord(coord.x(), coord.y()); /* des node depends on the type of routing track and direction. But it should be a starting point at the current SB[x][y] */ if (des_spine_direction == Direction::INC && clk_ntwk.spine_track_type(ispine) == CHANX) { des_coord.set_x(coord.x() + 1); - des_coord.set_y(coord.y()); - } - if (des_spine_direction == Direction::DEC && clk_ntwk.spine_track_type(ispine) == CHANX) { - des_coord.set_x(coord.x()); - des_coord.set_y(coord.y()); } if (des_spine_direction == Direction::INC && clk_ntwk.spine_track_type(ispine) == CHANY) { - des_coord.set_x(coord.x()); des_coord.set_y(coord.y() + 1); } - if (des_spine_direction == Direction::DEC && clk_ntwk.spine_track_type(ispine) == CHANY) { - des_coord.set_x(coord.x()); - des_coord.set_y(coord.y()); - } RRNodeId des_node = clk_rr_lookup.find_node( des_coord.x(), des_coord.y(), clk_tree, des_spine_level, ipin, des_spine_direction, verbose); diff --git a/openfpga/src/annotation/route_clock_rr_graph.cpp b/openfpga/src/annotation/route_clock_rr_graph.cpp index 79cad9ecb..2ff70bfc5 100644 --- a/openfpga/src/annotation/route_clock_rr_graph.cpp +++ b/openfpga/src/annotation/route_clock_rr_graph.cpp @@ -449,6 +449,50 @@ static int rec_expand_and_route_clock_spine( des_spine_direction, verbose); VTR_ASSERT(rr_graph.valid_node(src_node)); VTR_ASSERT(rr_graph.valid_node(des_node)); + + /* Internal drivers may appear at the intermediate. Check if there are + * any defined and related rr_node found as incoming edges. If the + * global net is mapped to the internal driver, use it as the previous + * node */ + size_t use_int_driver = 0; + if (!clk_ntwk.spine_intermediate_drivers(curr_spine, des_coord) + .empty() && + tree2clk_pin_map.find(curr_pin) != tree2clk_pin_map.end()) { + for (RREdgeId cand_edge : rr_graph.node_in_edges(des_node)) { + RRNodeId opin_node = rr_graph.edge_src_node(cand_edge); + if (OPIN != rr_graph.node_type(opin_node)) { + continue; + } + if (rr_node_gnets[opin_node] != tree2clk_pin_map.at(curr_pin)) { + continue; + } + /* This is the opin node we need, use it as the internal driver */ + vpr_routing_annotation.set_rr_node_prev_node(rr_graph, des_node, + opin_node); + vpr_routing_annotation.set_rr_node_net(opin_node, + tree2clk_pin_map.at(curr_pin)); + vpr_routing_annotation.set_rr_node_net(des_node, + tree2clk_pin_map.at(curr_pin)); + use_int_driver++; + VTR_LOGV(verbose, + "Routed intermediate point of spine '%s' at " + "(%lu, %lu) using internal driver\n", + clk_ntwk.spine_name(curr_spine).c_str(), des_coord.x(), + des_coord.y()); + } + } + if (use_int_driver > 1) { + VTR_LOG_ERROR( + "Found %lu internal drivers for the intermediate point (%lu, %lu) for " + "spine '%s'!\n Expect only 1!\n", + use_int_driver, des_coord.x(), des_coord.y(), + clk_ntwk.spine_name(curr_spine).c_str()); + return CMD_EXEC_FATAL_ERROR; + } + if (use_int_driver == 1) { + continue; /* Used internal driver, early pass. */ + } + VTR_LOGV(verbose, "Routed backbone of spine '%s' from (x=%lu, y=%lu) to (x=%lu, " "y=%lu)...\n",