[core] fixed a bug where the switch point coordinate of src spine required adjustment

This commit is contained in:
tangxifan 2024-08-15 12:41:09 -07:00
parent 586dd1a510
commit 00fd21704c
2 changed files with 41 additions and 13 deletions

View File

@ -109,6 +109,38 @@ static int route_clock_spine_switch_point(
Direction des_spine_direction = clk_ntwk.spine_direction(des_spine); Direction des_spine_direction = clk_ntwk.spine_direction(des_spine);
ClockLevelId src_spine_level = clk_ntwk.spine_level(ispine); ClockLevelId src_spine_level = clk_ntwk.spine_level(ispine);
ClockLevelId des_spine_level = clk_ntwk.spine_level(des_spine); ClockLevelId des_spine_level = clk_ntwk.spine_level(des_spine);
/* Special for DEC_DIR CHANX and CHANY, there should be a offset on the source coordinate
* Note that in the following condition, the switching point occurs in switch block (x, y)
* INC CHANY (x, y + 1)
* ^
* |
* INC CHANX (x, y) --->+<---- DEC CHANX (x + 1, y)
* |
* v
* DEC CHANY (x, y)
*
* Note that in the following condition, the switching point occurs in switch block (x, y)
* DEC CHANY (x, y + 1)
* |
* v
* DEC CHANX (x, y) <---+----> INC CHANX (x + 1, y)
* ^
* |
* INC CHANY (x, y)
* From the user point of view, the switching point should only occur in a switch block
* So the coordinate of a switch block should be provided as the coordinate of switching point
* However, the src node and des node may not follow the switch block coordinate!
* In short, the src coordinate requires an adjustment only when
* - The src is an CHANX in DEC
* - The src is an CHANY in DEC
* No adjustment is required for des node as it always comes from the starting point of the des spine
*/
if (clk_ntwk.spine_track_type(ispine) == CHANX && src_spine_direction == Direction::DEC) {
src_coord.set_x(src_coord.x() + 1);
}
if (clk_ntwk.spine_track_type(ispine) == CHANY && src_spine_direction == Direction::DEC) {
src_coord.set_y(src_coord.y() + 1);
}
RRNodeId src_node = clk_rr_lookup.find_node(src_coord.x(), src_coord.y(), RRNodeId src_node = clk_rr_lookup.find_node(src_coord.x(), src_coord.y(),
clk_tree, src_spine_level, ipin, clk_tree, src_spine_level, ipin,
src_spine_direction, verbose); src_spine_direction, verbose);
@ -160,10 +192,10 @@ static int route_clock_spine_switch_point(
return CMD_EXEC_SUCCESS; /* Used internal driver, early pass */ return CMD_EXEC_SUCCESS; /* Used internal driver, early pass */
} }
VTR_LOGV(verbose, VTR_LOGV(verbose,
"Routed switch points of spine '%s' from (x=%lu, y=%lu) to spine " "Routed switch points of spine '%s' (node '%lu') from (x=%lu, y=%lu) to spine "
"'%s' at (x=%lu, y=%lu)\n", "'%s' (node '%lu') at (x=%lu, y=%lu)\n",
clk_ntwk.spine_name(ispine).c_str(), src_coord.x(), src_coord.y(), clk_ntwk.spine_name(ispine).c_str(), size_t(src_node), src_coord.x(), src_coord.y(),
clk_ntwk.spine_name(des_spine).c_str(), des_coord.x(), clk_ntwk.spine_name(des_spine).c_str(), size_t(des_node), des_coord.x(),
des_coord.y()); des_coord.y());
vpr_routing_annotation.set_rr_node_prev_node(rr_graph, des_node, src_node); vpr_routing_annotation.set_rr_node_prev_node(rr_graph, des_node, src_node);
/* It could happen that there is no net mapped some clock pin, skip the /* It could happen that there is no net mapped some clock pin, skip the
@ -314,11 +346,8 @@ static int rec_expand_and_route_clock_spine(
if (CMD_EXEC_SUCCESS != status) { if (CMD_EXEC_SUCCESS != status) {
return CMD_EXEC_FATAL_ERROR; return CMD_EXEC_FATAL_ERROR;
} }
if (curr_tap_usage) {
curr_spine_usage = true;
}
/* If no taps are routed, this spine is not used. Early exit */ /* If no taps are routed, this spine is not used. Early exit */
if (!curr_tap_usage && clk_ntwk.is_last_level(curr_spine)) { if (disable_unused_spines && !curr_tap_usage && clk_ntwk.is_last_level(curr_spine)) {
spine_usage = false; spine_usage = false;
VTR_LOGV(verbose, VTR_LOGV(verbose,
"Disable last-level spine '%s' as " "Disable last-level spine '%s' as "
@ -386,9 +415,6 @@ static int rec_expand_and_route_clock_spine(
/* If there are any stop is used, mark this spine is used. This is to avoid /* If there are any stop is used, mark this spine is used. This is to avoid
* that a spine is marked unused when only its 1st stop is actually used. * that a spine is marked unused when only its 1st stop is actually used.
* The skip condition may cause this. */ * The skip condition may cause this. */
if (curr_stop_usage) {
curr_spine_usage = true;
}
/* Skip the first stop */ /* Skip the first stop */
if (icoord == spine_coords.size() - 1) { if (icoord == spine_coords.size() - 1) {
continue; continue;

View File

@ -60,11 +60,14 @@ static void build_switch_block_mux_bitstream(
* - There is a net mapped to cur_rr_node: we find the path id * - There is a net mapped to cur_rr_node: we find the path id
*/ */
int path_id = DEFAULT_PATH_ID; int path_id = DEFAULT_PATH_ID;
if (ClusterNetId::INVALID() != output_net) { VTR_LOGV(verbose, "Prev node '%lu' for src_node '%lu'\n", size_t(routing_annotation.rr_node_prev_node(cur_rr_node)), size_t(cur_rr_node));
AtomNetId output_atom_net = atom_ctx.lookup.atom_net(output_net);
if (true == atom_ctx.nlist.valid_net_id(output_atom_net)) {
/* We must have a valid previous node that is supposed to drive the source /* We must have a valid previous node that is supposed to drive the source
* node! */ * node! */
VTR_ASSERT(routing_annotation.rr_node_prev_node(cur_rr_node)); VTR_ASSERT(routing_annotation.rr_node_prev_node(cur_rr_node));
for (size_t inode = 0; inode < drive_rr_nodes.size(); ++inode) { for (size_t inode = 0; inode < drive_rr_nodes.size(); ++inode) {
VTR_LOGV(verbose, "Path: %lu -> Driver node '%lu' for src_node '%lu'\n", inode, size_t(drive_rr_nodes[inode]), size_t(cur_rr_node));
if ((input_nets[inode] == output_net) && if ((input_nets[inode] == output_net) &&
(drive_rr_nodes[inode] == (drive_rr_nodes[inode] ==
routing_annotation.rr_node_prev_node(cur_rr_node))) { routing_annotation.rr_node_prev_node(cur_rr_node))) {
@ -135,7 +138,6 @@ static void build_switch_block_mux_bitstream(
/* Add output nets */ /* Add output nets */
std::string output_net_ids; std::string output_net_ids;
AtomNetId output_atom_net = atom_ctx.lookup.atom_net(output_net);
if (true == atom_ctx.nlist.valid_net_id(output_atom_net)) { if (true == atom_ctx.nlist.valid_net_id(output_atom_net)) {
output_net_ids += atom_ctx.nlist.net_name(output_atom_net); output_net_ids += atom_ctx.nlist.net_name(output_atom_net);
} else { } else {