[core] support intermediate driver in clock routing

This commit is contained in:
tangxifan 2024-09-20 19:22:39 -07:00
parent e8957b6fd8
commit f87e095558
2 changed files with 45 additions and 11 deletions

View File

@ -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<int> des_coord;
vtr::Point<int> 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);

View File

@ -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",