diff --git a/vpr/src/base/read_blif.cpp b/vpr/src/base/read_blif.cpp index 3342a5ca558..a5ff28710ba 100644 --- a/vpr/src/base/read_blif.cpp +++ b/vpr/src/base/read_blif.cpp @@ -538,9 +538,9 @@ struct BlifAllocCallback : public blifparse::Callback { bool verify_blackbox_model(AtomNetlist& blif_model) { LogicalModelId arch_model_id = models_.get_model_by_name(blif_model.netlist_name()); - if(!arch_model_id.is_valid()) { + if (!arch_model_id.is_valid()) { vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "BLIF model '%s' has no equivalent architecture model.", - blif_model.netlist_name().c_str()); + blif_model.netlist_name().c_str()); } const t_model& arch_model = models_.get_model(arch_model_id); diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index ecd956f54d2..ed8a41cd146 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -609,172 +609,21 @@ 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(); - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; // Draw RR Nodes for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) { RRNodeId inode = rr_nodes_to_draw[i]; - 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); - 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_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_cluster_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_rr_node(inode, color, g); } // 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 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 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); - ezgl::color color = draw_state->draw_rr_node[inode].color; - - // For 3D architectures, draw only visible layers - if (!draw_state->draw_layer_display[current_node_layer].visible || !edge_visibility.visible) { - continue; - } - - // 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; - } - - g->set_color(color, edge_visibility.alpha); - - if (!inode_inter_cluster && !prev_node_inter_cluster) { - draw_intra_cluster_edge(inode, prev_node, g); - continue; - } - // 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; - } - - 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, 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: { - 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); - } - 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; - } - 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; - } + draw_rr_edge(inode, prev_node, draw_state->draw_rr_node[inode].color, g); } } diff --git a/vpr/src/draw/draw_basic.h b/vpr/src/draw/draw_basic.h index cad390861ae..3af8165b9a8 100644 --- a/vpr/src/draw/draw_basic.h +++ b/vpr/src/draw/draw_basic.h @@ -57,13 +57,6 @@ 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, 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 eca0b5b0176..542c2f5061d 100644 --- a/vpr/src/draw/draw_rr.cpp +++ b/vpr/src/draw/draw_rr.cpp @@ -55,8 +55,6 @@ void draw_rr(ezgl::renderer* g) { g->set_line_dash(ezgl::line_dash::none); for (const RRNodeId inode : device_ctx.rr_graph.nodes()) { - int layer_num = rr_graph.node_layer(inode); - int transparency_factor = get_rr_node_transparency(inode); if (!draw_state->draw_rr_node[inode].node_highlighted) { /* If not highlighted node, assign color based on type. */ switch (rr_graph.node_type(inode)) { @@ -68,7 +66,7 @@ void draw_rr(ezgl::renderer* g) { draw_state->draw_rr_node[inode].color = ezgl::PINK; break; case e_rr_type::IPIN: - draw_state->draw_rr_node[inode].color = blk_LIGHTSKYBLUE; + draw_state->draw_rr_node[inode].color = ezgl::PURPLE; break; case e_rr_type::SOURCE: draw_state->draw_rr_node[inode].color = ezgl::PLUM; @@ -81,45 +79,8 @@ void draw_rr(ezgl::renderer* g) { } } - draw_state->draw_rr_node[inode].color.alpha = transparency_factor; - - if (!draw_state->draw_layer_display[layer_num].visible) - continue; // skip drawing if layer is not visible - - /* Now call drawing routines to draw the node. */ - switch (rr_graph.node_type(inode)) { - case e_rr_type::SINK: - draw_rr_src_sink(inode, draw_state->draw_rr_node[inode].color, g); - break; - case e_rr_type::SOURCE: - draw_rr_edges(inode, g); - draw_rr_src_sink(inode, draw_state->draw_rr_node[inode].color, g); - break; - - case e_rr_type::CHANX: - draw_rr_chan(inode, draw_state->draw_rr_node[inode].color, g); - draw_rr_edges(inode, g); - break; - - case e_rr_type::CHANY: - draw_rr_chan(inode, draw_state->draw_rr_node[inode].color, g); - draw_rr_edges(inode, g); - break; - - case e_rr_type::IPIN: - draw_cluster_pin(inode, draw_state->draw_rr_node[inode].color, g); - draw_rr_edges(inode, g); - break; - - case e_rr_type::OPIN: - draw_cluster_pin(inode, draw_state->draw_rr_node[inode].color, g); - draw_rr_edges(inode, g); - break; - - default: - vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, - "in draw_rr: Unexpected rr_node type: %d.\n", rr_graph.node_type(inode)); - } + draw_rr_edges(inode, g); + draw_rr_node(inode, draw_state->draw_rr_node[inode].color, g); } drawroute(HIGHLIGHTED, g); @@ -275,14 +236,14 @@ void draw_rr_edges(RRNodeId inode, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; - auto rr_node = inode; - int transparency_factor = get_rr_node_transparency(rr_node); + e_rr_type to_type; + e_rr_type from_type = rr_graph.node_type(inode); - e_rr_type from_type, to_type; - short switch_type; - - from_type = rr_graph.node_type(rr_node); + // Currently don't visualize source or sinks. + if (from_type == e_rr_type::SOURCE || from_type == e_rr_type::SINK) { + return; + } if ((draw_state->draw_rr_toggle == DRAW_NODES_RR) || (draw_state->draw_rr_toggle == DRAW_NODES_SBOX_RR && (from_type == e_rr_type::OPIN || from_type == e_rr_type::SOURCE || from_type == e_rr_type::IPIN)) @@ -291,226 +252,100 @@ void draw_rr_edges(RRNodeId inode, ezgl::renderer* g) { } for (t_edge_size iedge = 0, l = rr_graph.num_edges(inode); iedge < l; iedge++) { - RRNodeId to_node = rr_graph.edge_sink_node(rr_node, iedge); + RRNodeId to_node = rr_graph.edge_sink_node(inode, iedge); to_type = rr_graph.node_type(to_node); bool edge_configurable = rr_graph.edge_is_configurable(inode, iedge); - if (!is_edge_valid_to_draw(RRNodeId(to_node), rr_node)) - continue; // skip drawing if edge is not valid to draw + // Currently don't visualize source or sinks. + if (to_type == e_rr_type::SOURCE || to_type == e_rr_type::SINK) { + continue; + } - switch (from_type) { - case e_rr_type::OPIN: - switch (to_type) { - case e_rr_type::CHANX: - case e_rr_type::CHANY: - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - // If OPIN was clicked on, set color to fan-out - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - // If CHANX or CHANY got clicked, set color to fan-in - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else { - g->set_color(ezgl::PINK, transparency_factor); - } - draw_pin_to_chan_edge(inode, to_node, g); - break; - case e_rr_type::IPIN: - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else { - g->set_color(ezgl::MEDIUM_PURPLE, transparency_factor); - } - draw_pin_to_pin(inode, to_node, g); - break; - default: - vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, - "in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n", - inode, from_type, to_node, to_type); - break; - } - break; + ezgl::color color = DEFAULT_RR_NODE_COLOR; + + // Color map for edges based on {from_type, to_type} + static const std::map, ezgl::color> edge_color_map = { + // Pin to pin connections + {{e_rr_type::IPIN, e_rr_type::IPIN}, ezgl::MEDIUM_PURPLE}, + {{e_rr_type::OPIN, e_rr_type::IPIN}, ezgl::MEDIUM_PURPLE}, + {{e_rr_type::OPIN, e_rr_type::OPIN}, ezgl::LIGHT_PINK}, + {{e_rr_type::IPIN, e_rr_type::OPIN}, ezgl::LIGHT_PINK}, + + // Channel to pin connections + {{e_rr_type::OPIN, e_rr_type::CHANX}, ezgl::PINK}, + {{e_rr_type::OPIN, e_rr_type::CHANY}, ezgl::PINK}, + {{e_rr_type::CHANX, e_rr_type::IPIN}, ezgl::PURPLE}, + {{e_rr_type::CHANY, e_rr_type::IPIN}, ezgl::PURPLE}, + + // Channel to channel connections + {{e_rr_type::CHANX, e_rr_type::CHANX}, blk_DARKGREEN}, + {{e_rr_type::CHANX, e_rr_type::CHANY}, blk_DARKGREEN}, + {{e_rr_type::CHANY, e_rr_type::CHANY}, blk_DARKGREEN}, + {{e_rr_type::CHANY, e_rr_type::CHANX}, blk_DARKGREEN}, + }; + + if (edge_color_map.find({from_type, to_type}) != edge_color_map.end()) { + color = edge_color_map.at({from_type, to_type}); + } - case e_rr_type::CHANX: /* from_type */ - switch (to_type) { - case e_rr_type::IPIN: - if (draw_state->draw_rr_toggle == DRAW_NODES_SBOX_RR) { - break; - } + if (!edge_configurable) color = blk_DARKGREY; + + if ((from_type == e_rr_type::CHANX || from_type == e_rr_type::CHANY) + && (to_type == e_rr_type::IPIN) + && draw_state->draw_rr_node[to_node].node_highlighted + && draw_state->draw_rr_node[inode].color == DEFAULT_RR_NODE_COLOR) { + // If the IPIN is clicked on, draw connection to all the CHANX + // wire segments fanning into the pin. If a CHANX wire is clicked + // on, draw only the connection between that wire and the IPIN, with + // the pin fanning out from the wire. + color = ezgl::MAGENTA; + } - if (draw_state->draw_rr_node[to_node].node_highlighted && draw_state->draw_rr_node[inode].color == DEFAULT_RR_NODE_COLOR) { - // If the IPIN is clicked on, draw connection to all the CHANX - // wire segments fanning into the pin. If a CHANX wire is clicked - // on, draw only the connection between that wire and the IPIN, with - // the pin fanning out from the wire. - break; - } + // If the node is highlighted, use its color + if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA) || rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { + color = draw_state->draw_rr_node[to_node].color; + } - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else { - g->set_color(blk_LIGHTSKYBLUE, transparency_factor); - } - draw_pin_to_chan_edge(to_node, inode, g); - break; - - case e_rr_type::CHANX: - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else if (!edge_configurable) { - ezgl::color color = blk_DARKGREY; - g->set_color(color, transparency_factor); - } else { - g->set_color(blk_DARKGREEN, transparency_factor); - } - switch_type = rr_graph.edge_switch(rr_node, iedge); - draw_chanx_to_chanx_edge(rr_node, RRNodeId(to_node), - switch_type, g); - break; - - case e_rr_type::CHANY: - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else if (!edge_configurable) { - g->set_color(blk_DARKGREY, transparency_factor); - } else { - g->set_color(blk_DARKGREEN, transparency_factor); - } - switch_type = rr_graph.edge_switch(rr_node, iedge); - draw_chanx_to_chany_edge(inode, to_node, - FROM_X_TO_Y, switch_type, g); - break; - - default: - vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, - "in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n", - inode, from_type, to_node, to_type); - break; - } - break; + draw_rr_edge(to_node, inode, color, g); - case e_rr_type::CHANY: /* from_type */ - switch (to_type) { - case e_rr_type::IPIN: - if (draw_state->draw_rr_toggle == DRAW_NODES_SBOX_RR) { - break; - } + } /* End of for each edge loop */ +} - if (draw_state->draw_rr_node[to_node].node_highlighted && draw_state->draw_rr_node[inode].color == DEFAULT_RR_NODE_COLOR) { - // If the IPIN is clicked on, draw connection to all the CHANY - // wire segments fanning into the pin. If a CHANY wire is clicked - // on, draw only the connection between that wire and the IPIN, with - // the pin fanning out from the wire. - break; - } +void draw_rr_node(RRNodeId inode, const ezgl::color color, ezgl::renderer* g) { + t_draw_state* draw_state = get_draw_state_vars(); + auto& device_ctx = g_vpr_ctx.device(); + const auto& rr_graph = device_ctx.rr_graph; + 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); - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else { - g->set_color(blk_LIGHTSKYBLUE, transparency_factor); - } - draw_pin_to_chan_edge(to_node, inode, g); - break; - - case e_rr_type::CHANX: - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else if (!edge_configurable) { - ezgl::color color = blk_DARKGREY; - g->set_color(color, transparency_factor); - } else { - g->set_color(blk_DARKGREEN, transparency_factor); - } - switch_type = rr_graph.edge_switch(rr_node, iedge); - draw_chanx_to_chany_edge(to_node, inode, - FROM_Y_TO_X, switch_type, g); - break; - - case e_rr_type::CHANY: - if (rgb_is_same(draw_state->draw_rr_node[inode].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[to_node].color; - g->set_color(color, transparency_factor); - } else if (rgb_is_same(draw_state->draw_rr_node[to_node].color, ezgl::MAGENTA)) { - ezgl::color color = draw_state->draw_rr_node[inode].color; - g->set_color(color, transparency_factor); - } else if (!edge_configurable) { - ezgl::color color = blk_DARKGREY; - g->set_color(color, transparency_factor); - } else { - g->set_color(blk_DARKGREEN, transparency_factor); - } - switch_type = rr_graph.edge_switch(rr_node, iedge); - draw_chany_to_chany_edge(rr_node, RRNodeId(to_node), - switch_type, g); - break; - - default: - vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, - "in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n", - inode, from_type, to_node, to_type); - break; - } - break; - case e_rr_type::IPIN: // from_type - switch (to_type) { - case e_rr_type::SINK: - g->set_color(ezgl::DARK_SLATE_BLUE, transparency_factor); - draw_pin_to_sink(inode, to_node, g); - break; - - default: - vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, - "in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n", - inode, from_type, to_node, to_type); - break; - } - break; - case e_rr_type::SOURCE: // from_type - switch (to_type) { - case e_rr_type::OPIN: - g->set_color(ezgl::PLUM, transparency_factor); - draw_source_to_pin(inode, to_node, g); - break; - - default: - vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, - "in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n", - inode, from_type, to_node, to_type); - break; - } - break; - default: /* from_type */ - vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, - "draw_rr_edges called with node %d of type %d.\n", - inode, from_type); - break; - } - } /* End of for each edge loop */ + // For 3D architectures, draw only visible layers + if (!draw_state->draw_layer_display[node_layer].visible) { + return; + } + + // Skip drawing sources and sinks + if (rr_type == e_rr_type::SINK || rr_type == e_rr_type::SOURCE) { + return; + } + + // Draw intra-cluster nodes + if (!is_inode_inter_cluster) { + draw_rr_intra_cluster_pin(inode, color, g); + return; + } + + // Draw cluster-level IO Pins + if (rr_type == e_rr_type::OPIN || rr_type == e_rr_type::IPIN) { + draw_cluster_pin(inode, color, g); + return; + } + + // Draw Channels + if (rr_type == e_rr_type::CHANY || rr_type == e_rr_type::CHANX) { + draw_rr_chan(inode, color, g); + return; + } } void draw_rr_intra_cluster_pin(RRNodeId inode, const ezgl::color& color, ezgl::renderer* g) { diff --git a/vpr/src/draw/draw_rr.h b/vpr/src/draw/draw_rr.h index 805352b951a..65951a31741 100644 --- a/vpr/src/draw/draw_rr.h +++ b/vpr/src/draw/draw_rr.h @@ -27,6 +27,15 @@ 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 a RR node. + * + * @param inode The RRNodeId of the node to draw. + * @param color The color to use for drawing the node. + * @param g The renderer to use for drawing. + */ +void draw_rr_node(RRNodeId inode, const ezgl::color color, ezgl::renderer* g); + /** * @brief Draws the intra-cluster pin for a given RRNodeId when flat routing is enabled. */ diff --git a/vpr/src/draw/draw_rr_edges.cpp b/vpr/src/draw/draw_rr_edges.cpp index eef034e872e..e4bca77cda3 100644 --- a/vpr/src/draw/draw_rr_edges.cpp +++ b/vpr/src/draw/draw_rr_edges.cpp @@ -10,6 +10,7 @@ #include "vpr_error.h" #include "globals.h" +#include "draw.h" #include "draw_rr.h" #include "draw_rr_edges.h" #include "draw_triangle.h" @@ -300,39 +301,48 @@ 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 intra_cluster_node, RRNodeId inter_cluster_node, e_pin_edge_dir pin_edge_dir, e_side pin_side, 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, ezgl::renderer* g) { t_draw_state* draw_state = get_draw_state_vars(); t_draw_coords* draw_coords = get_draw_coords_vars(); + const auto& device_ctx = g_vpr_ctx.device(); + const auto& rr_graph = device_ctx.rr_graph; if (!draw_state->is_flat) { return; } - // determine the location of the pins - float inter_cluster_x, inter_cluster_y; - ezgl::point2d intra_cluster_coord; + for (const e_side pin_side : TOTAL_2D_SIDES) { + // Draw connections to each side of the inter-cluster node + if (!rr_graph.is_node_on_specific_side(inter_cluster_node, pin_side)) { + continue; + } - draw_get_rr_pin_coords(inter_cluster_node, &inter_cluster_x, &inter_cluster_y, pin_side); + // determine the location of the pins + float inter_cluster_x, inter_cluster_y; + ezgl::point2d intra_cluster_coord; - 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); + draw_get_rr_pin_coords(inter_cluster_node, &inter_cluster_x, &inter_cluster_y, pin_side); - // 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 { - VPR_ERROR(VPR_ERROR_DRAW, "Invalid pin edge direction: %d", pin_edge_dir); - } + 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); - 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); + // 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 { + VPR_ERROR(VPR_ERROR_DRAW, "Invalid pin edge direction: %d", pin_edge_dir); + } + + 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) { @@ -349,7 +359,7 @@ void draw_pin_to_pin(RRNodeId opin_node, RRNodeId ipin_node, ezgl::renderer* g) */ float x1 = 0, y1 = 0; std::vector opin_candidate_sides; - for (const e_side& opin_candidate_side : TOTAL_2D_SIDES) { + for (const e_side opin_candidate_side : TOTAL_2D_SIDES) { if (rr_graph.is_node_on_specific_side(opin_node, opin_candidate_side)) { opin_candidate_sides.push_back(opin_candidate_side); } @@ -359,7 +369,7 @@ void draw_pin_to_pin(RRNodeId opin_node, RRNodeId ipin_node, ezgl::renderer* g) float x2 = 0, y2 = 0; std::vector ipin_candidate_sides; - for (const e_side& ipin_candidate_side : TOTAL_2D_SIDES) { + for (const e_side ipin_candidate_side : TOTAL_2D_SIDES) { if (rr_graph.is_node_on_specific_side(ipin_node, ipin_candidate_side)) { ipin_candidate_sides.push_back(ipin_candidate_side); } @@ -380,7 +390,7 @@ void draw_pin_to_sink(RRNodeId ipin_node, RRNodeId sink_node, ezgl::renderer* g) float x1 = 0, y1 = 0; /* Draw the line for each ipin on different sides */ - for (const e_side& pin_side : TOTAL_2D_SIDES) { + for (const e_side pin_side : TOTAL_2D_SIDES) { if (!rr_graph.is_node_on_specific_side(ipin_node, pin_side)) { continue; } @@ -406,7 +416,7 @@ void draw_source_to_pin(RRNodeId source_node, RRNodeId opin_node, ezgl::renderer draw_get_rr_src_sink_coords(rr_graph.rr_nodes()[size_t(source_node)], &x1, &y1); /* Draw the line for each ipin on different sides */ - for (const e_side& pin_side : TOTAL_2D_SIDES) { + for (const e_side pin_side : TOTAL_2D_SIDES) { if (!rr_graph.is_node_on_specific_side(opin_node, pin_side)) { continue; } @@ -473,7 +483,7 @@ e_side get_pin_side(RRNodeId pin_node, RRNodeId chan_node) { * the actual offset of the pin in the context of grid width and height */ std::vector pin_candidate_sides; - for (const e_side& pin_candidate_side : TOTAL_2D_SIDES) { + for (const e_side pin_candidate_side : TOTAL_2D_SIDES) { if ((rr_graph.is_node_on_specific_side(pin_node, pin_candidate_side)) && (grid_type->pinloc[width_offset][height_offset][pin_candidate_side][rr_graph.node_pin_num(pin_node)])) { pin_candidate_sides.push_back(pin_candidate_side); @@ -610,4 +620,115 @@ void draw_pin_to_chan_edge(RRNodeId pin_node, RRNodeId chan_node, ezgl::renderer } } +void draw_rr_edge(RRNodeId inode, RRNodeId prev_node, ezgl::color color, ezgl::renderer* g) { + auto& device_ctx = g_vpr_ctx.device(); + auto& rr_graph = device_ctx.rr_graph; + t_draw_state* draw_state = get_draw_state_vars(); + + e_rr_type rr_type = rr_graph.node_type(inode); + bool inode_inter_cluster = is_inter_cluster_node(rr_graph, inode); + int current_node_layer = rr_graph.node_layer(inode); + + e_rr_type prev_type = rr_graph.node_type(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); + + // For 3D architectures, draw only visible layers + if (!draw_state->draw_layer_display[current_node_layer].visible || !edge_visibility.visible) { + return; + } + + // 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) { + return; + } + + g->set_color(color, edge_visibility.alpha); + + if (!inode_inter_cluster && !prev_node_inter_cluster) { + draw_intra_cluster_edge(inode, prev_node, g); + return; + } + + if (!prev_node_inter_cluster && inode_inter_cluster) { + draw_intra_cluster_pin_to_pin(prev_node, inode, FROM_INTRA_CLUSTER_TO_INTER_CLUSTER, g); + return; + } + + if (prev_node_inter_cluster && !inode_inter_cluster) { + draw_intra_cluster_pin_to_pin(inode, prev_node, FROM_INTER_CLUSTER_TO_INTRA_CLUSTER, g); + return; + } + + 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, 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(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); + } + 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(prev_node, 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: + break; + } +} + #endif diff --git a/vpr/src/draw/draw_rr_edges.h b/vpr/src/draw/draw_rr_edges.h index fcfb4370c14..9adbcdae141 100644 --- a/vpr/src/draw/draw_rr_edges.h +++ b/vpr/src/draw/draw_rr_edges.h @@ -38,14 +38,13 @@ 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_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. + * @brief Draws the edge between an intra-cluster pin and an inter-cluster pin when flat routing is enabled. Draws to each side of the inter-cluster RR node. * @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 intra_cluster_node, RRNodeId inter_cluster_node, e_pin_edge_dir pin_edge_dir, e_side pin_side, 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, ezgl::renderer* g); /** * @brief Draws the edge between two intra-cluster pins when flat routing is enabled. @@ -78,4 +77,23 @@ e_side get_pin_side(RRNodeId pin_node, RRNodeId chan_node); */ void draw_pin_to_chan_edge(RRNodeId pin_node, RRNodeId chan_node, ezgl::renderer* g); +/** + * @brief Draws an edge between two RR nodes. + * + * This function determines the type of the RR nodes and calls the appropriate drawing function. + * + * @param inode The current node to draw to + * @param prev_node The previous node to draw from + * @param color The color of the edge + * @param g The ezgl renderer + */ +void draw_rr_edge(RRNodeId inode, RRNodeId prev_node, ezgl::color color, 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, ezgl::renderer* g); + #endif /* NO_GRAPHICS */