From 1d796a5b575c6c89b6a9092b1b9771a1efb5dc18 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Thu, 12 Jun 2025 17:24:28 -0400 Subject: [PATCH 01/22] created helper function and basic line drawing code --- vpr/src/draw/draw_basic.cpp | 37 +++++++++++++++++++++++++++++++------ vpr/src/util/vpr_utils.cpp | 29 +++++++++++++++++++++++++++++ vpr/src/util/vpr_utils.h | 9 +++++++++ 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index c6c6c6d7fd..e5d367b846 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -640,12 +640,8 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren RRNodeId prev_node = rr_nodes_to_draw[i - 1]; auto prev_type = rr_graph.node_type(RRNodeId(prev_node)); - if (!is_inter_cluster_node(rr_graph, prev_node) || !is_inter_cluster_node(rr_graph, inode)) { - continue; - } - - auto iedge = find_edge(prev_node, inode); - auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); + bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); + bool is_prev_node_inter_cluster = is_inter_cluster_node(rr_graph, prev_node); int current_node_layer = rr_graph.node_layer(inode); int prev_node_layer = rr_graph.node_layer(prev_node); @@ -658,6 +654,35 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren ezgl::color color = draw_state->draw_rr_node[inode].color; + + if (!is_inode_inter_cluster && !is_prev_node_inter_cluster) { + + AtomPinId pin_id1 = get_rr_node_atom_pin_id(inode); + AtomPinId pin_id2 = get_rr_node_atom_pin_id(prev_node); + + VTR_ASSERT(pin_id1 != AtomPinId::INVALID() && pin_id2 != AtomPinId::INVALID()); + + ezgl::point2d p1 = atom_pin_draw_coord(pin_id1); + ezgl::point2d p2 = atom_pin_draw_coord(pin_id2); + + g->set_color(color, edge_visibility.alpha); + g->draw_line(p1, p2); + + continue; + } + + if (!is_inode_inter_cluster || !is_prev_node_inter_cluster) { + continue; + } + + auto iedge = find_edge(prev_node, inode); + auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); + + + + + + switch (rr_type) { case e_rr_type::OPIN: { draw_rr_pin(inode, color, g); diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index a45818da48..5aad9c6f02 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -1755,6 +1755,35 @@ RRNodeId get_atom_pin_rr_node_id(AtomPinId atom_pin_id) { return rr_node_id; } +AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id) { + auto& device_ctx = g_vpr_ctx.device(); + auto& place_ctx = g_vpr_ctx.placement(); + + VTR_ASSERT(!is_inter_cluster_node(g_vpr_ctx.device().rr_graph, rr_node_id)); + + int pin_physical_num = device_ctx.rr_graph.node_ptc_num(rr_node_id); + int x = device_ctx.rr_graph.node_xlow(rr_node_id); + int y = device_ctx.rr_graph.node_ylow(rr_node_id); + int layer = device_ctx.rr_graph.node_layer(rr_node_id); + + t_physical_tile_type_ptr physical_tile = device_ctx.grid.get_physical_type({x, y, layer}); + + auto [sub_tile, sub_tile_num] = get_sub_tile_from_pin_physical_num(physical_tile, pin_physical_num); + VTR_ASSERT(sub_tile && sub_tile_num >= 0 && sub_tile_num < physical_tile->capacity); + + ClusterBlockId blk_id = place_ctx.grid_blocks().block_at_location({x, y, sub_tile_num, layer}); + VTR_ASSERT(blk_id != ClusterBlockId::INVALID()); + + t_pb_graph_pin* pb_graph_pin = physical_tile->pin_num_to_pb_pin.at(pin_physical_num); + + VTR_ASSERT(pb_graph_pin); + + AtomPinId atom_pin_id = find_atom_pin(blk_id, pb_graph_pin); + + return atom_pin_id; + +} + bool node_in_same_physical_tile(RRNodeId node_first, RRNodeId node_second) { const auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; diff --git a/vpr/src/util/vpr_utils.h b/vpr/src/util/vpr_utils.h index 7fe8e28175..35220edf3a 100644 --- a/vpr/src/util/vpr_utils.h +++ b/vpr/src/util/vpr_utils.h @@ -256,6 +256,15 @@ RRNodeId get_pin_rr_node_id(const RRSpatialLookup& rr_spatial_lookup, */ RRNodeId get_atom_pin_rr_node_id(AtomPinId atom_pin_id); +/** + * @brief Returns the atom pin ID for the given RR node ID. + * **Warning**: This function should be called only if flat-router is enabled, + * since, otherwise, the routing resources inside clusters are not added to the RR graph. + * @param rr_node_id The RR node ID. + */ +AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id); + + RRNodeId get_class_rr_node_id(const RRSpatialLookup& rr_spatial_lookup, t_physical_tile_type_ptr physical_tile, const int layer, From 718e85ae0e3d03059f895bc4805372dd9621ca52 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Mon, 16 Jun 2025 17:17:58 -0400 Subject: [PATCH 02/22] updated internal block drawing location --- vpr/src/draw/draw_basic.cpp | 34 ++++++++++------- vpr/src/draw/draw_types.h | 5 +++ vpr/src/draw/intra_logic_block.cpp | 59 +++++++++++++++--------------- vpr/src/util/vpr_utils.cpp | 11 +++--- vpr/src/util/vpr_utils.h | 1 - 5 files changed, 60 insertions(+), 50 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index e5d367b846..d30632d6da 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -632,6 +632,11 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren for (int j = 1; j < height - 1; j++) chany_track[i][j] = (-1); } + // VTR_LOG("Start"); + // for (RRNodeId inode : rr_nodes_to_draw) { + // VTR_LOG( "%d\n", rr_graph.node_type(inode)); + // } + // VTR_LOG("End"); for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { RRNodeId inode = rr_nodes_to_draw[i]; @@ -655,18 +660,26 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren ezgl::color color = draw_state->draw_rr_node[inode].color; + + + if (rr_graph.node_type(inode) == e_rr_type::SINK || rr_graph.node_type(inode) == e_rr_type::SOURCE || rr_graph.node_type(prev_node) == e_rr_type::SINK || rr_graph.node_type(prev_node) == e_rr_type::SOURCE) { + continue; + } + if (!is_inode_inter_cluster && !is_prev_node_inter_cluster) { - - AtomPinId pin_id1 = get_rr_node_atom_pin_id(inode); - AtomPinId pin_id2 = get_rr_node_atom_pin_id(prev_node); - VTR_ASSERT(pin_id1 != AtomPinId::INVALID() && pin_id2 != AtomPinId::INVALID()); - ezgl::point2d p1 = atom_pin_draw_coord(pin_id1); - ezgl::point2d p2 = atom_pin_draw_coord(pin_id2); - g->set_color(color, edge_visibility.alpha); - g->draw_line(p1, p2); + // AtomPinId pin_id1 = get_rr_node_atom_pin_id(inode); + // AtomPinId pin_id2 = get_rr_node_atom_pin_id(prev_node); + + // VTR_ASSERT(pin_id1 != AtomPinId::INVALID() && pin_id2 != AtomPinId::INVALID()); + + // ezgl::point2d p1 = atom_pin_draw_coord(pin_id1); + // ezgl::point2d p2 = atom_pin_draw_coord(pin_id2); + + // g->set_color(color, edge_visibility.alpha); + // g->draw_line(p1, p2); continue; } @@ -678,11 +691,6 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren auto iedge = find_edge(prev_node, inode); auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); - - - - - switch (rr_type) { case e_rr_type::OPIN: { draw_rr_pin(inode, color, g); diff --git a/vpr/src/draw/draw_types.h b/vpr/src/draw/draw_types.h index 92cdae4601..a0ea161d49 100644 --- a/vpr/src/draw/draw_types.h +++ b/vpr/src/draw/draw_types.h @@ -432,6 +432,11 @@ struct t_draw_coords { */ ezgl::rectangle get_absolute_pb_bbox(const ClusterBlockId clb_index, const t_pb_graph_node* pb_gnode); + /** + * @brief returns a 2D point for the absolute location of the given pb_graph_pin + */ + ezgl::point2d get_absolute_pin_location(const ClusterBlockId clb_index, const t_pb_graph_pin* pb_graph_pin); + ///@brief Returns bounding box for CLB of given idx/type ezgl::rectangle get_absolute_clb_bbox(const ClusterBlockId clb_index, const t_logical_block_type_ptr type); diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index d30bded969..28ea752b97 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -38,7 +38,7 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height); static int draw_internal_find_max_lvl(const t_pb_type& pb_type); -static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_pb_types, int type_index, int num_pb, int pb_index, float parent_width, float parent_height, float* blk_width, float* blk_height); +static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height); std::vector collect_pb_atoms(const t_pb* pb); void collect_pb_atoms_recurr(const t_pb* pb, std::vector& atoms); t_pb* highlight_sub_block_helper(const ClusterBlockId clb_index, t_pb* pb, const ezgl::point2d& local_pt, int max_depth); @@ -237,11 +237,25 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p /* Find the number of instances for each child pb_type. */ int num_pb = mode.pb_type_children[j].num_pb; + int num_blocks = num_pb * num_children; + + // determine an optimal number of columns (calculates central factor) + int num_columns = 1; + for(int k = 1; k * k <= num_blocks; ++k) { + if(num_blocks % k == 0) { + num_columns = k; + } + } + int num_rows = num_blocks / num_columns; + for (int k = 0; k < num_pb; ++k) { + + int num_block = j * num_pb + k; + /* Compute bound box for block. Don't call if pb_type is root-level pb. */ draw_internal_calc_coords(type_descrip_index, &pb_graph_node->child_pb_graph_nodes[i][j][k], - num_children, j, num_pb, k, + num_block, num_columns, num_rows, parent_width, parent_height, &blk_width, &blk_height); @@ -258,51 +272,36 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p * are relative to the left and bottom corner of the parent block. */ static void -draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_pb_types, int type_index, int num_pb, int pb_index, float parent_width, float parent_height, float* blk_width, float* blk_height) { - t_draw_state* draw_state = get_draw_state_vars(); - const auto& device_ctx = g_vpr_ctx.device(); - const auto& grid_blocks = draw_state->get_graphics_blk_loc_registry_ref().grid_blocks(); +draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height) { // get the bbox for this pb type ezgl::rectangle& pb_bbox = get_draw_coords_vars()->blk_info.at(type_descrip_index).get_pb_bbox_ref(*pb_graph_node); const float FRACTION_PARENT_PADDING_X = 0.01; + const float FRACTION_PARENT_PADDING_Y = 0.01; - const float NORMAL_FRACTION_PARENT_HEIGHT = 0.90; - float capacity_divisor = 1; - const float FRACTION_PARENT_PADDING_BOTTOM = 0.01; - - const float FRACTION_CHILD_MARGIN_X = 0.025; - const float FRACTION_CHILD_MARGIN_Y = 0.04; - - int capacity = device_ctx.physical_tile_types[type_descrip_index].capacity; - // TODO: this is a hack - should be fixed for the layer_num - const auto& type = device_ctx.grid.get_physical_type({1, 0, 0}); - if (capacity > 1 && device_ctx.grid.width() > 0 && device_ctx.grid.height() > 0 && grid_blocks.get_usage({1, 0, 0}) != 0 - && type_descrip_index == type->index) { - // that should test for io blocks, and setting capacity_divisor > 1 - // will squish every thing down - capacity_divisor = capacity - 1; - } + const float FRACTION_CHILD_MARGIN_X = 0.01; + const float FRACTION_CHILD_MARGIN_Y = 0.01; /* Draw all child-level blocks in just most of the space inside their parent block. */ float parent_drawing_width = parent_width * (1 - FRACTION_PARENT_PADDING_X * 2); - float parent_drawing_height = parent_height * (NORMAL_FRACTION_PARENT_HEIGHT / capacity_divisor); + float parent_drawing_height = parent_height * (1 - FRACTION_PARENT_PADDING_Y * 2); /* The left and bottom corner (inside the parent block) of the space to draw * child blocks. */ float sub_tile_x = parent_width * FRACTION_PARENT_PADDING_X; - float sub_tile_y = parent_height * FRACTION_PARENT_PADDING_BOTTOM; + float sub_tile_y = parent_height * FRACTION_PARENT_PADDING_Y; + + int x_index = num_block % num_columns; + int y_index = num_block / num_columns; - /* Divide parent_drawing_width by the number of child types. */ - float child_width = parent_drawing_width / num_pb_types; - /* Divide parent_drawing_height by the number of instances of the pb_type. */ - float child_height = parent_drawing_height / num_pb; + float child_width = parent_drawing_width / num_columns; + float child_height = parent_drawing_height / num_rows; /* The starting point to draw the physical block. */ - double left = child_width * type_index + sub_tile_x + FRACTION_CHILD_MARGIN_X * child_width; - double bot = child_height * pb_index + sub_tile_y + FRACTION_CHILD_MARGIN_Y * child_height; + double left = child_width * x_index + sub_tile_x + FRACTION_CHILD_MARGIN_X * child_width; + double bot = child_height * y_index + sub_tile_y + FRACTION_CHILD_MARGIN_Y * child_height; /* Leave some space between different pb_types. */ child_width *= 1 - FRACTION_CHILD_MARGIN_X * 2; diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index 5aad9c6f02..b672d09669 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -858,13 +858,13 @@ t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(const t_model_ports* m } //Retrieves the atom pin associated with a specific CLB and pb_graph_pin +// Warning: Not all pb_graph_pins are associated with an atom pin! AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin) { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& atom_ctx = g_vpr_ctx.atom(); int pb_route_id = pb_gpin->pin_count_in_cluster; AtomNetId atom_net = cluster_ctx.clb_nlist.block_pb(blk_id)->pb_route[pb_route_id].atom_net_id; - VTR_ASSERT(atom_net); AtomPinId atom_pin; @@ -879,7 +879,7 @@ AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin) { atom_pin = pin; } } - + VTR_ASSERT(atom_pin); return atom_pin; @@ -1765,7 +1765,7 @@ AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id) { int x = device_ctx.rr_graph.node_xlow(rr_node_id); int y = device_ctx.rr_graph.node_ylow(rr_node_id); int layer = device_ctx.rr_graph.node_layer(rr_node_id); - + t_physical_tile_type_ptr physical_tile = device_ctx.grid.get_physical_type({x, y, layer}); auto [sub_tile, sub_tile_num] = get_sub_tile_from_pin_physical_num(physical_tile, pin_physical_num); @@ -1774,14 +1774,13 @@ AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id) { ClusterBlockId blk_id = place_ctx.grid_blocks().block_at_location({x, y, sub_tile_num, layer}); VTR_ASSERT(blk_id != ClusterBlockId::INVALID()); - t_pb_graph_pin* pb_graph_pin = physical_tile->pin_num_to_pb_pin.at(pin_physical_num); + t_pb_graph_pin* pb_graph_pin = physical_tile->pin_num_to_pb_pin.at(pin_physical_num); VTR_ASSERT(pb_graph_pin); - AtomPinId atom_pin_id = find_atom_pin(blk_id, pb_graph_pin); + AtomPinId atom_pin_id = find_atom_pin(blk_id, pb_graph_pin); return atom_pin_id; - } bool node_in_same_physical_tile(RRNodeId node_first, RRNodeId node_second) { diff --git a/vpr/src/util/vpr_utils.h b/vpr/src/util/vpr_utils.h index 35220edf3a..7ebfc2145b 100644 --- a/vpr/src/util/vpr_utils.h +++ b/vpr/src/util/vpr_utils.h @@ -264,7 +264,6 @@ RRNodeId get_atom_pin_rr_node_id(AtomPinId atom_pin_id); */ AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id); - RRNodeId get_class_rr_node_id(const RRSpatialLookup& rr_spatial_lookup, t_physical_tile_type_ptr physical_tile, const int layer, From 885151aa14bfbc0914d34c4673edbd3533152442 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Tue, 17 Jun 2025 13:11:19 -0400 Subject: [PATCH 03/22] updated intra logic block drawing --- vpr/src/draw/draw_types.cpp | 10 ++++++ vpr/src/draw/intra_logic_block.cpp | 55 ++++++++++++++++-------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index 0394084364..227d3b8b95 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -151,6 +151,16 @@ ezgl::rectangle t_draw_coords::get_absolute_pb_bbox(const ClusterBlockId clb_ind return result; } +ezgl::point2d t_draw_coords::get_absolute_pin_location( const ClusterBlockId clb_index,const t_pb_graph_pin* pb_graph_pin) { + + t_pb_graph_node* pb_gnode = pb_graph_pin->parent_node; + ezgl::rectangle pb_bbox = this->get_absolute_pb_bbox(clb_index, pb_gnode); + int num_pins = pb_gnode->num_pins(); + // int pin_index = + + +} + ezgl::rectangle t_draw_coords::get_absolute_clb_bbox(const ClusterBlockId clb_index, const t_logical_block_type_ptr block_type) { t_draw_state* draw_state = get_draw_state_vars(); const auto& block_locs = draw_state->get_graphics_blk_loc_registry_ref().block_locs(); diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 28ea752b97..c50838fa48 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -36,9 +36,9 @@ /************************* Subroutines local to this file. *******************************/ -static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height); +static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height, float scale_factor); static int draw_internal_find_max_lvl(const t_pb_type& pb_type); -static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height); +static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height, float scale_factor); std::vector collect_pb_atoms(const t_pb* pb); void collect_pb_atoms_recurr(const t_pb* pb, std::vector& atoms); t_pb* highlight_sub_block_helper(const ClusterBlockId clb_index, t_pb* pb, const ezgl::point2d& local_pt, int max_depth); @@ -130,7 +130,7 @@ void draw_internal_init_blk() { clb_bbox = ezgl::rectangle(bot_left, top_right); draw_internal_load_coords(type_descriptor_index, pb_graph_head_node, - clb_bbox.width(), clb_bbox.height()); + clb_bbox.width(), clb_bbox.height(), std::max(clb_bbox.width(), clb_bbox.height())); /* Determine the max number of sub_block levels in the FPGA */ draw_state->max_sub_blk_lvl = std::max(draw_internal_find_max_lvl(*type.pb_type), @@ -218,7 +218,7 @@ static int draw_internal_find_max_lvl(const t_pb_type& pb_type) { * traverses through the pb_graph for a descriptor_type (given by type_descrip_index), and * calls helper function to compute bounding box values. */ -static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height) { +static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height, float scale_factor) { float blk_width = 0.; float blk_height = 0.; @@ -239,7 +239,7 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p int num_blocks = num_pb * num_children; - // determine an optimal number of columns (calculates central factor) + // determine an optimal number of columns int num_columns = 1; for(int k = 1; k * k <= num_blocks; ++k) { if(num_blocks % k == 0) { @@ -248,6 +248,11 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p } int num_rows = num_blocks / num_columns; + const int MAX_WIDTH_HEIGHT_RATIO = 2; + if(parent_width > parent_height * MAX_WIDTH_HEIGHT_RATIO){ + std::swap(num_columns, num_rows); + } + for (int k = 0; k < num_pb; ++k) { int num_block = j * num_pb + k; @@ -257,12 +262,12 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p &pb_graph_node->child_pb_graph_nodes[i][j][k], num_block, num_columns, num_rows, parent_width, parent_height, - &blk_width, &blk_height); + &blk_width, &blk_height, scale_factor); /* Traverse to next level in the pb_graph */ draw_internal_load_coords(type_descrip_index, &pb_graph_node->child_pb_graph_nodes[i][j][k], - blk_width, blk_height); + blk_width, blk_height, scale_factor); } } } @@ -272,26 +277,27 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p * are relative to the left and bottom corner of the parent block. */ static void -draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height) { +draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height, float scale_factor) { // get the bbox for this pb type ezgl::rectangle& pb_bbox = get_draw_coords_vars()->blk_info.at(type_descrip_index).get_pb_bbox_ref(*pb_graph_node); + - const float FRACTION_PARENT_PADDING_X = 0.01; - const float FRACTION_PARENT_PADDING_Y = 0.01; + const float FRACTION_PARENT_PADDING = 0.005; + const float FRACTION_CHILD_MARGIN = 0.003; + const float FRACTION_TEXT_PADDING = 0.01; + const int MIN_WIDTH_HEIGHT_RATIO = 2; - const float FRACTION_CHILD_MARGIN_X = 0.01; - const float FRACTION_CHILD_MARGIN_Y = 0.01; + float abs_parent_padding = scale_factor * FRACTION_PARENT_PADDING; + float abs_text_padding = scale_factor * FRACTION_TEXT_PADDING; /* Draw all child-level blocks in just most of the space inside their parent block. */ - float parent_drawing_width = parent_width * (1 - FRACTION_PARENT_PADDING_X * 2); - float parent_drawing_height = parent_height * (1 - FRACTION_PARENT_PADDING_Y * 2); + float parent_drawing_width = parent_width - 2* abs_parent_padding; + float parent_drawing_height = parent_height - 2 * abs_parent_padding - abs_text_padding; - /* The left and bottom corner (inside the parent block) of the space to draw - * child blocks. - */ - float sub_tile_x = parent_width * FRACTION_PARENT_PADDING_X; - float sub_tile_y = parent_height * FRACTION_PARENT_PADDING_Y; + if(parent_drawing_height > MIN_WIDTH_HEIGHT_RATIO * parent_drawing_width) { + parent_drawing_height /= 2; + } int x_index = num_block % num_columns; int y_index = num_block / num_columns; @@ -299,14 +305,13 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node float child_width = parent_drawing_width / num_columns; float child_height = parent_drawing_height / num_rows; + float abs_child_margin = scale_factor * FRACTION_CHILD_MARGIN; /* The starting point to draw the physical block. */ - double left = child_width * x_index + sub_tile_x + FRACTION_CHILD_MARGIN_X * child_width; - double bot = child_height * y_index + sub_tile_y + FRACTION_CHILD_MARGIN_Y * child_height; + double left = child_width * x_index + abs_parent_padding + abs_child_margin; + double bot = child_height * y_index + abs_parent_padding + abs_child_margin; - /* Leave some space between different pb_types. */ - child_width *= 1 - FRACTION_CHILD_MARGIN_X * 2; - /* Leave some space between different instances of the same type. */ - child_height *= 1 - FRACTION_CHILD_MARGIN_Y * 2; + child_width -= abs_child_margin * 2; + child_height -= abs_child_margin * 2; /* Endpoint for drawing the pb_type */ double right = left + child_width; From 6c43c20bea9b66b9ce5c6ff5822f5fe48addc619 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Tue, 17 Jun 2025 15:48:16 -0400 Subject: [PATCH 04/22] adjusted text position --- vpr/src/draw/intra_logic_block.cpp | 37 ++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index c50838fa48..47eb5c2152 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -36,9 +36,9 @@ /************************* Subroutines local to this file. *******************************/ -static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height, float scale_factor); +static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height); static int draw_internal_find_max_lvl(const t_pb_type& pb_type); -static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height, float scale_factor); +static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height); std::vector collect_pb_atoms(const t_pb* pb); void collect_pb_atoms_recurr(const t_pb* pb, std::vector& atoms); t_pb* highlight_sub_block_helper(const ClusterBlockId clb_index, t_pb* pb, const ezgl::point2d& local_pt, int max_depth); @@ -130,7 +130,7 @@ void draw_internal_init_blk() { clb_bbox = ezgl::rectangle(bot_left, top_right); draw_internal_load_coords(type_descriptor_index, pb_graph_head_node, - clb_bbox.width(), clb_bbox.height(), std::max(clb_bbox.width(), clb_bbox.height())); + clb_bbox.width(), clb_bbox.height()); /* Determine the max number of sub_block levels in the FPGA */ draw_state->max_sub_blk_lvl = std::max(draw_internal_find_max_lvl(*type.pb_type), @@ -218,7 +218,7 @@ static int draw_internal_find_max_lvl(const t_pb_type& pb_type) { * traverses through the pb_graph for a descriptor_type (given by type_descrip_index), and * calls helper function to compute bounding box values. */ -static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height, float scale_factor) { +static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height) { float blk_width = 0.; float blk_height = 0.; @@ -262,12 +262,12 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p &pb_graph_node->child_pb_graph_nodes[i][j][k], num_block, num_columns, num_rows, parent_width, parent_height, - &blk_width, &blk_height, scale_factor); + &blk_width, &blk_height); /* Traverse to next level in the pb_graph */ draw_internal_load_coords(type_descrip_index, &pb_graph_node->child_pb_graph_nodes[i][j][k], - blk_width, blk_height, scale_factor); + blk_width, blk_height); } } } @@ -277,19 +277,27 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p * are relative to the left and bottom corner of the parent block. */ static void -draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height, float scale_factor) { +draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height) { // get the bbox for this pb type ezgl::rectangle& pb_bbox = get_draw_coords_vars()->blk_info.at(type_descrip_index).get_pb_bbox_ref(*pb_graph_node); - + + float tile_width = get_draw_coords_vars()->get_tile_width(); const float FRACTION_PARENT_PADDING = 0.005; const float FRACTION_CHILD_MARGIN = 0.003; const float FRACTION_TEXT_PADDING = 0.01; const int MIN_WIDTH_HEIGHT_RATIO = 2; - float abs_parent_padding = scale_factor * FRACTION_PARENT_PADDING; - float abs_text_padding = scale_factor * FRACTION_TEXT_PADDING; + float abs_parent_padding = tile_width * FRACTION_PARENT_PADDING; + float abs_text_padding = tile_width * FRACTION_TEXT_PADDING; + float abs_child_margin = tile_width * FRACTION_CHILD_MARGIN; + + // add safety check to ensure that the dimensions will never be below zero + if (parent_width <= 2* abs_parent_padding || parent_height <= 2 * abs_parent_padding - abs_text_padding) { + abs_parent_padding = 0; + abs_text_padding = 0; + } /* Draw all child-level blocks in just most of the space inside their parent block. */ float parent_drawing_width = parent_width - 2* abs_parent_padding; @@ -305,11 +313,16 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node float child_width = parent_drawing_width / num_columns; float child_height = parent_drawing_height / num_rows; - float abs_child_margin = scale_factor * FRACTION_CHILD_MARGIN; + // add safety check to ensure that the dimensions will never be below zero + if(child_width <= abs_child_margin * 2 || child_height <= abs_child_margin * 2) { + abs_child_margin = 0; + } + /* The starting point to draw the physical block. */ double left = child_width * x_index + abs_parent_padding + abs_child_margin; double bot = child_height * y_index + abs_parent_padding + abs_child_margin; + child_width -= abs_child_margin * 2; child_height -= abs_child_margin * 2; @@ -404,7 +417,7 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg if (draw_state->draw_block_text) { g->draw_text( ezgl::point2d(abs_bbox.center_x(), - abs_bbox.top() - (abs_bbox.height()) / 15.0), + abs_bbox.top() - draw_coords->get_tile_height() * 0.01), pb_type->name, abs_bbox.width(), abs_bbox.height()); From 97f1203a9e9ba065ee3e407d4402d48b4c4688ed Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Wed, 18 Jun 2025 11:41:21 -0400 Subject: [PATCH 05/22] added basic intra cluster routing visualization --- vpr/src/draw/draw_basic.cpp | 26 ++++++++------------------ vpr/src/draw/draw_types.cpp | 10 ++++++++-- vpr/src/util/vpr_utils.cpp | 10 +++++++++- vpr/src/util/vpr_utils.h | 10 +++++++++- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index d30632d6da..5920b05502 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -607,6 +607,7 @@ void draw_routed_net(ParentNetId net_id, ezgl::renderer* g) { //Draws the set of rr_nodes specified, using the colors set in draw_state void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); + t_draw_coords* draw_coords = get_draw_coords_vars(); auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; @@ -632,11 +633,6 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren for (int j = 1; j < height - 1; j++) chany_track[i][j] = (-1); } - // VTR_LOG("Start"); - // for (RRNodeId inode : rr_nodes_to_draw) { - // VTR_LOG( "%d\n", rr_graph.node_type(inode)); - // } - // VTR_LOG("End"); for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { RRNodeId inode = rr_nodes_to_draw[i]; @@ -659,27 +655,21 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren ezgl::color color = draw_state->draw_rr_node[inode].color; - - - + // Skip drawing sources and sinks if (rr_graph.node_type(inode) == e_rr_type::SINK || rr_graph.node_type(inode) == e_rr_type::SOURCE || rr_graph.node_type(prev_node) == e_rr_type::SINK || rr_graph.node_type(prev_node) == e_rr_type::SOURCE) { continue; } if (!is_inode_inter_cluster && !is_prev_node_inter_cluster) { + auto blk_id_pin_id1 = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + auto blk_id_pin_id2 = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); + ezgl::point2d p1 = draw_coords->get_absolute_pin_location(blk_id_pin_id1.first, blk_id_pin_id1.second); + ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id2.first, blk_id_pin_id2.second); - // AtomPinId pin_id1 = get_rr_node_atom_pin_id(inode); - // AtomPinId pin_id2 = get_rr_node_atom_pin_id(prev_node); - - // VTR_ASSERT(pin_id1 != AtomPinId::INVALID() && pin_id2 != AtomPinId::INVALID()); - - // ezgl::point2d p1 = atom_pin_draw_coord(pin_id1); - // ezgl::point2d p2 = atom_pin_draw_coord(pin_id2); - - // g->set_color(color, edge_visibility.alpha); - // g->draw_line(p1, p2); + g->set_color(color, edge_visibility.alpha); + g->draw_line(p1, p2); continue; } diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index 227d3b8b95..b48a5084eb 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -156,9 +156,15 @@ ezgl::point2d t_draw_coords::get_absolute_pin_location( const ClusterBlockId clb t_pb_graph_node* pb_gnode = pb_graph_pin->parent_node; ezgl::rectangle pb_bbox = this->get_absolute_pb_bbox(clb_index, pb_gnode); int num_pins = pb_gnode->num_pins(); - // int pin_index = + int num_pin_in_port = pb_graph_pin->pin_number; + int num_pins_in_port = pb_graph_pin->port->num_pins; + int num_port = pb_graph_pin->port->index; + int num_pin = num_pins_in_port * num_port + num_pin_in_port; - + + float interval = pb_bbox.width() / (num_pins + 1); + + return ezgl::point2d(interval * (num_pin + 1), 0.01 *this->tile_width) + pb_bbox.top_left(); } ezgl::rectangle t_draw_coords::get_absolute_clb_bbox(const ClusterBlockId clb_index, const t_logical_block_type_ptr block_type) { diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index b672d09669..67987eb44d 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -1755,7 +1755,7 @@ RRNodeId get_atom_pin_rr_node_id(AtomPinId atom_pin_id) { return rr_node_id; } -AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id) { +std::pair get_rr_node_cluster_blk_id_pb_graph_pin(RRNodeId rr_node_id) { auto& device_ctx = g_vpr_ctx.device(); auto& place_ctx = g_vpr_ctx.placement(); @@ -1778,6 +1778,14 @@ AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id) { VTR_ASSERT(pb_graph_pin); + return {blk_id, pb_graph_pin}; +} + +AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id) { + ClusterBlockId blk_id; + t_pb_graph_pin* pb_graph_pin; + std::tie(blk_id, pb_graph_pin) = get_rr_node_cluster_blk_id_pb_graph_pin(rr_node_id); + AtomPinId atom_pin_id = find_atom_pin(blk_id, pb_graph_pin); return atom_pin_id; diff --git a/vpr/src/util/vpr_utils.h b/vpr/src/util/vpr_utils.h index 7ebfc2145b..a294e7d286 100644 --- a/vpr/src/util/vpr_utils.h +++ b/vpr/src/util/vpr_utils.h @@ -257,11 +257,19 @@ RRNodeId get_pin_rr_node_id(const RRSpatialLookup& rr_spatial_lookup, RRNodeId get_atom_pin_rr_node_id(AtomPinId atom_pin_id); /** - * @brief Returns the atom pin ID for the given RR node ID. + * @brief Returns the cluster block ID and pb_graph_pin for the given RR node ID. * **Warning**: This function should be called only if flat-router is enabled, * since, otherwise, the routing resources inside clusters are not added to the RR graph. * @param rr_node_id The RR node ID. */ +std::pair get_rr_node_cluster_blk_id_pb_graph_pin(RRNodeId rr_node_id); + +/** + * @brief Returns the atom pin ID for the given RR node ID. + * **Warning**: This function should be called only if flat-router is enabled, + * since, otherwise, the routing resources inside clusters are not added to the RR graph. Also, not all RRNodes have an AtomPinId associated with them. + * @param rr_node_id The RR node ID. + */ AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id); RRNodeId get_class_rr_node_id(const RRSpatialLookup& rr_spatial_lookup, From c6f7d0dca2376212e1af894d3f4a781193ce15f5 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Fri, 20 Jun 2025 13:29:32 -0400 Subject: [PATCH 06/22] implemented intra-cluster routing --- vpr/src/draw/draw.cpp | 2 +- vpr/src/draw/draw.h | 2 +- vpr/src/draw/draw_basic.cpp | 31 ++++++++++++--- vpr/src/draw/draw_searchbar.cpp | 60 ++++++++++++++++++++---------- vpr/src/draw/draw_searchbar.h | 6 ++- vpr/src/draw/draw_types.cpp | 2 +- vpr/src/draw/intra_logic_block.cpp | 2 +- vpr/src/draw/search_bar.cpp | 2 +- 8 files changed, 75 insertions(+), 32 deletions(-) diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp index 42d6123370..796096ac5e 100644 --- a/vpr/src/draw/draw.cpp +++ b/vpr/src/draw/draw.cpp @@ -658,7 +658,7 @@ int get_track_num(int inode, const vtr::OffsetMatrix& chanx_track, const vt * could be caused by the user clicking on a routing resource, toggled, or * fan-in/fan-out of a highlighted node. */ -bool draw_if_net_highlighted(ClusterNetId inet) { +bool draw_if_net_highlighted(ParentNetId inet) { t_draw_state* draw_state = get_draw_state_vars(); if (draw_state->net_color[inet] != DEFAULT_RR_NODE_COLOR) { diff --git a/vpr/src/draw/draw.h b/vpr/src/draw/draw.h index 6224bf49b9..294e3d37ff 100644 --- a/vpr/src/draw/draw.h +++ b/vpr/src/draw/draw.h @@ -94,7 +94,7 @@ ezgl::color to_ezgl_color(vtr::Color color); /* This helper function determines whether a net has been highlighted. The highlighting * could be caused by the user clicking on a routing resource, toggled, or * fan-in/fan-out of a highlighted node. */ -bool draw_if_net_highlighted(ClusterNetId inet); +bool draw_if_net_highlighted(ParentNetId inet); std::vector trace_routed_connection_rr_nodes( ClusterNetId net_id, int driver_pin, diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index df13c659e9..4c68d087e1 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -569,13 +569,9 @@ void drawroute(enum e_draw_net_type draw_net_type, ezgl::renderer* g) { void draw_routed_net(ParentNetId net_id, ezgl::renderer* g) { auto& route_ctx = g_vpr_ctx.routing(); - auto& cluster_ctx = g_vpr_ctx.clustering(); t_draw_state* draw_state = get_draw_state_vars(); - if (cluster_ctx.clb_nlist.net_is_ignored(convert_to_cluster_net_id(net_id))) /* Don't draw. */ - return; - if (!route_ctx.route_trees[net_id]) // No routing -> Skip. (Allows me to draw partially complete routes) return; @@ -583,10 +579,10 @@ void draw_routed_net(ParentNetId net_id, ezgl::renderer* g) { for (auto& rt_node : route_ctx.route_trees[net_id].value().all_nodes()) { RRNodeId inode = rt_node.inode; - if (draw_if_net_highlighted(convert_to_cluster_net_id(net_id))) { + if (draw_if_net_highlighted(net_id)) { /* If a net has been highlighted, highlight the whole net in * * the same color. */ - draw_state->draw_rr_node[inode].color = draw_state->net_color[convert_to_cluster_net_id(net_id)]; + draw_state->draw_rr_node[inode].color = draw_state->net_color[net_id]; draw_state->draw_rr_node[inode].node_highlighted = true; } else { /* If not highlighted, draw the node in default color. */ @@ -676,12 +672,35 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren g->set_color(color, edge_visibility.alpha); g->draw_line(p1, p2); + g->draw_text(p1, blk_id_pin_id1.second->parent_node->pb_type->name, 50, 0.5 * 20); continue; } if (!is_inode_inter_cluster || !is_prev_node_inter_cluster) { + bool swap = false; + if (!is_inode_inter_cluster && is_prev_node_inter_cluster) { + //Swap the nodes so that the inter-cluster node is always the current node + std::swap(inode, prev_node); + swap = true; + } + + auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); + float x1, y1; + ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); + + + for (const e_side& pin_side : TOTAL_2D_SIDES) { + if (!rr_graph.is_node_on_specific_side(RRNodeId(inode), pin_side)) { + continue; + } + draw_get_rr_pin_coords(inode, &x1, &y1, pin_side); + g->set_color(color, edge_visibility.alpha); + g->draw_line({x1, y1}, p2); + } + continue; + } auto iedge = find_edge(prev_node, inode); diff --git a/vpr/src/draw/draw_searchbar.cpp b/vpr/src/draw/draw_searchbar.cpp index e80f450af3..188a411661 100644 --- a/vpr/src/draw/draw_searchbar.cpp +++ b/vpr/src/draw/draw_searchbar.cpp @@ -131,40 +131,60 @@ void draw_highlight_blocks_color(t_logical_block_type_ptr type, /* If an rr_node has been clicked on, it will be highlighted in MAGENTA. * If so, and toggle nets is selected, highlight the whole net in that colour. */ -void highlight_nets(char* message, RRNodeId hit_node, bool is_flat) { +void highlight_net(char* message, RRNodeId hit_node) { auto& cluster_ctx = g_vpr_ctx.clustering(); + auto& atom_ctx = g_vpr_ctx.atom(); auto& route_ctx = g_vpr_ctx.routing(); /* Don't crash if there's no routing */ if (route_ctx.route_trees.empty()) return; + if (route_ctx.is_flat){ + for (auto net_id : atom_ctx.netlist().nets()){ + check_node_highlight_net(message, net_id, hit_node); + } + + } else{ + for (auto net_id : cluster_ctx.clb_nlist.nets()) { + check_node_highlight_net(message, net_id, hit_node); + } + } + + application.update_message(message); +} + +void check_node_highlight_net(char* message, ParentNetId parent_id, + RRNodeId hit_node) { + auto& route_ctx = g_vpr_ctx.routing(); t_draw_state* draw_state = get_draw_state_vars(); - for (auto net_id : cluster_ctx.clb_nlist.nets()) { - ParentNetId parent_id = get_cluster_net_parent_id(g_vpr_ctx.atom().lookup(), net_id, is_flat); - if (!route_ctx.route_trees[parent_id]) - continue; + if (!route_ctx.route_trees[parent_id]) + return; - for (auto& rt_node : route_ctx.route_trees[parent_id].value().all_nodes()) { - RRNodeId inode = rt_node.inode; - if (draw_state->draw_rr_node[inode].color == ezgl::MAGENTA) { - draw_state->net_color[net_id] = draw_state->draw_rr_node[inode].color; - if (inode == hit_node) { - std::string orig_msg(message); - sprintf(message, "%s || Net: %zu (%s)", orig_msg.c_str(), - size_t(net_id), - cluster_ctx.clb_nlist.net_name(net_id).c_str()); + for (auto& rt_node : route_ctx.route_trees[parent_id].value().all_nodes()) { + RRNodeId inode = rt_node.inode; + if (draw_state->draw_rr_node[inode].color == ezgl::MAGENTA) { + draw_state->net_color[parent_id] = draw_state->draw_rr_node[inode].color; + if (inode == hit_node) { + std::string orig_msg(message); + std::string net_name; + if(!route_ctx.is_flat){ + net_name = g_vpr_ctx.clustering().clb_nlist.net_name(convert_to_cluster_net_id(parent_id)); + } else { + net_name = g_vpr_ctx.atom().netlist().net_name(convert_to_atom_net_id(parent_id)); } - } else if (draw_state->draw_rr_node[inode].color - == ezgl::WHITE) { - // If node is de-selected. - draw_state->net_color[net_id] = ezgl::BLACK; - break; + sprintf(message, "%s || Net: %zu (%s)", orig_msg.c_str(), + size_t(parent_id), + net_name.c_str()); } + } else if (draw_state->draw_rr_node[inode].color + == ezgl::WHITE) { + // If node is de-selected. + draw_state->net_color[parent_id] = ezgl::BLACK; + break; } } - application.update_message(message); } /* If an rr_node has been clicked on, it will be either highlighted in MAGENTA, diff --git a/vpr/src/draw/draw_searchbar.h b/vpr/src/draw/draw_searchbar.h index 7d195dde98..4ec24d374e 100644 --- a/vpr/src/draw/draw_searchbar.h +++ b/vpr/src/draw/draw_searchbar.h @@ -28,7 +28,11 @@ void draw_highlight_blocks_color(t_logical_block_type_ptr type, ClusterBlockId b /* If an rr_node has been clicked on, it will be highlighted in MAGENTA. * If so, and toggle nets is selected, highlight the whole net in that colour.*/ -void highlight_nets(char* message, RRNodeId hit_node, bool is_flat); +void highlight_net(char* message, RRNodeId hit_node); + +/* Checks if a node is part of a net, and highlights the net if it is. */ +void check_node_highlight_net(char* message, ParentNetId parent_id, + RRNodeId hit_node); /* If an rr_node has been clicked on, it will be either highlighted in MAGENTA, * or de-highlighted in WHITE. If highlighted, and toggle_rr is selected, highlight diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index b48a5084eb..572e38b512 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -164,7 +164,7 @@ ezgl::point2d t_draw_coords::get_absolute_pin_location( const ClusterBlockId clb float interval = pb_bbox.width() / (num_pins + 1); - return ezgl::point2d(interval * (num_pin + 1), 0.01 *this->tile_width) + pb_bbox.top_left(); + return ezgl::point2d(interval * (num_pin + 1), -0.01 *this->tile_width) + pb_bbox.top_left(); } ezgl::rectangle t_draw_coords::get_absolute_clb_bbox(const ClusterBlockId clb_index, const t_logical_block_type_ptr block_type) { diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 47eb5c2152..b6d2c7fedb 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -198,7 +198,7 @@ void draw_internal_draw_subblk(ezgl::renderer* g) { static int draw_internal_find_max_lvl(const t_pb_type& pb_type) { int i, j; t_mode mode; - int max_levels = 0; + int max_levels = 1; /* If pb_type is a primitive, we have reached the end of pb_graph */ if (pb_type.is_primitive()) diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 17de84c587..74414b6048 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -247,7 +247,7 @@ bool highlight_rr_nodes(RRNodeId hit_node) { } if (draw_state->show_nets) - highlight_nets(message, hit_node, draw_state->is_flat); + highlight_net(message, hit_node); else application.update_message(message); From 9a1a3c4818829f7bfbf0fe04a1c9518f912a5e65 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Fri, 20 Jun 2025 14:11:51 -0400 Subject: [PATCH 07/22] fixed function which calculates max depth --- vpr/src/draw/draw_basic.cpp | 32 ++++++-------------------- vpr/src/draw/draw_toggle_functions.cpp | 2 +- vpr/src/draw/intra_logic_block.cpp | 2 +- vpr/src/draw/ui_setup.cpp | 2 +- 4 files changed, 10 insertions(+), 28 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index 4c68d087e1..5d366d9c39 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -613,29 +613,17 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - static vtr::OffsetMatrix chanx_track; /* [1..device_ctx.grid.width() - 2][0..device_ctx.grid.height() - 2] */ - static vtr::OffsetMatrix chany_track; /* [0..device_ctx.grid.width() - 2][1..device_ctx.grid.height() - 2] */ - if (draw_state->draw_route_type == GLOBAL) { - /* Allocate some temporary storage if it's not already available. */ - int width = (int)device_ctx.grid.width(); - int height = (int)device_ctx.grid.height(); - if (chanx_track.empty()) { - chanx_track = vtr::OffsetMatrix({{{1, width - 1}, {0, height - 1}}}); - } - - if (chany_track.empty()) { - chany_track = vtr::OffsetMatrix({{{0, width - 1}, {1, height - 1}}}); - } + // Draw Pins + for (RRNodeId inode : rr_nodes_to_draw) { + + bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); - for (int i = 1; i < width - 1; i++) - for (int j = 0; j < height - 1; j++) - chanx_track[i][j] = (-1); - for (int i = 0; i < width - 1; i++) - for (int j = 1; j < height - 1; j++) - chany_track[i][j] = (-1); } + + + // Draw Edges for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { RRNodeId inode = rr_nodes_to_draw[i]; auto rr_type = rr_graph.node_type(inode); @@ -724,9 +712,6 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren break; } case e_rr_type::CHANX: { - if (draw_state->draw_route_type == GLOBAL) - chanx_track[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)]++; - draw_rr_chan(inode, color, g); if (edge_visibility.visible) { g->set_color(color, edge_visibility.alpha); @@ -754,9 +739,6 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren break; } case e_rr_type::CHANY: { - if (draw_state->draw_route_type == GLOBAL) - chany_track[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)]++; - draw_rr_chan(inode, color, g); if (edge_visibility.visible) { diff --git a/vpr/src/draw/draw_toggle_functions.cpp b/vpr/src/draw/draw_toggle_functions.cpp index 4800ac14e2..f97c286dac 100644 --- a/vpr/src/draw/draw_toggle_functions.cpp +++ b/vpr/src/draw/draw_toggle_functions.cpp @@ -235,7 +235,7 @@ void toggle_blk_internal_cbk(GtkSpinButton* self, ezgl::application* app) { if (new_value < 0) draw_state->show_blk_internal = 0; else if (new_value >= draw_state->max_sub_blk_lvl) - draw_state->show_blk_internal = draw_state->max_sub_blk_lvl - 1; + draw_state->show_blk_internal = draw_state->max_sub_blk_lvl; else draw_state->show_blk_internal = new_value; app->refresh_drawing(); diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index b6d2c7fedb..47eb5c2152 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -198,7 +198,7 @@ void draw_internal_draw_subblk(ezgl::renderer* g) { static int draw_internal_find_max_lvl(const t_pb_type& pb_type) { int i, j; t_mode mode; - int max_levels = 1; + int max_levels = 0; /* If pb_type is a primitive, we have reached the end of pb_graph */ if (pb_type.is_primitive()) diff --git a/vpr/src/draw/ui_setup.cpp b/vpr/src/draw/ui_setup.cpp index 018f951d37..12e31772f9 100644 --- a/vpr/src/draw/ui_setup.cpp +++ b/vpr/src/draw/ui_setup.cpp @@ -82,7 +82,7 @@ void block_button_setup(ezgl::application* app) { GtkSpinButton* blk_internals_button = GTK_SPIN_BUTTON(app->get_object("ToggleBlkInternals")); g_signal_connect(blk_internals_button, "value-changed", G_CALLBACK(toggle_blk_internal_cbk), app); gtk_spin_button_set_increments(blk_internals_button, 1, 1); - gtk_spin_button_set_range(blk_internals_button, 0., (double)(draw_state->max_sub_blk_lvl - 1)); + gtk_spin_button_set_range(blk_internals_button, 0., (double)(draw_state->max_sub_blk_lvl)); //Toggle Block Pin Util GtkComboBoxText* blk_pin_util = GTK_COMBO_BOX_TEXT(app->get_object("ToggleBlkPinUtil")); From 1aa214c27804e15ee7cde5a299b8343e02af8bb5 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Fri, 20 Jun 2025 15:17:37 -0400 Subject: [PATCH 08/22] reworked pin and edge drawing code --- vpr/src/draw/draw_basic.cpp | 188 +++++++++++++++------------------ vpr/src/draw/draw_rr.cpp | 15 +++ vpr/src/draw/draw_rr.h | 1 + vpr/src/draw/draw_rr_edges.cpp | 37 +++++++ vpr/src/draw/draw_rr_edges.h | 2 + 5 files changed, 138 insertions(+), 105 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index 5d366d9c39..ab8bced504 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -609,164 +609,142 @@ void draw_routed_net(ParentNetId net_id, ezgl::renderer* g) { //Draws the set of rr_nodes specified, using the colors set in draw_state void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); - t_draw_coords* draw_coords = get_draw_coords_vars(); auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; // Draw Pins - for (RRNodeId inode : rr_nodes_to_draw) { - + for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { + RRNodeId inode = rr_nodes_to_draw[i]; + auto rr_type = rr_graph.node_type(inode); bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); + int node_layer = rr_graph.node_layer(inode); + ezgl::color color = draw_state->draw_rr_node[inode].color; - } + // For 3D architectures, draw only visible layers + if (!draw_state->draw_layer_display[node_layer].visible) { + continue; + } + // Skip drawing sources and sinks + if (rr_type == e_rr_type::SINK || rr_type == e_rr_type::SOURCE){ + continue; + } + + // Draw intra-cluster nodes + if (!is_inode_inter_cluster) { + draw_rr_intrapin(inode, color, g); + continue; + } + + // Draw IO Pins + if (rr_type == e_rr_type::OPIN || rr_type == e_rr_type::IPIN) { + draw_rr_pin(inode, color, g); + continue; + } + // Draw Channels + if (rr_type == e_rr_type::CHANY || rr_type == e_rr_type::CHANX) { + draw_rr_chan(inode, color, g); + continue; + } + } // Draw Edges for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { + RRNodeId inode = rr_nodes_to_draw[i]; auto rr_type = rr_graph.node_type(inode); + bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); + int current_node_layer = rr_graph.node_layer(inode); RRNodeId prev_node = rr_nodes_to_draw[i - 1]; auto prev_type = rr_graph.node_type(RRNodeId(prev_node)); - - bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); bool is_prev_node_inter_cluster = is_inter_cluster_node(rr_graph, prev_node); - - int current_node_layer = rr_graph.node_layer(inode); int prev_node_layer = rr_graph.node_layer(prev_node); + t_draw_layer_display edge_visibility = get_element_visibility_and_transparency(prev_node_layer, current_node_layer); + ezgl::color color = draw_state->draw_rr_node[inode].color; - //Don't draw node if the layer of the node is not set to visible on screen - if (!draw_state->draw_layer_display[current_node_layer].visible) { + // For 3D architectures, draw only visible layers + if (!draw_state->draw_layer_display[current_node_layer].visible || !edge_visibility.visible) { continue; } - ezgl::color color = draw_state->draw_rr_node[inode].color; - // Skip drawing sources and sinks - if (rr_graph.node_type(inode) == e_rr_type::SINK || rr_graph.node_type(inode) == e_rr_type::SOURCE || rr_graph.node_type(prev_node) == e_rr_type::SINK || rr_graph.node_type(prev_node) == e_rr_type::SOURCE) { + if (rr_type == e_rr_type::SINK || rr_type == e_rr_type::SOURCE || prev_type == e_rr_type::SINK || prev_type == e_rr_type::SOURCE) { continue; } - if (!is_inode_inter_cluster && !is_prev_node_inter_cluster) { - - auto blk_id_pin_id1 = get_rr_node_cluster_blk_id_pb_graph_pin(inode); - auto blk_id_pin_id2 = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); - - ezgl::point2d p1 = draw_coords->get_absolute_pin_location(blk_id_pin_id1.first, blk_id_pin_id1.second); - ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id2.first, blk_id_pin_id2.second); - - g->set_color(color, edge_visibility.alpha); - g->draw_line(p1, p2); - g->draw_text(p1, blk_id_pin_id1.second->parent_node->pb_type->name, 50, 0.5 * 20); + g->set_color(color, edge_visibility.alpha); + if (!is_inode_inter_cluster && !is_prev_node_inter_cluster) { + draw_intrapin_to_intrapin(inode, prev_node, g); continue; } if (!is_inode_inter_cluster || !is_prev_node_inter_cluster) { - bool swap = false; - if (!is_inode_inter_cluster && is_prev_node_inter_cluster) { - //Swap the nodes so that the inter-cluster node is always the current node - std::swap(inode, prev_node); - swap = true; - } - - auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); - float x1, y1; - ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); - - - for (const e_side& pin_side : TOTAL_2D_SIDES) { - if (!rr_graph.is_node_on_specific_side(RRNodeId(inode), pin_side)) { - continue; - } - draw_get_rr_pin_coords(inode, &x1, &y1, pin_side); - g->set_color(color, edge_visibility.alpha); - g->draw_line({x1, y1}, p2); - } - + draw_intrapin_to_pin(inode, prev_node, g); continue; - } auto iedge = find_edge(prev_node, inode); auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); switch (rr_type) { - case e_rr_type::OPIN: { - draw_rr_pin(inode, color, g); - break; - } case e_rr_type::IPIN: { - draw_rr_pin(inode, color, g); - if (edge_visibility.visible) { - g->set_color(color, edge_visibility.alpha); - if (rr_graph.node_type(prev_node) == e_rr_type::OPIN) { - draw_pin_to_pin(prev_node, inode, g); - } else { - draw_pin_to_chan_edge(inode, prev_node, g); - } + if (rr_graph.node_type(prev_node) == e_rr_type::OPIN) { + draw_pin_to_pin(prev_node, inode, g); + } else { + draw_pin_to_chan_edge(inode, prev_node, g); } break; } case e_rr_type::CHANX: { - draw_rr_chan(inode, color, g); - if (edge_visibility.visible) { - g->set_color(color, edge_visibility.alpha); - switch (prev_type) { - case e_rr_type::CHANX: { - draw_chanx_to_chanx_edge(prev_node, inode, switch_type, g); - break; - } - case e_rr_type::CHANY: { - draw_chanx_to_chany_edge(inode, prev_node, FROM_Y_TO_X, switch_type, g); - break; - } - case e_rr_type::OPIN: { - draw_pin_to_chan_edge(prev_node, inode, g); - break; - } - default: { - VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); - } + switch (prev_type) { + case e_rr_type::CHANX: { + draw_chanx_to_chanx_edge(prev_node, inode, switch_type, g); + break; + } + case e_rr_type::CHANY: { + draw_chanx_to_chany_edge(inode, prev_node, FROM_Y_TO_X, switch_type, g); + break; + } + case e_rr_type::OPIN: { + draw_pin_to_chan_edge(prev_node, inode, g); + break; + } + default: { + VPR_ERROR(VPR_ERROR_OTHER, + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } } - break; } case e_rr_type::CHANY: { - draw_rr_chan(inode, color, g); - - if (edge_visibility.visible) { - g->set_color(color, edge_visibility.alpha); - switch (prev_type) { - case e_rr_type::CHANX: { - draw_chanx_to_chany_edge(prev_node, inode, - FROM_X_TO_Y, switch_type, g); - break; - } - case e_rr_type::CHANY: { - draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode), - switch_type, g); - break; - } - case e_rr_type::OPIN: { - draw_pin_to_chan_edge(prev_node, inode, g); + switch (prev_type) { + case e_rr_type::CHANX: { + draw_chanx_to_chany_edge(prev_node, inode, + FROM_X_TO_Y, switch_type, g); + break; + } + case e_rr_type::CHANY: { + draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode), + switch_type, g); + break; + } + case e_rr_type::OPIN: { + draw_pin_to_chan_edge(prev_node, inode, g); - break; - } - default: { - VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); - } + break; + } + default: { + VPR_ERROR(VPR_ERROR_OTHER, + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } } - break; } default: { diff --git a/vpr/src/draw/draw_rr.cpp b/vpr/src/draw/draw_rr.cpp index 156147c17e..f4b6fb3c1a 100644 --- a/vpr/src/draw/draw_rr.cpp +++ b/vpr/src/draw/draw_rr.cpp @@ -513,6 +513,21 @@ void draw_rr_edges(RRNodeId inode, ezgl::renderer* g) { } /* End of for each edge loop */ } +void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g) { + t_draw_coords* draw_coords = get_draw_coords_vars(); + + auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + + ezgl::point2d p = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); + + int transparency_factor = get_rr_node_transparency(inode); + + g->set_color(color, transparency_factor); + g->fill_rectangle( + {p.x - draw_coords->pin_size, p.y - draw_coords->pin_size}, + {p.x + draw_coords->pin_size, p.y + draw_coords->pin_size}); +} + /* Draws an IPIN or OPIN rr_node. Note that the pin can appear on more * * than one side of a clb. Also note that this routine can change the * * current color to BLACK. */ diff --git a/vpr/src/draw/draw_rr.h b/vpr/src/draw/draw_rr.h index dd7a305ffc..97eea54e7a 100644 --- a/vpr/src/draw/draw_rr.h +++ b/vpr/src/draw/draw_rr.h @@ -27,6 +27,7 @@ void draw_rr_edges(RRNodeId from_node, ezgl::renderer* g); void draw_rr_chan(RRNodeId inode, const ezgl::color color, ezgl::renderer* g); +void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); /* Draws an IPIN or OPIN rr_node. Note that the pin can appear on more * than one side of a clb. Also note that this routine can change the * current color to BLACK. */ diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index 85deffe765..4f0443f6f7 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -279,6 +279,43 @@ void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_e } } +void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { + + auto draw_coords = get_draw_coords_vars(); + + auto blk_id_pin_id1 = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + auto blk_id_pin_id2 = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); + + ezgl::point2d p1 = draw_coords->get_absolute_pin_location(blk_id_pin_id1.first, blk_id_pin_id1.second); + ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id2.first, blk_id_pin_id2.second); + + g->draw_line(p1, p2); +} + +void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { + auto draw_coords = get_draw_coords_vars(); + const auto& rr_graph = g_vpr_ctx.device().rr_graph; + + if (!is_inter_cluster_node(rr_graph, inode) && is_inter_cluster_node(rr_graph, prev_node)) { + //Swap the nodes so that the inter-cluster node is always the current node + std::swap(inode, prev_node); + } + + auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); + float x1, y1; + ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); + + + for (const e_side& pin_side : TOTAL_2D_SIDES) { + if (!rr_graph.is_node_on_specific_side(RRNodeId(inode), pin_side)) { + continue; + } + draw_get_rr_pin_coords(inode, &x1, &y1, pin_side); + g->draw_line({x1, y1}, p2); + } + +} + void draw_pin_to_pin(RRNodeId opin_node, RRNodeId ipin_node, ezgl::renderer* g) { /* This routine draws an edge from the opin rr node to the ipin rr node */ const auto& device_ctx = g_vpr_ctx.device(); diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index 3b51bd0ab6..72339bdf5e 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -20,6 +20,8 @@ void draw_chany_to_chany_edge(RRNodeId from_node, RRNodeId to_node, short switch_type, ezgl::renderer* g); void draw_chanx_to_chanx_edge(RRNodeId from_node, RRNodeId to_node, short switch_type, ezgl::renderer* g); void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_edge_dir edge_dir, short switch_type, ezgl::renderer* g); +void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); +void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); void draw_pin_to_pin(RRNodeId opin, RRNodeId ipin, ezgl::renderer* g); void draw_pin_to_sink(RRNodeId ipin_node, RRNodeId sink_node, ezgl::renderer* g); void draw_source_to_pin(RRNodeId source_node, RRNodeId opin_node, ezgl::renderer* g); From 8577aee86ab9910fee2631607a82004533287a15 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Fri, 20 Jun 2025 15:44:25 -0400 Subject: [PATCH 09/22] made the intracluster pins clickable --- vpr/src/draw/draw_rr.cpp | 29 +++++++++++++++++++++++++++++ vpr/src/draw/draw_rr_edges.cpp | 13 +++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/vpr/src/draw/draw_rr.cpp b/vpr/src/draw/draw_rr.cpp index f4b6fb3c1a..ab3c6cdfdc 100644 --- a/vpr/src/draw/draw_rr.cpp +++ b/vpr/src/draw/draw_rr.cpp @@ -514,8 +514,13 @@ void draw_rr_edges(RRNodeId inode, ezgl::renderer* g) { } void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g) { + t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); + if(!draw_state->is_flat){ + return; + } + auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(inode); ezgl::point2d p = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); @@ -698,6 +703,30 @@ RRNodeId draw_check_rr_node_hit(float click_x, float click_y) { if (!draw_state->draw_layer_display[layer_num].visible) { continue; /* Don't check RR nodes on currently invisible layers*/ } + + // Skip Source and Sink Nodes + if (rr_graph.node_type(inode) == e_rr_type::SOURCE + || rr_graph.node_type(inode) == e_rr_type::SINK) { + continue; + } + + // Check for intra cluster nodes + if (!is_inter_cluster_node(rr_graph, inode)) { + + if(!draw_state->is_flat){ + continue; + } + + auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + ezgl::point2d p = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); + + if (click_x >= p.x - draw_coords->pin_size && click_x <= p.x + draw_coords->pin_size && click_y >= p.y - draw_coords->pin_size && click_y <= p.y + draw_coords->pin_size) { + hit_node = inode; + return hit_node; + } + + continue; + } switch (rr_graph.node_type(inode)) { case e_rr_type::IPIN: case e_rr_type::OPIN: { diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index 4f0443f6f7..174fb2f5f3 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -280,8 +280,12 @@ void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_e } void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { + t_draw_state* draw_state = get_draw_state_vars(); + t_draw_coords* draw_coords = get_draw_coords_vars(); - auto draw_coords = get_draw_coords_vars(); + if(!draw_state->is_flat){ + return; + } auto blk_id_pin_id1 = get_rr_node_cluster_blk_id_pb_graph_pin(inode); auto blk_id_pin_id2 = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); @@ -293,7 +297,12 @@ void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::rendere } void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { - auto draw_coords = get_draw_coords_vars(); + t_draw_state* draw_state = get_draw_state_vars(); + t_draw_coords* draw_coords = get_draw_coords_vars(); + + if(!draw_state->is_flat){ + return; + } const auto& rr_graph = g_vpr_ctx.device().rr_graph; if (!is_inter_cluster_node(rr_graph, inode) && is_inter_cluster_node(rr_graph, prev_node)) { From 18c377f6c71e600870d2ee263cb29275db6afab5 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Sat, 21 Jun 2025 18:35:34 -0400 Subject: [PATCH 10/22] fixed pin location assignment bug --- vpr/src/draw/draw_types.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index 572e38b512..87dc698422 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -156,11 +156,11 @@ ezgl::point2d t_draw_coords::get_absolute_pin_location( const ClusterBlockId clb t_pb_graph_node* pb_gnode = pb_graph_pin->parent_node; ezgl::rectangle pb_bbox = this->get_absolute_pb_bbox(clb_index, pb_gnode); int num_pins = pb_gnode->num_pins(); - int num_pin_in_port = pb_graph_pin->pin_number; - int num_pins_in_port = pb_graph_pin->port->num_pins; - int num_port = pb_graph_pin->port->index; - int num_pin = num_pins_in_port * num_port + num_pin_in_port; + int num_pin = pb_graph_pin->pin_number; + for(int i=0;iport->index; ++i){ + num_pin += pb_gnode->pb_type->ports[i].num_pins; + } float interval = pb_bbox.width() / (num_pins + 1); From 571e50db03f54ef5a7e302134fd955bd0aceb8a5 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Sat, 21 Jun 2025 19:30:57 -0400 Subject: [PATCH 11/22] added arrows --- vpr/src/draw/draw_rr_edges.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index 174fb2f5f3..740dd83545 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -294,6 +294,10 @@ void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::rendere ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id2.first, blk_id_pin_id2.second); g->draw_line(p1, p2); + + float xend = p2.x + (p1.x - p2.x) / 10.; + float yend = p2.y + (p1.y - p2.y) / 10.; + draw_triangle_along_line(g, xend, yend, p1.x, p2.x, p1.y, p2.y); } void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { @@ -305,9 +309,11 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) } const auto& rr_graph = g_vpr_ctx.device().rr_graph; + bool swapped = false; if (!is_inter_cluster_node(rr_graph, inode) && is_inter_cluster_node(rr_graph, prev_node)) { //Swap the nodes so that the inter-cluster node is always the current node std::swap(inode, prev_node); + swapped = true; } auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); @@ -320,7 +326,16 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) continue; } draw_get_rr_pin_coords(inode, &x1, &y1, pin_side); - g->draw_line({x1, y1}, p2); + ezgl::point2d p1 = {x1, y1}; + + if (swapped) { + std::swap(p1, p2); + } + + g->draw_line(p1, p2); + float xend = p2.x + (p1.x - p2.x) / 10.; + float yend = p2.y + (p1.y - p2.y) / 10.; + draw_triangle_along_line(g, xend, yend, p1.x, p2.x, p1.y, p2.y); } } From 0be77464b94ddc6fd1370fec0476329ff9eb72fc Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Sat, 21 Jun 2025 20:28:18 -0400 Subject: [PATCH 12/22] format --- vpr/src/draw/draw_basic.cpp | 14 +++++++------- vpr/src/draw/draw_rr.cpp | 4 ++-- vpr/src/draw/draw_rr_edges.cpp | 6 ++---- vpr/src/draw/draw_searchbar.cpp | 19 +++++++++---------- vpr/src/draw/draw_searchbar.h | 3 +-- vpr/src/draw/draw_types.cpp | 6 +++--- vpr/src/draw/intra_logic_block.cpp | 17 ++++++++--------- vpr/src/util/vpr_utils.cpp | 4 ++-- 8 files changed, 34 insertions(+), 39 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index ab8bced504..ac312afd39 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -627,7 +627,7 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren } // Skip drawing sources and sinks - if (rr_type == e_rr_type::SINK || rr_type == e_rr_type::SOURCE){ + if (rr_type == e_rr_type::SINK || rr_type == e_rr_type::SOURCE) { continue; } @@ -716,8 +716,8 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren } default: { VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } } break; @@ -726,12 +726,12 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren switch (prev_type) { case e_rr_type::CHANX: { draw_chanx_to_chany_edge(prev_node, inode, - FROM_X_TO_Y, switch_type, g); + FROM_X_TO_Y, switch_type, g); break; } case e_rr_type::CHANY: { draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode), - switch_type, g); + switch_type, g); break; } case e_rr_type::OPIN: { @@ -741,8 +741,8 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren } default: { VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } } break; diff --git a/vpr/src/draw/draw_rr.cpp b/vpr/src/draw/draw_rr.cpp index ab3c6cdfdc..6548949a24 100644 --- a/vpr/src/draw/draw_rr.cpp +++ b/vpr/src/draw/draw_rr.cpp @@ -517,7 +517,7 @@ void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); - if(!draw_state->is_flat){ + if (!draw_state->is_flat) { return; } @@ -713,7 +713,7 @@ RRNodeId draw_check_rr_node_hit(float click_x, float click_y) { // Check for intra cluster nodes if (!is_inter_cluster_node(rr_graph, inode)) { - if(!draw_state->is_flat){ + if (!draw_state->is_flat) { continue; } diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index 740dd83545..fc1b12e32e 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -283,7 +283,7 @@ void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::rendere t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); - if(!draw_state->is_flat){ + if (!draw_state->is_flat) { return; } @@ -304,7 +304,7 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); - if(!draw_state->is_flat){ + if (!draw_state->is_flat) { return; } const auto& rr_graph = g_vpr_ctx.device().rr_graph; @@ -319,7 +319,6 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); float x1, y1; ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); - for (const e_side& pin_side : TOTAL_2D_SIDES) { if (!rr_graph.is_node_on_specific_side(RRNodeId(inode), pin_side)) { @@ -337,7 +336,6 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) float yend = p2.y + (p1.y - p2.y) / 10.; draw_triangle_along_line(g, xend, yend, p1.x, p2.x, p1.y, p2.y); } - } void draw_pin_to_pin(RRNodeId opin_node, RRNodeId ipin_node, ezgl::renderer* g) { diff --git a/vpr/src/draw/draw_searchbar.cpp b/vpr/src/draw/draw_searchbar.cpp index 188a411661..e5a1053cb8 100644 --- a/vpr/src/draw/draw_searchbar.cpp +++ b/vpr/src/draw/draw_searchbar.cpp @@ -140,22 +140,21 @@ void highlight_net(char* message, RRNodeId hit_node) { if (route_ctx.route_trees.empty()) return; - if (route_ctx.is_flat){ - for (auto net_id : atom_ctx.netlist().nets()){ + if (route_ctx.is_flat) { + for (auto net_id : atom_ctx.netlist().nets()) { check_node_highlight_net(message, net_id, hit_node); - } + } - } else{ + } else { for (auto net_id : cluster_ctx.clb_nlist.nets()) { check_node_highlight_net(message, net_id, hit_node); } } - + application.update_message(message); } -void check_node_highlight_net(char* message, ParentNetId parent_id, - RRNodeId hit_node) { +void check_node_highlight_net(char* message, ParentNetId parent_id, RRNodeId hit_node) { auto& route_ctx = g_vpr_ctx.routing(); t_draw_state* draw_state = get_draw_state_vars(); @@ -168,8 +167,8 @@ void check_node_highlight_net(char* message, ParentNetId parent_id, draw_state->net_color[parent_id] = draw_state->draw_rr_node[inode].color; if (inode == hit_node) { std::string orig_msg(message); - std::string net_name; - if(!route_ctx.is_flat){ + std::string net_name; + if (!route_ctx.is_flat) { net_name = g_vpr_ctx.clustering().clb_nlist.net_name(convert_to_cluster_net_id(parent_id)); } else { net_name = g_vpr_ctx.atom().netlist().net_name(convert_to_atom_net_id(parent_id)); @@ -179,7 +178,7 @@ void check_node_highlight_net(char* message, ParentNetId parent_id, net_name.c_str()); } } else if (draw_state->draw_rr_node[inode].color - == ezgl::WHITE) { + == ezgl::WHITE) { // If node is de-selected. draw_state->net_color[parent_id] = ezgl::BLACK; break; diff --git a/vpr/src/draw/draw_searchbar.h b/vpr/src/draw/draw_searchbar.h index 4ec24d374e..9603d19962 100644 --- a/vpr/src/draw/draw_searchbar.h +++ b/vpr/src/draw/draw_searchbar.h @@ -31,8 +31,7 @@ void draw_highlight_blocks_color(t_logical_block_type_ptr type, ClusterBlockId b void highlight_net(char* message, RRNodeId hit_node); /* Checks if a node is part of a net, and highlights the net if it is. */ -void check_node_highlight_net(char* message, ParentNetId parent_id, - RRNodeId hit_node); +void check_node_highlight_net(char* message, ParentNetId parent_id, RRNodeId hit_node); /* If an rr_node has been clicked on, it will be either highlighted in MAGENTA, * or de-highlighted in WHITE. If highlighted, and toggle_rr is selected, highlight diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index 87dc698422..fd7203aaad 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -151,20 +151,20 @@ ezgl::rectangle t_draw_coords::get_absolute_pb_bbox(const ClusterBlockId clb_ind return result; } -ezgl::point2d t_draw_coords::get_absolute_pin_location( const ClusterBlockId clb_index,const t_pb_graph_pin* pb_graph_pin) { +ezgl::point2d t_draw_coords::get_absolute_pin_location(const ClusterBlockId clb_index, const t_pb_graph_pin* pb_graph_pin) { t_pb_graph_node* pb_gnode = pb_graph_pin->parent_node; ezgl::rectangle pb_bbox = this->get_absolute_pb_bbox(clb_index, pb_gnode); int num_pins = pb_gnode->num_pins(); int num_pin = pb_graph_pin->pin_number; - for(int i=0;iport->index; ++i){ + for (int i = 0; i < pb_graph_pin->port->index; ++i) { num_pin += pb_gnode->pb_type->ports[i].num_pins; } float interval = pb_bbox.width() / (num_pins + 1); - return ezgl::point2d(interval * (num_pin + 1), -0.01 *this->tile_width) + pb_bbox.top_left(); + return ezgl::point2d(interval * (num_pin + 1), -0.01 * this->tile_width) + pb_bbox.top_left(); } ezgl::rectangle t_draw_coords::get_absolute_clb_bbox(const ClusterBlockId clb_index, const t_logical_block_type_ptr block_type) { diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 47eb5c2152..69ec9d6ac0 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -241,15 +241,15 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p // determine an optimal number of columns int num_columns = 1; - for(int k = 1; k * k <= num_blocks; ++k) { - if(num_blocks % k == 0) { + for (int k = 1; k * k <= num_blocks; ++k) { + if (num_blocks % k == 0) { num_columns = k; } } int num_rows = num_blocks / num_columns; const int MAX_WIDTH_HEIGHT_RATIO = 2; - if(parent_width > parent_height * MAX_WIDTH_HEIGHT_RATIO){ + if (parent_width > parent_height * MAX_WIDTH_HEIGHT_RATIO) { std::swap(num_columns, num_rows); } @@ -287,23 +287,23 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node const float FRACTION_PARENT_PADDING = 0.005; const float FRACTION_CHILD_MARGIN = 0.003; const float FRACTION_TEXT_PADDING = 0.01; - const int MIN_WIDTH_HEIGHT_RATIO = 2; + const int MIN_WIDTH_HEIGHT_RATIO = 2; float abs_parent_padding = tile_width * FRACTION_PARENT_PADDING; float abs_text_padding = tile_width * FRACTION_TEXT_PADDING; float abs_child_margin = tile_width * FRACTION_CHILD_MARGIN; // add safety check to ensure that the dimensions will never be below zero - if (parent_width <= 2* abs_parent_padding || parent_height <= 2 * abs_parent_padding - abs_text_padding) { + if (parent_width <= 2 * abs_parent_padding || parent_height <= 2 * abs_parent_padding - abs_text_padding) { abs_parent_padding = 0; abs_text_padding = 0; } /* Draw all child-level blocks in just most of the space inside their parent block. */ - float parent_drawing_width = parent_width - 2* abs_parent_padding; + float parent_drawing_width = parent_width - 2 * abs_parent_padding; float parent_drawing_height = parent_height - 2 * abs_parent_padding - abs_text_padding; - if(parent_drawing_height > MIN_WIDTH_HEIGHT_RATIO * parent_drawing_width) { + if (parent_drawing_height > MIN_WIDTH_HEIGHT_RATIO * parent_drawing_width) { parent_drawing_height /= 2; } @@ -314,7 +314,7 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node float child_height = parent_drawing_height / num_rows; // add safety check to ensure that the dimensions will never be below zero - if(child_width <= abs_child_margin * 2 || child_height <= abs_child_margin * 2) { + if (child_width <= abs_child_margin * 2 || child_height <= abs_child_margin * 2) { abs_child_margin = 0; } @@ -322,7 +322,6 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node double left = child_width * x_index + abs_parent_padding + abs_child_margin; double bot = child_height * y_index + abs_parent_padding + abs_child_margin; - child_width -= abs_child_margin * 2; child_height -= abs_child_margin * 2; diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index 67987eb44d..b8d012a64b 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -879,7 +879,7 @@ AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin) { atom_pin = pin; } } - + VTR_ASSERT(atom_pin); return atom_pin; @@ -1774,7 +1774,7 @@ std::pair get_rr_node_cluster_blk_id_pb_graph_p ClusterBlockId blk_id = place_ctx.grid_blocks().block_at_location({x, y, sub_tile_num, layer}); VTR_ASSERT(blk_id != ClusterBlockId::INVALID()); - t_pb_graph_pin* pb_graph_pin = physical_tile->pin_num_to_pb_pin.at(pin_physical_num); + t_pb_graph_pin* pb_graph_pin = physical_tile->pin_num_to_pb_pin.at(pin_physical_num); VTR_ASSERT(pb_graph_pin); From 9970b2e19dbb50839179c68c55accd1c182f19f1 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Tue, 24 Jun 2025 13:33:24 -0400 Subject: [PATCH 13/22] swapped arrow directions --- vpr/src/draw/draw_rr_edges.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index fc1b12e32e..d07024055d 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -290,8 +290,8 @@ void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::rendere auto blk_id_pin_id1 = get_rr_node_cluster_blk_id_pb_graph_pin(inode); auto blk_id_pin_id2 = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); - ezgl::point2d p1 = draw_coords->get_absolute_pin_location(blk_id_pin_id1.first, blk_id_pin_id1.second); - ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id2.first, blk_id_pin_id2.second); + ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id1.first, blk_id_pin_id1.second); + ezgl::point2d p1 = draw_coords->get_absolute_pin_location(blk_id_pin_id2.first, blk_id_pin_id2.second); g->draw_line(p1, p2); @@ -327,7 +327,7 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) draw_get_rr_pin_coords(inode, &x1, &y1, pin_side); ezgl::point2d p1 = {x1, y1}; - if (swapped) { + if (!swapped) { std::swap(p1, p2); } From a958d7e44a36fd60e1a760800e659277804edcb4 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Fri, 27 Jun 2025 16:34:10 -0400 Subject: [PATCH 14/22] improved comments and code structure --- vpr/src/draw/draw_basic.cpp | 123 +++++++++++++++-------------- vpr/src/draw/draw_basic.h | 6 ++ vpr/src/draw/draw_rr.cpp | 2 + vpr/src/draw/draw_rr.h | 3 + vpr/src/draw/draw_rr_edges.cpp | 67 +++++++++------- vpr/src/draw/draw_rr_edges.h | 39 +++++++++ vpr/src/draw/draw_searchbar.cpp | 30 +++---- vpr/src/draw/draw_searchbar.h | 25 ++++-- vpr/src/draw/draw_types.cpp | 10 ++- vpr/src/draw/draw_types.h | 5 +- vpr/src/draw/intra_logic_block.cpp | 45 +++++++++-- vpr/src/draw/search_bar.cpp | 6 +- vpr/src/util/vpr_utils.cpp | 10 +-- vpr/src/util/vpr_utils.h | 12 ++- 14 files changed, 257 insertions(+), 126 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index ac312afd39..849f27239d 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -612,7 +612,7 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - // Draw Pins + // Draw RR Nodes for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { RRNodeId inode = rr_nodes_to_draw[i]; auto rr_type = rr_graph.node_type(inode); @@ -637,7 +637,7 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren continue; } - // Draw IO Pins + // Draw cluster-level IO Pins if (rr_type == e_rr_type::OPIN || rr_type == e_rr_type::IPIN) { draw_rr_pin(inode, color, g); continue; @@ -671,7 +671,7 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren continue; } - // Skip drawing sources and sinks + // Skip drawing edges to or from sources and sinks if (rr_type == e_rr_type::SINK || rr_type == e_rr_type::SOURCE || prev_type == e_rr_type::SINK || prev_type == e_rr_type::SOURCE) { continue; } @@ -688,71 +688,78 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren continue; } - auto iedge = find_edge(prev_node, inode); - auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); + draw_inter_cluster_rr_edge(inode, prev_node, rr_type, prev_type, rr_graph, g); - switch (rr_type) { - case e_rr_type::IPIN: { - if (rr_graph.node_type(prev_node) == e_rr_type::OPIN) { - draw_pin_to_pin(prev_node, inode, g); - } else { - draw_pin_to_chan_edge(inode, prev_node, g); - } - break; + } +} + +void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, const RRGraphView& rr_graph, ezgl::renderer* g) { + + auto iedge = find_edge(prev_node, inode); + auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); + + switch (rr_type) { + case e_rr_type::IPIN: { + if (prev_type == e_rr_type::OPIN) { + draw_pin_to_pin(prev_node, inode, g); + } else { + draw_pin_to_chan_edge(inode, prev_node, g); } - case e_rr_type::CHANX: { - switch (prev_type) { - case e_rr_type::CHANX: { - draw_chanx_to_chanx_edge(prev_node, inode, switch_type, g); - break; - } - case e_rr_type::CHANY: { - draw_chanx_to_chany_edge(inode, prev_node, FROM_Y_TO_X, switch_type, g); - break; - } - case e_rr_type::OPIN: { - draw_pin_to_chan_edge(prev_node, inode, g); - break; - } - default: { - VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); - } + break; + } + case e_rr_type::CHANX: { + switch (prev_type) { + case e_rr_type::CHANX: { + draw_chanx_to_chanx_edge(prev_node, inode, switch_type, g); + break; + } + case e_rr_type::CHANY: { + draw_chanx_to_chany_edge(inode, prev_node, FROM_Y_TO_X, switch_type, g); + break; + } + case e_rr_type::OPIN: { + draw_pin_to_chan_edge(prev_node, inode, g); + break; + } + default: { + VPR_ERROR(VPR_ERROR_OTHER, + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } - break; } - case e_rr_type::CHANY: { - switch (prev_type) { - case e_rr_type::CHANX: { - draw_chanx_to_chany_edge(prev_node, inode, - FROM_X_TO_Y, switch_type, g); - break; - } - case e_rr_type::CHANY: { - draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode), - switch_type, g); - break; - } - case e_rr_type::OPIN: { - draw_pin_to_chan_edge(prev_node, inode, g); + break; + } + case e_rr_type::CHANY: { + switch (prev_type) { + case e_rr_type::CHANX: { + draw_chanx_to_chany_edge(prev_node, inode, + FROM_X_TO_Y, switch_type, g); + break; + } + case e_rr_type::CHANY: { + draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode), + switch_type, g); + break; + } + case e_rr_type::OPIN: { + draw_pin_to_chan_edge(prev_node, inode, g); - break; - } - default: { - VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); - } + break; + } + default: { + VPR_ERROR(VPR_ERROR_OTHER, + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } - break; - } - default: { - break; } + break; + } + default: { + break; } } } + /* Helper function that checks whether the edges between the current and previous nodes can be drawn * based on whether the cross-layer connections option is enabled and whether the layer on which the diff --git a/vpr/src/draw/draw_basic.h b/vpr/src/draw/draw_basic.h index 3af8165b9a..fcb93e72e2 100644 --- a/vpr/src/draw/draw_basic.h +++ b/vpr/src/draw/draw_basic.h @@ -57,6 +57,12 @@ void draw_routed_net(ParentNetId net, ezgl::renderer* g); void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::renderer* g); +/** @brief Draws an edge between two rr_nodes, which are both intra-cluster nodes. + * @param inode The current rr_node id + * @param prev_node The previous rr_node id + * @param g The ezgl renderer + */ +void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, const RRGraphView& rr_graph, ezgl::renderer* g); /** * @brief Returns the layer number of a timing path node * @param node diff --git a/vpr/src/draw/draw_rr.cpp b/vpr/src/draw/draw_rr.cpp index 6548949a24..8663110e56 100644 --- a/vpr/src/draw/draw_rr.cpp +++ b/vpr/src/draw/draw_rr.cpp @@ -727,6 +727,8 @@ RRNodeId draw_check_rr_node_hit(float click_x, float click_y) { continue; } + + // Check for inter cluster nodes switch (rr_graph.node_type(inode)) { case e_rr_type::IPIN: case e_rr_type::OPIN: { diff --git a/vpr/src/draw/draw_rr.h b/vpr/src/draw/draw_rr.h index 97eea54e7a..ddbb2a7cbe 100644 --- a/vpr/src/draw/draw_rr.h +++ b/vpr/src/draw/draw_rr.h @@ -27,6 +27,9 @@ void draw_rr_edges(RRNodeId from_node, ezgl::renderer* g); void draw_rr_chan(RRNodeId inode, const ezgl::color color, ezgl::renderer* g); +/** + * @brief Draws the intra-cluster pin for a given RRNodeId when flat routing is enabled. + */ void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); /* Draws an IPIN or OPIN rr_node. Note that the pin can appear on more * than one side of a clb. Also note that this routine can change the diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index d07024055d..7485eb2823 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -287,17 +287,17 @@ void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::rendere return; } - auto blk_id_pin_id1 = get_rr_node_cluster_blk_id_pb_graph_pin(inode); - auto blk_id_pin_id2 = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); + auto [blk_id, pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + auto [prev_blk_id, prev_pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); - ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id1.first, blk_id_pin_id1.second); - ezgl::point2d p1 = draw_coords->get_absolute_pin_location(blk_id_pin_id2.first, blk_id_pin_id2.second); + ezgl::point2d icoord = draw_coords->get_absolute_pin_location(blk_id, pin_id); + ezgl::point2d prev_coord = draw_coords->get_absolute_pin_location(prev_blk_id, prev_pin_id); - g->draw_line(p1, p2); + g->draw_line(prev_coord, icoord); - float xend = p2.x + (p1.x - p2.x) / 10.; - float yend = p2.y + (p1.y - p2.y) / 10.; - draw_triangle_along_line(g, xend, yend, p1.x, p2.x, p1.y, p2.y); + float triangle_coord_x = icoord.x + (prev_coord.x - icoord.x) / 10.; + float triangle_coord_y = icoord.y + (prev_coord.y - icoord.y) / 10.; + draw_triangle_along_line(g, triangle_coord_x, triangle_coord_y, prev_coord.x, icoord.x, prev_coord.y, icoord.y); } void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { @@ -307,35 +307,44 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) if (!draw_state->is_flat) { return; } + const auto& rr_graph = g_vpr_ctx.device().rr_graph; - bool swapped = false; - if (!is_inter_cluster_node(rr_graph, inode) && is_inter_cluster_node(rr_graph, prev_node)) { - //Swap the nodes so that the inter-cluster node is always the current node - std::swap(inode, prev_node); - swapped = true; - } + ezgl::point2d prev_coord, icoord; + float temp_x, temp_y; // temporary variables to hold coordinates to cast into ezgl::point2d - auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); - float x1, y1; - ezgl::point2d p2 = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); + // get the location of the nodes based on whether inode is an inter-cluster or intra-cluster pin. + if (!is_inter_cluster_node(rr_graph, inode)) { - for (const e_side& pin_side : TOTAL_2D_SIDES) { - if (!rr_graph.is_node_on_specific_side(RRNodeId(inode), pin_side)) { - continue; - } - draw_get_rr_pin_coords(inode, &x1, &y1, pin_side); - ezgl::point2d p1 = {x1, y1}; + auto [blk_id, pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + icoord = draw_coords->get_absolute_pin_location(blk_id, pin_id); - if (!swapped) { - std::swap(p1, p2); + for (const e_side& pin_side : TOTAL_2D_SIDES) { + if (!rr_graph.is_node_on_specific_side(RRNodeId(prev_node), pin_side)) { + continue; + } + draw_get_rr_pin_coords(prev_node, &temp_x, &temp_y, pin_side); + prev_coord = {temp_x, temp_y}; } + } else { + + auto [prev_blk_id, prev_pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); + prev_coord = draw_coords->get_absolute_pin_location(prev_blk_id, prev_pin_id); - g->draw_line(p1, p2); - float xend = p2.x + (p1.x - p2.x) / 10.; - float yend = p2.y + (p1.y - p2.y) / 10.; - draw_triangle_along_line(g, xend, yend, p1.x, p2.x, p1.y, p2.y); + for (const e_side& pin_side : TOTAL_2D_SIDES) { + if (!rr_graph.is_node_on_specific_side(RRNodeId(inode), pin_side)) { + continue; + } + draw_get_rr_pin_coords(inode, &temp_x, &temp_y, pin_side); + icoord = {temp_x, temp_y}; + } } + + g->draw_line(prev_coord, icoord); + float triangle_coord_x = icoord.x + (prev_coord.x - icoord.x) / 10.; + float triangle_coord_y = icoord.y + (prev_coord.y - icoord.y) / 10.; + draw_triangle_along_line(g, triangle_coord_x, triangle_coord_y, prev_coord.x, icoord.x, prev_coord.y, icoord.y); + } void draw_pin_to_pin(RRNodeId opin_node, RRNodeId ipin_node, ezgl::renderer* g) { diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index 72339bdf5e..63275eaf58 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -17,14 +17,53 @@ #include "ezgl/graphics.hpp" +/** + * @brief Draws the edge between two vertical channel nodes + */ void draw_chany_to_chany_edge(RRNodeId from_node, RRNodeId to_node, short switch_type, ezgl::renderer* g); + +/** + * @brief Draws the edge between two horizontal channel nodes + */ void draw_chanx_to_chanx_edge(RRNodeId from_node, RRNodeId to_node, short switch_type, ezgl::renderer* g); + +/** + * @brief Draws the edge between a horizontal channel node and a vertical channel node + * @param chanx_node The horizontal channel node + * @param chany_node The vertical channel node + * @param edge_dir The direction of the edge, FROM_X_TO_Y or FROM_Y_TO_X + * @param switch_type The type of switch used for the connection + * @param g The ezgl renderer + */ void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_edge_dir edge_dir, short switch_type, ezgl::renderer* g); + +/** + * @brief Draws the edge between an intra-cluster pin and a pin when flat routing is enabled. It does not matter whether prev_node is the intra-cluster pin or whether inode is the intra-cluster pin. + * @param inode The current node to draw to + * @param prev_node The previous node to draw from + * @param g The ezgl renderer + */ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); +/** + * @brief Draws the edge between two intra-cluster pins when flat routing is enabled. + * @param inode The current node to draw to + * @param prev_node The previous node to draw from + * @param g The ezgl renderer + */ void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); + +/** + * @brief This routine directly draws an edge from an inter-cluster output pin to an inter-cluster input pin. + */ void draw_pin_to_pin(RRNodeId opin, RRNodeId ipin, ezgl::renderer* g); + +//TODO: These two functions currently do not draw correctly after rearranging the block locations. They need an update. void draw_pin_to_sink(RRNodeId ipin_node, RRNodeId sink_node, ezgl::renderer* g); void draw_source_to_pin(RRNodeId source_node, RRNodeId opin_node, ezgl::renderer* g); + +/** + * @brief Draws an edge from a inter-cluster pin node to a channel node (CHANX or CHANY). + */ void draw_pin_to_chan_edge(RRNodeId pin_node, RRNodeId chan_node, ezgl::renderer* g); #endif /* NO_GRAPHICS */ diff --git a/vpr/src/draw/draw_searchbar.cpp b/vpr/src/draw/draw_searchbar.cpp index e5a1053cb8..200ec2bb6f 100644 --- a/vpr/src/draw/draw_searchbar.cpp +++ b/vpr/src/draw/draw_searchbar.cpp @@ -131,7 +131,7 @@ void draw_highlight_blocks_color(t_logical_block_type_ptr type, /* If an rr_node has been clicked on, it will be highlighted in MAGENTA. * If so, and toggle nets is selected, highlight the whole net in that colour. */ -void highlight_net(char* message, RRNodeId hit_node) { +void highlight_nets(char* message, RRNodeId hit_node) { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& atom_ctx = g_vpr_ctx.atom(); auto& route_ctx = g_vpr_ctx.routing(); @@ -154,33 +154,35 @@ void highlight_net(char* message, RRNodeId hit_node) { application.update_message(message); } -void check_node_highlight_net(char* message, ParentNetId parent_id, RRNodeId hit_node) { +std::string draw_get_net_name(ParentNetId parent_id) { + if (!g_vpr_ctx.routing().is_flat) { + return g_vpr_ctx.clustering().clb_nlist.net_name(convert_to_cluster_net_id(parent_id)); + } else { + return g_vpr_ctx.atom().netlist().net_name(convert_to_atom_net_id(parent_id)); + } +} + +void check_node_highlight_net(char* message, ParentNetId parent_net_id, RRNodeId hit_node) { auto& route_ctx = g_vpr_ctx.routing(); t_draw_state* draw_state = get_draw_state_vars(); - if (!route_ctx.route_trees[parent_id]) + if (!route_ctx.route_trees[parent_net_id]) return; - for (auto& rt_node : route_ctx.route_trees[parent_id].value().all_nodes()) { + for (auto& rt_node : route_ctx.route_trees[parent_net_id].value().all_nodes()) { RRNodeId inode = rt_node.inode; if (draw_state->draw_rr_node[inode].color == ezgl::MAGENTA) { - draw_state->net_color[parent_id] = draw_state->draw_rr_node[inode].color; + draw_state->net_color[parent_net_id] = draw_state->draw_rr_node[inode].color; if (inode == hit_node) { std::string orig_msg(message); - std::string net_name; - if (!route_ctx.is_flat) { - net_name = g_vpr_ctx.clustering().clb_nlist.net_name(convert_to_cluster_net_id(parent_id)); - } else { - net_name = g_vpr_ctx.atom().netlist().net_name(convert_to_atom_net_id(parent_id)); - } sprintf(message, "%s || Net: %zu (%s)", orig_msg.c_str(), - size_t(parent_id), - net_name.c_str()); + size_t(parent_net_id), + draw_get_net_name(parent_net_id).c_str()); } } else if (draw_state->draw_rr_node[inode].color == ezgl::WHITE) { // If node is de-selected. - draw_state->net_color[parent_id] = ezgl::BLACK; + draw_state->net_color[parent_net_id] = ezgl::BLACK; break; } } diff --git a/vpr/src/draw/draw_searchbar.h b/vpr/src/draw/draw_searchbar.h index 9603d19962..359639a7b1 100644 --- a/vpr/src/draw/draw_searchbar.h +++ b/vpr/src/draw/draw_searchbar.h @@ -26,12 +26,27 @@ ezgl::rectangle draw_get_rr_chan_bbox(RRNodeId inode); /* Highlights a block and its fanout/fanin. */ void draw_highlight_blocks_color(t_logical_block_type_ptr type, ClusterBlockId blk_id); -/* If an rr_node has been clicked on, it will be highlighted in MAGENTA. - * If so, and toggle nets is selected, highlight the whole net in that colour.*/ -void highlight_net(char* message, RRNodeId hit_node); -/* Checks if a node is part of a net, and highlights the net if it is. */ -void check_node_highlight_net(char* message, ParentNetId parent_id, RRNodeId hit_node); +/** + * @brief Highlights the net associated with the specified RRNodeId in Magenta. De-highlights all other nets. Also appends relevant net information to the provided message char pointer. + * + * @param message A message which we want to update by appending additional net information. + * @param hit_node The RRNodeId of the routing resource node whose net should be highlighted. + */ +void highlight_nets(char* message, RRNodeId hit_node); + +/** + * @brief Returns the name of the net associated with a ParentNetId. + */ +std::string draw_get_net_name(ParentNetId parent_id); + +/** + * @brief Determines if a given RRNode is part of the specified net and highlights the net if so. Additionally, appends relevant net information to the provided message char pointer. + * @param message Pointer to a character array where additional net information will be appended. + * @param parent_net_id The ParentNetId representing the net to check. This may refer to either atom or cluster nets. + * @param hit_node The RRNodeId of the node that was selected. + */ +void check_node_highlight_net(char* message, ParentNetId parent_net_id, RRNodeId hit_node); /* If an rr_node has been clicked on, it will be either highlighted in MAGENTA, * or de-highlighted in WHITE. If highlighted, and toggle_rr is selected, highlight diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index fd7203aaad..dc7247aa9d 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -152,19 +152,25 @@ ezgl::rectangle t_draw_coords::get_absolute_pb_bbox(const ClusterBlockId clb_ind } ezgl::point2d t_draw_coords::get_absolute_pin_location(const ClusterBlockId clb_index, const t_pb_graph_pin* pb_graph_pin) { + // Pins are positioned on a horizontal row at the top of each internal block. t_pb_graph_node* pb_gnode = pb_graph_pin->parent_node; ezgl::rectangle pb_bbox = this->get_absolute_pb_bbox(clb_index, pb_gnode); - int num_pins = pb_gnode->num_pins(); + // Calculate the pin location based on the pin number and the total number of pins in the block. + int num_pins = pb_gnode->num_pins(); int num_pin = pb_graph_pin->pin_number; for (int i = 0; i < pb_graph_pin->port->index; ++i) { num_pin += pb_gnode->pb_type->ports[i].num_pins; } + // horizontal spacing between pins float interval = pb_bbox.width() / (num_pins + 1); - return ezgl::point2d(interval * (num_pin + 1), -0.01 * this->tile_width) + pb_bbox.top_left(); + // vertical spacing between pins and top edge of the block + const float Y_PIN_OFFSET = 0.01; + + return ezgl::point2d(interval * (num_pin + 1), -Y_PIN_OFFSET * this->tile_width) + pb_bbox.top_left(); } ezgl::rectangle t_draw_coords::get_absolute_clb_bbox(const ClusterBlockId clb_index, const t_logical_block_type_ptr block_type) { diff --git a/vpr/src/draw/draw_types.h b/vpr/src/draw/draw_types.h index f8d9a2d278..7f006e23ea 100644 --- a/vpr/src/draw/draw_types.h +++ b/vpr/src/draw/draw_types.h @@ -433,7 +433,10 @@ struct t_draw_coords { ezgl::rectangle get_absolute_pb_bbox(const ClusterBlockId clb_index, const t_pb_graph_node* pb_gnode); /** - * @brief returns a 2D point for the absolute location of the given pb_graph_pin + * @brief returns a 2D point for the absolute location of the given pb_graph_pin in the entire graphics context. + * @param clb_index The index of the cluster block containing the pin. + * @param pb_graph_pin The pin for which the absolute location is requested. + * @return A point2d representing the absolute coordinates of the pin. */ ezgl::point2d get_absolute_pin_location(const ClusterBlockId clb_index, const t_pb_graph_pin* pb_graph_pin); diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 69ec9d6ac0..4e3499a577 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -36,9 +36,34 @@ /************************* Subroutines local to this file. *******************************/ +/** + * @brief A recursive function which traverses through each sub-block of a pb_graph_node, calculates bounding boxes for each sub-block, and stores the bounding boxes in the global draw_coords variable. + * @param type_descrip_index The index of the logical block type. + * @param pb_graph_node The pb_graph_node. + * @param parent_width The width of the parent block. + * @param parent_height The height of the parent block. + */ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height); + +/** + * @brief Finds the maximum depth of sub-blocks for a given pb_type. + * @param pb_type The top-level pb_type. + * @return The maximum level for the given pb_type. + */ static int draw_internal_find_max_lvl(const t_pb_type& pb_type); -static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height); +/** + * @brief A helper function for draw_internal_load_coords. Calculates the coordinates of a internal block and stores its bounding box inside global variables. The calculated width and height of the block are also assigned to the pointers blk_width and blk_height. + * @param type_descrip_index The index of the logical block type. + * @param pb_graph_node The pb_graph_node of the logical block type. + * @param blk_num Each logical block type has num_modes * num_pb_type_children sub-blocks. blk_num is the index of the sub-block within the logical block type. + * @param num_columns Number of columns of blocks to draw in the parent block type. + * @param num_rows Number of rows of blocks to draw in the parent block type. + * @param parent_width The width of the parent block. + * @param parent_height The height of the parent block. + * @param blk_width Pointer to store the calculated width of the block. + * @param blk_height Pointer to store the calculated height of the block. + */ +static void draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int blk_num, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height); std::vector collect_pb_atoms(const t_pb* pb); void collect_pb_atoms_recurr(const t_pb* pb, std::vector& atoms); t_pb* highlight_sub_block_helper(const ClusterBlockId clb_index, t_pb* pb, const ezgl::point2d& local_pt, int max_depth); @@ -237,9 +262,11 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p /* Find the number of instances for each child pb_type. */ int num_pb = mode.pb_type_children[j].num_pb; + // Determine how we want to arrange the sub-blocks in the parent block. We want the blocks to be squarish, and not too wide or too tall. In other words, we want the number of rows to be as close to the number of columns as possible such that num_rows * num_columns = num_blocks. + int num_blocks = num_pb * num_children; - // determine an optimal number of columns + // determine central factor for the number of columns int num_columns = 1; for (int k = 1; k * k <= num_blocks; ++k) { if (num_blocks % k == 0) { @@ -247,7 +274,9 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p } } int num_rows = num_blocks / num_columns; + // Currently num_rows >= num_columns + // If blocks are too wide, swap num_rows and num_columns, so that num_rows <= num_columns. const int MAX_WIDTH_HEIGHT_RATIO = 2; if (parent_width > parent_height * MAX_WIDTH_HEIGHT_RATIO) { std::swap(num_columns, num_rows); @@ -255,12 +284,12 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p for (int k = 0; k < num_pb; ++k) { - int num_block = j * num_pb + k; + int blk_num = j * num_pb + k; /* Compute bound box for block. Don't call if pb_type is root-level pb. */ draw_internal_calc_coords(type_descrip_index, &pb_graph_node->child_pb_graph_nodes[i][j][k], - num_block, num_columns, num_rows, + blk_num, num_columns, num_rows, parent_width, parent_height, &blk_width, &blk_height); @@ -277,7 +306,7 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p * are relative to the left and bottom corner of the parent block. */ static void -draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int num_block, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height) { +draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, int blk_num, int num_columns, int num_rows, float parent_width, float parent_height, float* blk_width, float* blk_height) { // get the bbox for this pb type ezgl::rectangle& pb_bbox = get_draw_coords_vars()->blk_info.at(type_descrip_index).get_pb_bbox_ref(*pb_graph_node); @@ -299,7 +328,7 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node abs_text_padding = 0; } - /* Draw all child-level blocks in just most of the space inside their parent block. */ + /* Draw all child-level blocks using most of the space inside their parent block. */ float parent_drawing_width = parent_width - 2 * abs_parent_padding; float parent_drawing_height = parent_height - 2 * abs_parent_padding - abs_text_padding; @@ -307,8 +336,8 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node parent_drawing_height /= 2; } - int x_index = num_block % num_columns; - int y_index = num_block / num_columns; + int x_index = blk_num % num_columns; + int y_index = blk_num / num_columns; float child_width = parent_drawing_width / num_columns; float child_height = parent_drawing_height / num_rows; diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 74414b6048..173f63be4a 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -247,9 +247,9 @@ bool highlight_rr_nodes(RRNodeId hit_node) { } if (draw_state->show_nets) - highlight_net(message, hit_node); - else - application.update_message(message); + highlight_nets(message, hit_node); + + application.update_message(message); application.refresh_drawing(); return true; diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index b8d012a64b..a1ae77dbee 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -857,8 +857,7 @@ t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(const t_model_ports* m return nullptr; } -//Retrieves the atom pin associated with a specific CLB and pb_graph_pin -// Warning: Not all pb_graph_pins are associated with an atom pin! + AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin) { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& atom_ctx = g_vpr_ctx.atom(); @@ -1782,12 +1781,13 @@ std::pair get_rr_node_cluster_blk_id_pb_graph_p } AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id) { - ClusterBlockId blk_id; - t_pb_graph_pin* pb_graph_pin; - std::tie(blk_id, pb_graph_pin) = get_rr_node_cluster_blk_id_pb_graph_pin(rr_node_id); + + auto [blk_id, pb_graph_pin] = get_rr_node_cluster_blk_id_pb_graph_pin(rr_node_id); AtomPinId atom_pin_id = find_atom_pin(blk_id, pb_graph_pin); + VTR_ASSERT_SAFE(atom_pin_id != AtomPinId::INVALID()); + return atom_pin_id; } diff --git a/vpr/src/util/vpr_utils.h b/vpr/src/util/vpr_utils.h index a294e7d286..0817743530 100644 --- a/vpr/src/util/vpr_utils.h +++ b/vpr/src/util/vpr_utils.h @@ -166,6 +166,9 @@ const t_pb_graph_pin* find_pb_graph_pin(const t_pb_graph_node* pb_gnode, const s const t_pb_graph_pin* find_pb_graph_pin(const AtomNetlist& netlist, const AtomPBBimap& atom_pb_lookup, const AtomPinId pin_id); +/** + * @brief Retrieves the atom pin associated with a specific CLB and pb_graph_pin. Warning: Not all pb_graph_pins are associated with an atom pin! Only pb_graph_pins on primatives are associated with an AtomPinId. + */ AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin); //Returns the logical block type which is most common in the device grid @@ -258,16 +261,23 @@ RRNodeId get_atom_pin_rr_node_id(AtomPinId atom_pin_id); /** * @brief Returns the cluster block ID and pb_graph_pin for the given RR node ID. + * @note Use structured bindings for clarity: + * ```cpp + * auto [blk_id, pb_graph_pin] = get_rr_node_cluster_blk_id_pb_graph_pin ( ... ); + * ``` * **Warning**: This function should be called only if flat-router is enabled, * since, otherwise, the routing resources inside clusters are not added to the RR graph. * @param rr_node_id The RR node ID. + * @return A pair containing the ClusterBlockId and the corresponding t_pb_graph_pin pointer. */ std::pair get_rr_node_cluster_blk_id_pb_graph_pin(RRNodeId rr_node_id); /** * @brief Returns the atom pin ID for the given RR node ID. * **Warning**: This function should be called only if flat-router is enabled, - * since, otherwise, the routing resources inside clusters are not added to the RR graph. Also, not all RRNodes have an AtomPinId associated with them. + * since, otherwise, the routing resources inside clusters are not added to the RR graph. + * Not all RRNodes have an AtomPinId associated with them. + * See also: find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin). * @param rr_node_id The RR node ID. */ AtomPinId get_rr_node_atom_pin_id(RRNodeId rr_node_id); From 11d01c06ba9d18db7d8db4e836194632fb56328c Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Fri, 27 Jun 2025 16:54:30 -0400 Subject: [PATCH 15/22] renamed certain variables for clarity --- vpr/src/draw/draw_basic.cpp | 32 ++++++++++++++---------------- vpr/src/draw/draw_rr.cpp | 12 +++++------ vpr/src/draw/draw_rr.h | 4 ++-- vpr/src/draw/draw_rr_edges.cpp | 5 ++--- vpr/src/draw/draw_rr_edges.h | 4 ++-- vpr/src/draw/draw_searchbar.h | 1 - vpr/src/draw/draw_types.cpp | 2 +- vpr/src/draw/intra_logic_block.cpp | 13 ++++++------ vpr/src/draw/search_bar.cpp | 2 +- vpr/src/util/vpr_utils.cpp | 1 - 10 files changed, 36 insertions(+), 40 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index 849f27239d..b8f59a0b4d 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -357,7 +357,7 @@ void draw_congestion(ezgl::renderer* g) { case e_rr_type::IPIN: //fallthrough case e_rr_type::OPIN: - draw_rr_pin(inode, color, g); + draw_cluster_pin(inode, color, g); break; default: break; @@ -633,13 +633,13 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren // Draw intra-cluster nodes if (!is_inode_inter_cluster) { - draw_rr_intrapin(inode, color, g); + draw_rr_intra_cluster_pin(inode, color, g); continue; } // Draw cluster-level IO Pins if (rr_type == e_rr_type::OPIN || rr_type == e_rr_type::IPIN) { - draw_rr_pin(inode, color, g); + draw_cluster_pin(inode, color, g); continue; } @@ -655,12 +655,12 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren RRNodeId inode = rr_nodes_to_draw[i]; auto rr_type = rr_graph.node_type(inode); - bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); + bool inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); int current_node_layer = rr_graph.node_layer(inode); RRNodeId prev_node = rr_nodes_to_draw[i - 1]; auto prev_type = rr_graph.node_type(RRNodeId(prev_node)); - bool is_prev_node_inter_cluster = is_inter_cluster_node(rr_graph, prev_node); + bool prev_node_inter_cluster = is_inter_cluster_node(rr_graph, prev_node); int prev_node_layer = rr_graph.node_layer(prev_node); t_draw_layer_display edge_visibility = get_element_visibility_and_transparency(prev_node_layer, current_node_layer); @@ -678,18 +678,17 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren g->set_color(color, edge_visibility.alpha); - if (!is_inode_inter_cluster && !is_prev_node_inter_cluster) { - draw_intrapin_to_intrapin(inode, prev_node, g); + if (!inode_inter_cluster && !prev_node_inter_cluster) { + draw_intra_cluster_edge(inode, prev_node, g); continue; } - if (!is_inode_inter_cluster || !is_prev_node_inter_cluster) { - draw_intrapin_to_pin(inode, prev_node, g); + if (!inode_inter_cluster || !prev_node_inter_cluster) { + draw_intra_cluster_pin_to_pin(inode, prev_node, g); continue; } draw_inter_cluster_rr_edge(inode, prev_node, rr_type, prev_type, rr_graph, g); - } } @@ -723,8 +722,8 @@ void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr } default: { VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } } break; @@ -733,12 +732,12 @@ void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr switch (prev_type) { case e_rr_type::CHANX: { draw_chanx_to_chany_edge(prev_node, inode, - FROM_X_TO_Y, switch_type, g); + FROM_X_TO_Y, switch_type, g); break; } case e_rr_type::CHANY: { draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode), - switch_type, g); + switch_type, g); break; } case e_rr_type::OPIN: { @@ -748,8 +747,8 @@ void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr } default: { VPR_ERROR(VPR_ERROR_OTHER, - "Unexpected connection from an rr_node of type %d to one of type %d.\n", - prev_type, rr_type); + "Unexpected connection from an rr_node of type %d to one of type %d.\n", + prev_type, rr_type); } } break; @@ -759,7 +758,6 @@ void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr } } } - /* Helper function that checks whether the edges between the current and previous nodes can be drawn * based on whether the cross-layer connections option is enabled and whether the layer on which the diff --git a/vpr/src/draw/draw_rr.cpp b/vpr/src/draw/draw_rr.cpp index 8663110e56..656f48ace5 100644 --- a/vpr/src/draw/draw_rr.cpp +++ b/vpr/src/draw/draw_rr.cpp @@ -107,12 +107,12 @@ void draw_rr(ezgl::renderer* g) { break; case e_rr_type::IPIN: - draw_rr_pin(inode, draw_state->draw_rr_node[inode].color, g); + draw_cluster_pin(inode, draw_state->draw_rr_node[inode].color, g); draw_rr_edges(inode, g); break; case e_rr_type::OPIN: - draw_rr_pin(inode, draw_state->draw_rr_node[inode].color, g); + draw_cluster_pin(inode, draw_state->draw_rr_node[inode].color, g); draw_rr_edges(inode, g); break; @@ -513,7 +513,7 @@ void draw_rr_edges(RRNodeId inode, ezgl::renderer* g) { } /* End of for each edge loop */ } -void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g) { +void draw_rr_intra_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); @@ -536,7 +536,7 @@ void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* /* Draws an IPIN or OPIN rr_node. Note that the pin can appear on more * * than one side of a clb. Also note that this routine can change the * * current color to BLACK. */ -void draw_rr_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g) { +void draw_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g) { t_draw_coords* draw_coords = get_draw_coords_vars(); float xcen, ycen; @@ -866,11 +866,11 @@ void draw_rr_costs(ezgl::renderer* g, const vtr::vector& rr_cos break; case e_rr_type::IPIN: //fallthrough - draw_rr_pin(inode, color, g); + draw_cluster_pin(inode, color, g); if (with_edges) draw_rr_edges(inode, g); break; case e_rr_type::OPIN: - draw_rr_pin(inode, color, g); + draw_cluster_pin(inode, color, g); if (with_edges) draw_rr_edges(inode, g); break; case e_rr_type::SOURCE: diff --git a/vpr/src/draw/draw_rr.h b/vpr/src/draw/draw_rr.h index ddbb2a7cbe..381b446d31 100644 --- a/vpr/src/draw/draw_rr.h +++ b/vpr/src/draw/draw_rr.h @@ -30,11 +30,11 @@ void draw_rr_chan(RRNodeId inode, const ezgl::color color, ezgl::renderer* g); /** * @brief Draws the intra-cluster pin for a given RRNodeId when flat routing is enabled. */ -void draw_rr_intrapin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); +void draw_rr_intra_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); /* Draws an IPIN or OPIN rr_node. Note that the pin can appear on more * than one side of a clb. Also note that this routine can change the * current color to BLACK. */ -void draw_rr_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); +void draw_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); void draw_rr_src_sink(RRNodeId inode, ezgl::color color, ezgl::renderer* g); void draw_get_rr_src_sink_coords(const t_rr_node& node, float* xcen, float* ycen); diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index 7485eb2823..046c1b497e 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -279,7 +279,7 @@ void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_e } } -void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { +void draw_intra_cluster_edge(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); @@ -300,7 +300,7 @@ void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::rendere draw_triangle_along_line(g, triangle_coord_x, triangle_coord_y, prev_coord.x, icoord.x, prev_coord.y, icoord.y); } -void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { +void draw_intra_cluster_pin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); @@ -344,7 +344,6 @@ void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) float triangle_coord_x = icoord.x + (prev_coord.x - icoord.x) / 10.; float triangle_coord_y = icoord.y + (prev_coord.y - icoord.y) / 10.; draw_triangle_along_line(g, triangle_coord_x, triangle_coord_y, prev_coord.x, icoord.x, prev_coord.y, icoord.y); - } void draw_pin_to_pin(RRNodeId opin_node, RRNodeId ipin_node, ezgl::renderer* g) { diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index 63275eaf58..bd5b95a6ad 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -43,14 +43,14 @@ void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_e * @param prev_node The previous node to draw from * @param g The ezgl renderer */ -void draw_intrapin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); +void draw_intra_cluster_pin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); /** * @brief Draws the edge between two intra-cluster pins when flat routing is enabled. * @param inode The current node to draw to * @param prev_node The previous node to draw from * @param g The ezgl renderer */ -void draw_intrapin_to_intrapin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); +void draw_intra_cluster_edge(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); /** * @brief This routine directly draws an edge from an inter-cluster output pin to an inter-cluster input pin. diff --git a/vpr/src/draw/draw_searchbar.h b/vpr/src/draw/draw_searchbar.h index 359639a7b1..59582ee529 100644 --- a/vpr/src/draw/draw_searchbar.h +++ b/vpr/src/draw/draw_searchbar.h @@ -26,7 +26,6 @@ ezgl::rectangle draw_get_rr_chan_bbox(RRNodeId inode); /* Highlights a block and its fanout/fanin. */ void draw_highlight_blocks_color(t_logical_block_type_ptr type, ClusterBlockId blk_id); - /** * @brief Highlights the net associated with the specified RRNodeId in Magenta. De-highlights all other nets. Also appends relevant net information to the provided message char pointer. * diff --git a/vpr/src/draw/draw_types.cpp b/vpr/src/draw/draw_types.cpp index dc7247aa9d..76d52fbe59 100644 --- a/vpr/src/draw/draw_types.cpp +++ b/vpr/src/draw/draw_types.cpp @@ -152,7 +152,7 @@ ezgl::rectangle t_draw_coords::get_absolute_pb_bbox(const ClusterBlockId clb_ind } ezgl::point2d t_draw_coords::get_absolute_pin_location(const ClusterBlockId clb_index, const t_pb_graph_pin* pb_graph_pin) { - // Pins are positioned on a horizontal row at the top of each internal block. + // Pins are positioned on a horizontal row at the top of each internal block. t_pb_graph_node* pb_gnode = pb_graph_pin->parent_node; ezgl::rectangle pb_bbox = this->get_absolute_pb_bbox(clb_index, pb_gnode); diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 4e3499a577..82b27af52f 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -34,6 +34,8 @@ #include "draw.h" #include "draw_triangle.h" +constexpr float FRACTION_TEXT_PADDING = 0.01; + /************************* Subroutines local to this file. *******************************/ /** @@ -262,7 +264,7 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p /* Find the number of instances for each child pb_type. */ int num_pb = mode.pb_type_children[j].num_pb; - // Determine how we want to arrange the sub-blocks in the parent block. We want the blocks to be squarish, and not too wide or too tall. In other words, we want the number of rows to be as close to the number of columns as possible such that num_rows * num_columns = num_blocks. + // Determine how we want to arrange the sub-blocks in the parent block. We want the blocks to be squarish, and not too wide or too tall. In other words, we want the number of rows to be as close to the number of columns as possible such that num_rows * num_columns = num_blocks. int num_blocks = num_pb * num_children; @@ -313,10 +315,9 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node float tile_width = get_draw_coords_vars()->get_tile_width(); - const float FRACTION_PARENT_PADDING = 0.005; - const float FRACTION_CHILD_MARGIN = 0.003; - const float FRACTION_TEXT_PADDING = 0.01; - const int MIN_WIDTH_HEIGHT_RATIO = 2; + constexpr float FRACTION_PARENT_PADDING = 0.005; + constexpr float FRACTION_CHILD_MARGIN = 0.003; + constexpr int MIN_WIDTH_HEIGHT_RATIO = 2; float abs_parent_padding = tile_width * FRACTION_PARENT_PADDING; float abs_text_padding = tile_width * FRACTION_TEXT_PADDING; @@ -445,7 +446,7 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg if (draw_state->draw_block_text) { g->draw_text( ezgl::point2d(abs_bbox.center_x(), - abs_bbox.top() - draw_coords->get_tile_height() * 0.01), + abs_bbox.top() - draw_coords->get_tile_height() * FRACTION_TEXT_PADDING), pb_type->name, abs_bbox.width(), abs_bbox.height()); diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 173f63be4a..6bc729b79f 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -248,7 +248,7 @@ bool highlight_rr_nodes(RRNodeId hit_node) { if (draw_state->show_nets) highlight_nets(message, hit_node); - + application.update_message(message); application.refresh_drawing(); diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index a1ae77dbee..d52982fd66 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -857,7 +857,6 @@ t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(const t_model_ports* m return nullptr; } - AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin) { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& atom_ctx = g_vpr_ctx.atom(); From 4d5a52240c1d0be009f43226e358d4126e6a7ef8 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Fri, 27 Jun 2025 17:19:51 -0400 Subject: [PATCH 16/22] changed pb name display --- vpr/src/draw/intra_logic_block.cpp | 59 ++++++++++++++---------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 82b27af52f..0dfafcdd6d 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -421,43 +421,38 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg /// then draw text /// - if (pb->name != nullptr) { - g->set_font_size(16); // note: calc_text_xbound(...) assumes this is 16 - if (pb_type->depth == draw_state->show_blk_internal || pb->child_pbs == nullptr) { - // If this pb is at the lowest displayed level, or has no more children, then - // label it in the center with its type and name - - std::string pb_type_name(pb_type->name); - std::string pb_name(pb->name); - - std::string blk_tag = pb_type_name + pb_name; - - if (draw_state->draw_block_text) { - g->draw_text( - abs_bbox.center(), - blk_tag.c_str(), - abs_bbox.width(), - abs_bbox.height()); - } + std::string pb_type_name(pb_type->name); - } else { - // else (ie. has chilren, and isn't at the lowest displayed level) - // just label its type, and put it up at the top so we can see it - if (draw_state->draw_block_text) { - g->draw_text( - ezgl::point2d(abs_bbox.center_x(), - abs_bbox.top() - draw_coords->get_tile_height() * FRACTION_TEXT_PADDING), - pb_type->name, - abs_bbox.width(), - abs_bbox.height()); - } + pb_type_name += "[" + std::to_string(pb->pb_graph_node->placement_index) + "]"; + + //get the mode of the physical block + if (!pb->is_primitive()) { + // primitives have no modes + std::string mode_name = pb->pb_graph_node->pb_type->modes[pb->mode].name; + pb_type_name += "[" + mode_name + "]"; + } + + g->set_font_size(16); // note: calc_text_xbound(...) assumes this is 16 + if (pb_type->depth == draw_state->show_blk_internal || pb->child_pbs == nullptr) { + // If this pb is at the lowest displayed level, or has no more children, then + // label it in the center with its type and name + + if (draw_state->draw_block_text) { + g->draw_text( + abs_bbox.center(), + pb_type_name.c_str(), + abs_bbox.width(), + abs_bbox.height()); } + } else { - // If child block is not used, label it only by its type + // else (ie. has chilren, and isn't at the lowest displayed level) + // just label its type, and put it up at the top so we can see it if (draw_state->draw_block_text) { g->draw_text( - abs_bbox.center(), - pb_type->name, + ezgl::point2d(abs_bbox.center_x(), + abs_bbox.top() - draw_coords->get_tile_height() * FRACTION_TEXT_PADDING), + pb_type_name.c_str(), abs_bbox.width(), abs_bbox.height()); } From ea61183767ef1bc02330d0f588e4ba918f52e627 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Wed, 2 Jul 2025 17:10:25 -0400 Subject: [PATCH 17/22] updated comments and fixed block drawing issue --- vpr/src/draw/draw_rr_edges.h | 2 +- vpr/src/draw/intra_logic_block.cpp | 67 ++++++++++++++++++------------ vpr/src/util/vpr_utils.cpp | 4 +- vpr/src/util/vpr_utils.h | 2 +- 4 files changed, 44 insertions(+), 31 deletions(-) diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index bd5b95a6ad..776192e5da 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -38,7 +38,7 @@ void draw_chanx_to_chanx_edge(RRNodeId from_node, RRNodeId to_node, short switch void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_edge_dir edge_dir, short switch_type, ezgl::renderer* g); /** - * @brief Draws the edge between an intra-cluster pin and a pin when flat routing is enabled. It does not matter whether prev_node is the intra-cluster pin or whether inode is the intra-cluster pin. + * @brief Draws the edge between an intra-cluster pin and an inter-cluster pin when flat routing is enabled. It does not matter whether prev_node is the intra-cluster pin or whether inode is the intra-cluster pin. * @param inode The current node to draw to * @param prev_node The previous node to draw from * @param g The ezgl renderer diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 0dfafcdd6d..06e6da49b2 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -34,6 +34,7 @@ #include "draw.h" #include "draw_triangle.h" +// Vertical padding (as a fraction of tile height) added to leave space for text inside internal logic blocks constexpr float FRACTION_TEXT_PADDING = 0.01; /************************* Subroutines local to this file. *******************************/ @@ -54,7 +55,15 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p */ static int draw_internal_find_max_lvl(const t_pb_type& pb_type); /** - * @brief A helper function for draw_internal_load_coords. Calculates the coordinates of a internal block and stores its bounding box inside global variables. The calculated width and height of the block are also assigned to the pointers blk_width and blk_height. + * @brief A helper function to calculate the number of child blocks for a given t_mode. + * @param mode The mode of the parent pb_type. + * @return The number of child blocks for the given t_mode. + */ +static int get_num_child_blocks(const t_mode& mode); +/** + * @brief A helper function for draw_internal_load_coords. + * Calculates the coordinates of a internal block and stores its bounding box inside global variables. + * The calculated width and height of the block are also assigned to the pointers blk_width and blk_height. * @param type_descrip_index The index of the logical block type. * @param pb_graph_node The pb_graph_node of the logical block type. * @param blk_num Each logical block type has num_modes * num_pb_type_children sub-blocks. blk_num is the index of the sub-block within the logical block type. @@ -241,6 +250,15 @@ static int draw_internal_find_max_lvl(const t_pb_type& pb_type) { return max_levels; } +static int get_num_child_blocks(const t_mode& mode) { + // not all child_pb_types have the same number of physical blocks, so we have to manually loop through and count the physical blocks + int num_blocks = 0; + for (int j=0;jmodes[i]; int num_children = mode.num_pb_type_children; + int num_blocks = get_num_child_blocks(mode); + int blk_num = 0; for (int j = 0; j < num_children; ++j) { - /* Find the number of instances for each child pb_type. */ + // Find the number of instances for each child pb_type. int num_pb = mode.pb_type_children[j].num_pb; - // Determine how we want to arrange the sub-blocks in the parent block. We want the blocks to be squarish, and not too wide or too tall. In other words, we want the number of rows to be as close to the number of columns as possible such that num_rows * num_columns = num_blocks. - - int num_blocks = num_pb * num_children; - - // determine central factor for the number of columns + // Determine how we want to arrange the sub-blocks in the parent block. + // We want the blocks to be squarish, and not too wide or too tall. + // In other words, we want the number of rows to be as close to the number of columns as possible such that + // num_rows * num_columns = num_blocks. + // first, determine the "middle" factor for the number of columns int num_columns = 1; for (int k = 1; k * k <= num_blocks; ++k) { if (num_blocks % k == 0) { @@ -286,19 +306,19 @@ static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* p for (int k = 0; k < num_pb; ++k) { - int blk_num = j * num_pb + k; - - /* Compute bound box for block. Don't call if pb_type is root-level pb. */ + // Compute bound box for block. Don't call if pb_type is root-level pb. draw_internal_calc_coords(type_descrip_index, &pb_graph_node->child_pb_graph_nodes[i][j][k], blk_num, num_columns, num_rows, parent_width, parent_height, &blk_width, &blk_height); - /* Traverse to next level in the pb_graph */ + // Traverse to next level in the pb_graph draw_internal_load_coords(type_descrip_index, &pb_graph_node->child_pb_graph_nodes[i][j][k], blk_width, blk_height); + + blk_num++; } } } @@ -317,7 +337,6 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node constexpr float FRACTION_PARENT_PADDING = 0.005; constexpr float FRACTION_CHILD_MARGIN = 0.003; - constexpr int MIN_WIDTH_HEIGHT_RATIO = 2; float abs_parent_padding = tile_width * FRACTION_PARENT_PADDING; float abs_text_padding = tile_width * FRACTION_TEXT_PADDING; @@ -333,10 +352,6 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node float parent_drawing_width = parent_width - 2 * abs_parent_padding; float parent_drawing_height = parent_height - 2 * abs_parent_padding - abs_text_padding; - if (parent_drawing_height > MIN_WIDTH_HEIGHT_RATIO * parent_drawing_width) { - parent_drawing_height /= 2; - } - int x_index = blk_num % num_columns; int y_index = blk_num / num_columns; @@ -348,7 +363,7 @@ draw_internal_calc_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node abs_child_margin = 0; } - /* The starting point to draw the physical block. */ + // The starting point to draw the physical block. double left = child_width * x_index + abs_parent_padding + abs_child_margin; double bot = child_height * y_index + abs_parent_padding + abs_child_margin; @@ -389,7 +404,7 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg return; } - /// first draw box /// + // first draw box if (pb->name != nullptr) { // If block is used, draw it in colour with solid border. @@ -419,20 +434,20 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg g->draw_rectangle(abs_bbox); } - /// then draw text /// - + // draw text for each physical block. + // format: :[] std::string pb_type_name(pb_type->name); - pb_type_name += "[" + std::to_string(pb->pb_graph_node->placement_index) + "]"; - - //get the mode of the physical block + // get the mode of the physical block if (!pb->is_primitive()) { // primitives have no modes std::string mode_name = pb->pb_graph_node->pb_type->modes[pb->mode].name; - pb_type_name += "[" + mode_name + "]"; + pb_type_name += ":" + mode_name; } - g->set_font_size(16); // note: calc_text_xbound(...) assumes this is 16 + pb_type_name += "[" + std::to_string(pb->pb_graph_node->placement_index) + "]"; + + g->set_font_size(16); if (pb_type->depth == draw_state->show_blk_internal || pb->child_pbs == nullptr) { // If this pb is at the lowest displayed level, or has no more children, then // label it in the center with its type and name @@ -458,7 +473,7 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg } } - /// now recurse on the child pbs. /// + // now recurse on the child pbs. // return if no children, or this is an unusused pb, // or if going down will be too far down (this one is redundant, but for optimazition) diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index d52982fd66..c1f79b4e63 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -865,7 +865,7 @@ AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin) { AtomNetId atom_net = cluster_ctx.clb_nlist.block_pb(blk_id)->pb_route[pb_route_id].atom_net_id; VTR_ASSERT(atom_net); - AtomPinId atom_pin; + AtomPinId atom_pin = AtomPinId::INVALID(); //Look through all the pins on this net, looking for the matching pin for (AtomPinId pin : atom_ctx.netlist().net_pins(atom_net)) { @@ -878,8 +878,6 @@ AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin) { } } - VTR_ASSERT(atom_pin); - return atom_pin; } diff --git a/vpr/src/util/vpr_utils.h b/vpr/src/util/vpr_utils.h index 0817743530..9fa6df0f46 100644 --- a/vpr/src/util/vpr_utils.h +++ b/vpr/src/util/vpr_utils.h @@ -167,7 +167,7 @@ const t_pb_graph_pin* find_pb_graph_pin(const t_pb_graph_node* pb_gnode, const s const t_pb_graph_pin* find_pb_graph_pin(const AtomNetlist& netlist, const AtomPBBimap& atom_pb_lookup, const AtomPinId pin_id); /** - * @brief Retrieves the atom pin associated with a specific CLB and pb_graph_pin. Warning: Not all pb_graph_pins are associated with an atom pin! Only pb_graph_pins on primatives are associated with an AtomPinId. + * @brief Retrieves the atom pin associated with a specific CLB and pb_graph_pin. Warning: Not all pb_graph_pins are associated with an atom pin! Only pb_graph_pins on primatives are associated with an AtomPinId. Returns AtomPinId::INVALID() if no atom pin is found. */ AtomPinId find_atom_pin(ClusterBlockId blk_id, const t_pb_graph_pin* pb_gpin); From 850a0e60ded5fba52459d7d6e019cc1f6a347140 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Thu, 3 Jul 2025 13:03:42 -0400 Subject: [PATCH 18/22] fixed incorrect pin side issue --- vpr/src/draw/draw_basic.cpp | 23 ++++++++- vpr/src/draw/draw_rr_edges.cpp | 78 ++++++++++++++++-------------- vpr/src/draw/draw_rr_edges.h | 19 ++++++-- vpr/src/draw/draw_types.h | 11 +++-- vpr/src/draw/intra_logic_block.cpp | 10 ++-- 5 files changed, 90 insertions(+), 51 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index b8f59a0b4d..3e8a12fea6 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -683,8 +683,27 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren continue; } - if (!inode_inter_cluster || !prev_node_inter_cluster) { - draw_intra_cluster_pin_to_pin(inode, prev_node, g); + // Default side for pin in case none can be found + e_side pin_side = e_side::TOP; + if (!prev_node_inter_cluster && inode_inter_cluster) { + // draw intra-cluster pin to inter-cluster pin + // node i + 1 is the channel node + if (i + 1 < rr_nodes_to_draw.size()) { + pin_side = get_pin_side(inode, rr_nodes_to_draw[i + 1]); + } + + draw_intra_cluster_pin_to_pin(prev_node, inode, FROM_INTRA_CLUSTER_TO_INTER_CLUSTER, pin_side, g); + continue; + } + + if (prev_node_inter_cluster && !inode_inter_cluster) { + // draw inter-cluster pin to intra-cluster pin + // node i - 2 is the channel node + if (i >= 2) { + pin_side = get_pin_side(prev_node, rr_nodes_to_draw[i - 2]); + } + + draw_intra_cluster_pin_to_pin(inode, prev_node, FROM_INTER_CLUSTER_TO_INTRA_CLUSTER, pin_side, g); continue; } diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index 046c1b497e..eef034e872 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -205,7 +205,7 @@ void draw_chanx_to_chanx_edge(RRNodeId from_node, RRNodeId to_node, short switch } } -void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_edge_dir edge_dir, short switch_type, ezgl::renderer* g) { +void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_chan_edge_dir edge_dir, short switch_type, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); auto& device_ctx = g_vpr_ctx.device(); @@ -300,7 +300,7 @@ void draw_intra_cluster_edge(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* draw_triangle_along_line(g, triangle_coord_x, triangle_coord_y, prev_coord.x, icoord.x, prev_coord.y, icoord.y); } -void draw_intra_cluster_pin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g) { +void draw_intra_cluster_pin_to_pin(RRNodeId intra_cluster_node, RRNodeId inter_cluster_node, e_pin_edge_dir pin_edge_dir, e_side pin_side, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); @@ -308,36 +308,25 @@ void draw_intra_cluster_pin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::ren return; } - const auto& rr_graph = g_vpr_ctx.device().rr_graph; + // determine the location of the pins + float inter_cluster_x, inter_cluster_y; + ezgl::point2d intra_cluster_coord; - ezgl::point2d prev_coord, icoord; - float temp_x, temp_y; // temporary variables to hold coordinates to cast into ezgl::point2d - - // get the location of the nodes based on whether inode is an inter-cluster or intra-cluster pin. - if (!is_inter_cluster_node(rr_graph, inode)) { + draw_get_rr_pin_coords(inter_cluster_node, &inter_cluster_x, &inter_cluster_y, pin_side); - auto [blk_id, pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(inode); - icoord = draw_coords->get_absolute_pin_location(blk_id, pin_id); + auto [blk_id, pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(intra_cluster_node); + intra_cluster_coord = draw_coords->get_absolute_pin_location(blk_id, pin_id); - for (const e_side& pin_side : TOTAL_2D_SIDES) { - if (!rr_graph.is_node_on_specific_side(RRNodeId(prev_node), pin_side)) { - continue; - } - draw_get_rr_pin_coords(prev_node, &temp_x, &temp_y, pin_side); - prev_coord = {temp_x, temp_y}; - } + // determine which coord is first based on the pin edge direction + ezgl::point2d prev_coord, icoord; + if (pin_edge_dir == FROM_INTRA_CLUSTER_TO_INTER_CLUSTER) { + prev_coord = intra_cluster_coord; + icoord = {inter_cluster_x, inter_cluster_y}; + } else if (pin_edge_dir == FROM_INTER_CLUSTER_TO_INTRA_CLUSTER) { + prev_coord = {inter_cluster_x, inter_cluster_y}; + icoord = intra_cluster_coord; } else { - - auto [prev_blk_id, prev_pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(prev_node); - prev_coord = draw_coords->get_absolute_pin_location(prev_blk_id, prev_pin_id); - - for (const e_side& pin_side : TOTAL_2D_SIDES) { - if (!rr_graph.is_node_on_specific_side(RRNodeId(inode), pin_side)) { - continue; - } - draw_get_rr_pin_coords(inode, &temp_x, &temp_y, pin_side); - icoord = {temp_x, temp_y}; - } + VPR_ERROR(VPR_ERROR_DRAW, "Invalid pin edge direction: %d", pin_edge_dir); } g->draw_line(prev_coord, icoord); @@ -433,14 +422,8 @@ void draw_source_to_pin(RRNodeId source_node, RRNodeId opin_node, ezgl::renderer } } -void draw_pin_to_chan_edge(RRNodeId pin_node, RRNodeId chan_node, ezgl::renderer* g) { - /* This routine draws an edge from the pin_node to the chan_node (CHANX or * - * CHANY). The connection is made to the nearest end of the track instead * - * of perpendicular to the track to symbolize a single-drive connection. */ - - /* TODO: Fix this for global routing, currently for detailed only */ +e_side get_pin_side(RRNodeId pin_node, RRNodeId chan_node) { - t_draw_coords* draw_coords = get_draw_coords_vars(); auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; @@ -453,7 +436,6 @@ void draw_pin_to_chan_edge(RRNodeId pin_node, RRNodeId chan_node, ezgl::renderer int width_offset = device_ctx.grid.get_width_offset(tile_loc); int height_offset = device_ctx.grid.get_height_offset(tile_loc); - float x1 = 0, y1 = 0; /* If there is only one side, no need for the following inference!!! * When a node may have multiple sides, * we lack direct information about which side of the node drives the channel node @@ -521,6 +503,30 @@ void draw_pin_to_chan_edge(RRNodeId pin_node, RRNodeId chan_node, ezgl::renderer /* Sanity check */ VTR_ASSERT(NUM_2D_SIDES != pin_side); + return pin_side; +} + +void draw_pin_to_chan_edge(RRNodeId pin_node, RRNodeId chan_node, ezgl::renderer* g) { + /* This routine draws an edge from the pin_node to the chan_node (CHANX or * + * CHANY). The connection is made to the nearest end of the track instead * + * of perpendicular to the track to symbolize a single-drive connection. */ + + /* TODO: Fix this for global routing, currently for detailed only */ + + t_draw_coords* draw_coords = get_draw_coords_vars(); + auto& device_ctx = g_vpr_ctx.device(); + const auto& rr_graph = device_ctx.rr_graph; + + t_physical_tile_loc tile_loc = { + rr_graph.node_xlow(pin_node), + rr_graph.node_ylow(pin_node), + rr_graph.node_layer(pin_node)}; + + const auto& grid_type = device_ctx.grid.get_physical_type(tile_loc); + const e_rr_type channel_type = rr_graph.node_type(chan_node); + e_side pin_side = get_pin_side(pin_node, chan_node); + + float x1 = 0, y1 = 0; /* Now we determine which side to be used, calculate the offset for the pin to be drawn * - For the pin locates above/right to the grid (at the top/right side), * a positive offset (+ve) is required diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index 776192e5da..649fb33066 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -35,15 +35,17 @@ void draw_chanx_to_chanx_edge(RRNodeId from_node, RRNodeId to_node, short switch * @param switch_type The type of switch used for the connection * @param g The ezgl renderer */ -void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_edge_dir edge_dir, short switch_type, ezgl::renderer* g); +void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_chan_edge_dir edge_dir, short switch_type, ezgl::renderer* g); /** - * @brief Draws the edge between an intra-cluster pin and an inter-cluster pin when flat routing is enabled. It does not matter whether prev_node is the intra-cluster pin or whether inode is the intra-cluster pin. - * @param inode The current node to draw to - * @param prev_node The previous node to draw from + * @brief Draws the edge between an intra-cluster pin and an inter-cluster pin when flat routing is enabled. + * @param intra_cluster_node The intra-cluster pin node + * @param inter_cluster_node The inter-cluster pin node + * @param pin_edge_dir The direction of the edge, FROM_INTER_CLUSTER_TO_INTRA_CLUSTER or FROM_INTRA_CLUSTER_TO_INTER_CLUSTER + * @param pin_side The side of the inter-cluster pin (e.g. TOP, RIGHT, BOTTOM, LEFT) * @param g The ezgl renderer */ -void draw_intra_cluster_pin_to_pin(RRNodeId inode, RRNodeId prev_node, ezgl::renderer* g); +void draw_intra_cluster_pin_to_pin(RRNodeId intra_cluster_node, RRNodeId inter_cluster_node, e_pin_edge_dir pin_edge_dir, e_side pin_side, ezgl::renderer* g); /** * @brief Draws the edge between two intra-cluster pins when flat routing is enabled. * @param inode The current node to draw to @@ -61,6 +63,13 @@ void draw_pin_to_pin(RRNodeId opin, RRNodeId ipin, ezgl::renderer* g); void draw_pin_to_sink(RRNodeId ipin_node, RRNodeId sink_node, ezgl::renderer* g); void draw_source_to_pin(RRNodeId source_node, RRNodeId opin_node, ezgl::renderer* g); +/** + * @brief Determines the side of clb, the inter-cluster pin is located on based on the channel node. + * @param pin_node The inter-cluster pin node + * @param chan_node The channel node (CHANX or CHANY) that the pin is connected to + * @return The side of the clb that the pin is located on (e.g. TOP, RIGHT, BOTTOM, LEFT) + */ +e_side get_pin_side(RRNodeId pin_node, RRNodeId chan_node); /** * @brief Draws an edge from a inter-cluster pin node to a channel node (CHANX or CHANY). */ diff --git a/vpr/src/draw/draw_types.h b/vpr/src/draw/draw_types.h index 7f006e23ea..ed6f46946f 100644 --- a/vpr/src/draw/draw_types.h +++ b/vpr/src/draw/draw_types.h @@ -109,13 +109,18 @@ enum e_draw_net_type { ALL_NETS, HIGHLIGHTED }; - -/* Chanx to chany or vice versa? */ -enum e_edge_dir { +/// Chanx to chany or vice versa? +enum e_chan_edge_dir { FROM_X_TO_Y, FROM_Y_TO_X }; +/// From inter-cluster pin to intra-cluster pin or vice versa? +enum e_pin_edge_dir { + FROM_INTER_CLUSTER_TO_INTRA_CLUSTER, + FROM_INTRA_CLUSTER_TO_INTER_CLUSTER +}; + /* * Defines the type of drawings that can be generated for the NoC. * DRAW_NO_NOC -> user did not select the option to draw the NoC diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index 06e6da49b2..fcbe18f12c 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -253,7 +253,7 @@ static int draw_internal_find_max_lvl(const t_pb_type& pb_type) { static int get_num_child_blocks(const t_mode& mode) { // not all child_pb_types have the same number of physical blocks, so we have to manually loop through and count the physical blocks int num_blocks = 0; - for (int j=0;jchild_pb_graph_nodes[i][j][k], blk_width, blk_height); - + blk_num++; } } From 4f34f40481e2e385afb7c13ff450d893558ab11b Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Thu, 3 Jul 2025 14:30:53 -0400 Subject: [PATCH 19/22] coding style changes --- vpr/src/draw/draw_basic.cpp | 12 ++++++------ vpr/src/draw/draw_basic.h | 3 ++- vpr/src/draw/draw_rr.cpp | 8 ++++---- vpr/src/draw/draw_rr.h | 3 +++ vpr/src/draw/draw_rr_edges.h | 3 +++ vpr/src/draw/draw_searchbar.cpp | 11 +++++------ vpr/src/draw/draw_types.h | 1 + 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index 3e8a12fea6..ecd956f54d 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -615,7 +615,7 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren // Draw RR Nodes for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { RRNodeId inode = rr_nodes_to_draw[i]; - auto rr_type = rr_graph.node_type(inode); + e_rr_type rr_type = rr_graph.node_type(inode); bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); int node_layer = rr_graph.node_layer(inode); @@ -707,14 +707,14 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::ren continue; } - draw_inter_cluster_rr_edge(inode, prev_node, rr_type, prev_type, rr_graph, g); + draw_inter_cluster_rr_edge(inode, prev_node, rr_type, prev_type, g); } } -void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, const RRGraphView& rr_graph, ezgl::renderer* g) { - - auto iedge = find_edge(prev_node, inode); - auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); +void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, ezgl::renderer* g) { + const RRGraphView& rr_graph = g_vpr_ctx.device().rr_graph; + t_edge_size iedge = find_edge(prev_node, inode); + short switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge); switch (rr_type) { case e_rr_type::IPIN: { diff --git a/vpr/src/draw/draw_basic.h b/vpr/src/draw/draw_basic.h index fcb93e72e2..cad390861a 100644 --- a/vpr/src/draw/draw_basic.h +++ b/vpr/src/draw/draw_basic.h @@ -62,7 +62,8 @@ void draw_partial_route(const std::vector& rr_nodes_to_draw, * @param prev_node The previous rr_node id * @param g The ezgl renderer */ -void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, const RRGraphView& rr_graph, ezgl::renderer* g); +void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, ezgl::renderer* g); + /** * @brief Returns the layer number of a timing path node * @param node diff --git a/vpr/src/draw/draw_rr.cpp b/vpr/src/draw/draw_rr.cpp index 656f48ace5..eca0b5b017 100644 --- a/vpr/src/draw/draw_rr.cpp +++ b/vpr/src/draw/draw_rr.cpp @@ -521,9 +521,9 @@ void draw_rr_intra_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::r return; } - auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + auto [blk_id, pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(inode); - ezgl::point2d p = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); + ezgl::point2d p = draw_coords->get_absolute_pin_location(blk_id, pin_id); int transparency_factor = get_rr_node_transparency(inode); @@ -717,8 +717,8 @@ RRNodeId draw_check_rr_node_hit(float click_x, float click_y) { continue; } - auto blk_id_pin_id = get_rr_node_cluster_blk_id_pb_graph_pin(inode); - ezgl::point2d p = draw_coords->get_absolute_pin_location(blk_id_pin_id.first, blk_id_pin_id.second); + auto [blk_id, pin_id] = get_rr_node_cluster_blk_id_pb_graph_pin(inode); + ezgl::point2d p = draw_coords->get_absolute_pin_location(blk_id, pin_id); if (click_x >= p.x - draw_coords->pin_size && click_x <= p.x + draw_coords->pin_size && click_y >= p.y - draw_coords->pin_size && click_y <= p.y + draw_coords->pin_size) { hit_node = inode; diff --git a/vpr/src/draw/draw_rr.h b/vpr/src/draw/draw_rr.h index 381b446d31..805352b951 100644 --- a/vpr/src/draw/draw_rr.h +++ b/vpr/src/draw/draw_rr.h @@ -31,18 +31,21 @@ void draw_rr_chan(RRNodeId inode, const ezgl::color color, ezgl::renderer* g); * @brief Draws the intra-cluster pin for a given RRNodeId when flat routing is enabled. */ void draw_rr_intra_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); + /* Draws an IPIN or OPIN rr_node. Note that the pin can appear on more * than one side of a clb. Also note that this routine can change the * current color to BLACK. */ void draw_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g); void draw_rr_src_sink(RRNodeId inode, ezgl::color color, ezgl::renderer* g); + void draw_get_rr_src_sink_coords(const t_rr_node& node, float* xcen, float* ycen); /* Draws a buffer (triangle) or pass transistor (circle) on the edge * connecting from to to, depending on the status of buffered. The drawing * is closest to the from_node, since it reflects the switch type of from. */ void draw_rr_switch(float from_x, float from_y, float to_x, float to_y, bool buffered, bool switch_configurable, ezgl::renderer* g); + void draw_expand_non_configurable_rr_nodes_recurr(RRNodeId from_node, std::set& expanded_nodes); diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index 649fb33066..fcfb4370c1 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -46,6 +46,7 @@ void draw_chanx_to_chany_edge(RRNodeId chanx_node, RRNodeId chany_node, enum e_c * @param g The ezgl renderer */ void draw_intra_cluster_pin_to_pin(RRNodeId intra_cluster_node, RRNodeId inter_cluster_node, e_pin_edge_dir pin_edge_dir, e_side pin_side, ezgl::renderer* g); + /** * @brief Draws the edge between two intra-cluster pins when flat routing is enabled. * @param inode The current node to draw to @@ -61,6 +62,7 @@ void draw_pin_to_pin(RRNodeId opin, RRNodeId ipin, ezgl::renderer* g); //TODO: These two functions currently do not draw correctly after rearranging the block locations. They need an update. void draw_pin_to_sink(RRNodeId ipin_node, RRNodeId sink_node, ezgl::renderer* g); + void draw_source_to_pin(RRNodeId source_node, RRNodeId opin_node, ezgl::renderer* g); /** @@ -70,6 +72,7 @@ void draw_source_to_pin(RRNodeId source_node, RRNodeId opin_node, ezgl::renderer * @return The side of the clb that the pin is located on (e.g. TOP, RIGHT, BOTTOM, LEFT) */ e_side get_pin_side(RRNodeId pin_node, RRNodeId chan_node); + /** * @brief Draws an edge from a inter-cluster pin node to a channel node (CHANX or CHANY). */ diff --git a/vpr/src/draw/draw_searchbar.cpp b/vpr/src/draw/draw_searchbar.cpp index 200ec2bb6f..49ccddd275 100644 --- a/vpr/src/draw/draw_searchbar.cpp +++ b/vpr/src/draw/draw_searchbar.cpp @@ -136,17 +136,17 @@ void highlight_nets(char* message, RRNodeId hit_node) { auto& atom_ctx = g_vpr_ctx.atom(); auto& route_ctx = g_vpr_ctx.routing(); - /* Don't crash if there's no routing */ + // Don't crash if there's no routing if (route_ctx.route_trees.empty()) return; if (route_ctx.is_flat) { - for (auto net_id : atom_ctx.netlist().nets()) { + for (AtomNetId net_id : atom_ctx.netlist().nets()) { check_node_highlight_net(message, net_id, hit_node); } } else { - for (auto net_id : cluster_ctx.clb_nlist.nets()) { + for (ClusterNetId net_id : cluster_ctx.clb_nlist.nets()) { check_node_highlight_net(message, net_id, hit_node); } } @@ -169,7 +169,7 @@ void check_node_highlight_net(char* message, ParentNetId parent_net_id, RRNodeId if (!route_ctx.route_trees[parent_net_id]) return; - for (auto& rt_node : route_ctx.route_trees[parent_net_id].value().all_nodes()) { + for (RouteTreeNode& rt_node : route_ctx.route_trees[parent_net_id].value().all_nodes()) { RRNodeId inode = rt_node.inode; if (draw_state->draw_rr_node[inode].color == ezgl::MAGENTA) { draw_state->net_color[parent_net_id] = draw_state->draw_rr_node[inode].color; @@ -179,8 +179,7 @@ void check_node_highlight_net(char* message, ParentNetId parent_net_id, RRNodeId size_t(parent_net_id), draw_get_net_name(parent_net_id).c_str()); } - } else if (draw_state->draw_rr_node[inode].color - == ezgl::WHITE) { + } else if (draw_state->draw_rr_node[inode].color == ezgl::WHITE) { // If node is de-selected. draw_state->net_color[parent_net_id] = ezgl::BLACK; break; diff --git a/vpr/src/draw/draw_types.h b/vpr/src/draw/draw_types.h index ed6f46946f..e7106a5107 100644 --- a/vpr/src/draw/draw_types.h +++ b/vpr/src/draw/draw_types.h @@ -109,6 +109,7 @@ enum e_draw_net_type { ALL_NETS, HIGHLIGHTED }; + /// Chanx to chany or vice versa? enum e_chan_edge_dir { FROM_X_TO_Y, From 5df4c550304365beaf8d2ef7a857bfd2e5062f61 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Thu, 3 Jul 2025 15:18:37 -0400 Subject: [PATCH 20/22] build error fix --- vpr/src/draw/draw_searchbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpr/src/draw/draw_searchbar.cpp b/vpr/src/draw/draw_searchbar.cpp index 49ccddd275..cb04be62ee 100644 --- a/vpr/src/draw/draw_searchbar.cpp +++ b/vpr/src/draw/draw_searchbar.cpp @@ -169,7 +169,7 @@ void check_node_highlight_net(char* message, ParentNetId parent_net_id, RRNodeId if (!route_ctx.route_trees[parent_net_id]) return; - for (RouteTreeNode& rt_node : route_ctx.route_trees[parent_net_id].value().all_nodes()) { + for (const RouteTreeNode& rt_node : route_ctx.route_trees[parent_net_id].value().all_nodes()) { RRNodeId inode = rt_node.inode; if (draw_state->draw_rr_node[inode].color == ezgl::MAGENTA) { draw_state->net_color[parent_net_id] = draw_state->draw_rr_node[inode].color; From 06bd0a24edbfc177127c56eecfe2cd3d2f1d6b86 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Mon, 7 Jul 2025 16:05:59 -0400 Subject: [PATCH 21/22] updated pb text display --- vpr/src/draw/intra_logic_block.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index fcbe18f12c..ab1dd3326a 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -434,19 +434,22 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg g->draw_rectangle(abs_bbox); } - // draw text for each physical block. - // format: :[] + // Display text for each physical block. std::string pb_type_name(pb_type->name); - // get the mode of the physical block if (!pb->is_primitive()) { - // primitives have no modes + // Format for non-primitives: []: + pb_type_name += "[" + std::to_string(pb->pb_graph_node->placement_index) + "]"; std::string mode_name = pb->pb_graph_node->pb_type->modes[pb->mode].name; pb_type_name += ":" + mode_name; + } else { + // Format for primitives: () + if (pb->name != nullptr) { + std::string pb_name(pb->name); + pb_type_name += "(" + pb_name + ")"; + } } - pb_type_name += "[" + std::to_string(pb->pb_graph_node->placement_index) + "]"; - g->set_font_size(16); if (pb_type->depth == draw_state->show_blk_internal || pb->child_pbs == nullptr) { // If this pb is at the lowest displayed level, or has no more children, then From b9f09dba5a50f97bf23f0368e25c497a2e72fc34 Mon Sep 17 00:00:00 2001 From: SamuelHo10 Date: Mon, 7 Jul 2025 16:20:34 -0400 Subject: [PATCH 22/22] dont display mode if its the same as type name --- vpr/src/draw/intra_logic_block.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index ab1dd3326a..7450f1279a 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -435,18 +435,23 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg } // Display text for each physical block. + std::string pb_display_text(pb_type->name); std::string pb_type_name(pb_type->name); if (!pb->is_primitive()) { // Format for non-primitives: []: - pb_type_name += "[" + std::to_string(pb->pb_graph_node->placement_index) + "]"; std::string mode_name = pb->pb_graph_node->pb_type->modes[pb->mode].name; - pb_type_name += ":" + mode_name; + pb_display_text += "[" + std::to_string(pb->pb_graph_node->placement_index) + "]"; + + // Don't display mode name if it is the same as the pb_type name + if (mode_name != pb_type_name) { + pb_display_text += ":" + mode_name; + } } else { // Format for primitives: () if (pb->name != nullptr) { std::string pb_name(pb->name); - pb_type_name += "(" + pb_name + ")"; + pb_display_text += "(" + pb_name + ")"; } } @@ -458,7 +463,7 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg if (draw_state->draw_block_text) { g->draw_text( abs_bbox.center(), - pb_type_name.c_str(), + pb_display_text.c_str(), abs_bbox.width(), abs_bbox.height()); } @@ -470,7 +475,7 @@ static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* pb, const ezg g->draw_text( ezgl::point2d(abs_bbox.center_x(), abs_bbox.top() - draw_coords->get_tile_height() * FRACTION_TEXT_PADDING), - pb_type_name.c_str(), + pb_display_text.c_str(), abs_bbox.width(), abs_bbox.height()); }