Skip to content

Commit 1ed4a94

Browse files
authored
Merge pull request #3159 from verilog-to-routing/visualize_flat_routing
Flat Routing Visualization
2 parents b26c43a + b9f09db commit 1ed4a94

18 files changed

+644
-236
lines changed

vpr/src/draw/draw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ int get_track_num(int inode, const vtr::OffsetMatrix<int>& chanx_track, const vt
658658
* could be caused by the user clicking on a routing resource, toggled, or
659659
* fan-in/fan-out of a highlighted node.
660660
*/
661-
bool draw_if_net_highlighted(ClusterNetId inet) {
661+
bool draw_if_net_highlighted(ParentNetId inet) {
662662
t_draw_state* draw_state = get_draw_state_vars();
663663

664664
if (draw_state->net_color[inet] != DEFAULT_RR_NODE_COLOR) {

vpr/src/draw/draw.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ ezgl::color to_ezgl_color(vtr::Color<float> color);
9494
/* This helper function determines whether a net has been highlighted. The highlighting
9595
* could be caused by the user clicking on a routing resource, toggled, or
9696
* fan-in/fan-out of a highlighted node. */
97-
bool draw_if_net_highlighted(ClusterNetId inet);
97+
bool draw_if_net_highlighted(ParentNetId inet);
9898
std::vector<RRNodeId> trace_routed_connection_rr_nodes(
9999
ClusterNetId net_id,
100100
int driver_pin,

vpr/src/draw/draw_basic.cpp

Lines changed: 133 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ void draw_congestion(ezgl::renderer* g) {
357357

358358
case e_rr_type::IPIN: //fallthrough
359359
case e_rr_type::OPIN:
360-
draw_rr_pin(inode, color, g);
360+
draw_cluster_pin(inode, color, g);
361361
break;
362362
default:
363363
break;
@@ -569,24 +569,20 @@ void drawroute(enum e_draw_net_type draw_net_type, ezgl::renderer* g) {
569569

570570
void draw_routed_net(ParentNetId net_id, ezgl::renderer* g) {
571571
auto& route_ctx = g_vpr_ctx.routing();
572-
auto& cluster_ctx = g_vpr_ctx.clustering();
573572

574573
t_draw_state* draw_state = get_draw_state_vars();
575574

576-
if (cluster_ctx.clb_nlist.net_is_ignored(convert_to_cluster_net_id(net_id))) /* Don't draw. */
577-
return;
578-
579575
if (!route_ctx.route_trees[net_id]) // No routing -> Skip. (Allows me to draw partially complete routes)
580576
return;
581577

582578
std::vector<RRNodeId> rr_nodes_to_draw;
583579
for (auto& rt_node : route_ctx.route_trees[net_id].value().all_nodes()) {
584580
RRNodeId inode = rt_node.inode;
585581

586-
if (draw_if_net_highlighted(convert_to_cluster_net_id(net_id))) {
582+
if (draw_if_net_highlighted(net_id)) {
587583
/* If a net has been highlighted, highlight the whole net in *
588584
* the same color. */
589-
draw_state->draw_rr_node[inode].color = draw_state->net_color[convert_to_cluster_net_id(net_id)];
585+
draw_state->draw_rr_node[inode].color = draw_state->net_color[net_id];
590586
draw_state->draw_rr_node[inode].node_highlighted = true;
591587
} else {
592588
/* If not highlighted, draw the node in default color. */
@@ -616,138 +612,168 @@ void draw_partial_route(const std::vector<RRNodeId>& rr_nodes_to_draw, ezgl::ren
616612
auto& device_ctx = g_vpr_ctx.device();
617613
const auto& rr_graph = device_ctx.rr_graph;
618614

619-
static vtr::OffsetMatrix<int> chanx_track; /* [1..device_ctx.grid.width() - 2][0..device_ctx.grid.height() - 2] */
620-
static vtr::OffsetMatrix<int> chany_track; /* [0..device_ctx.grid.width() - 2][1..device_ctx.grid.height() - 2] */
621-
if (draw_state->draw_route_type == e_route_type::GLOBAL) {
622-
/* Allocate some temporary storage if it's not already available. */
623-
int width = (int)device_ctx.grid.width();
624-
int height = (int)device_ctx.grid.height();
625-
if (chanx_track.empty()) {
626-
chanx_track = vtr::OffsetMatrix<int>({{{1, width - 1}, {0, height - 1}}});
615+
// Draw RR Nodes
616+
for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) {
617+
RRNodeId inode = rr_nodes_to_draw[i];
618+
e_rr_type rr_type = rr_graph.node_type(inode);
619+
bool is_inode_inter_cluster = is_inter_cluster_node(rr_graph, inode);
620+
int node_layer = rr_graph.node_layer(inode);
621+
622+
ezgl::color color = draw_state->draw_rr_node[inode].color;
623+
624+
// For 3D architectures, draw only visible layers
625+
if (!draw_state->draw_layer_display[node_layer].visible) {
626+
continue;
627627
}
628628

629-
if (chany_track.empty()) {
630-
chany_track = vtr::OffsetMatrix<int>({{{0, width - 1}, {1, height - 1}}});
629+
// Skip drawing sources and sinks
630+
if (rr_type == e_rr_type::SINK || rr_type == e_rr_type::SOURCE) {
631+
continue;
631632
}
632633

633-
for (int i = 1; i < width - 1; i++)
634-
for (int j = 0; j < height - 1; j++)
635-
chanx_track[i][j] = (-1);
634+
// Draw intra-cluster nodes
635+
if (!is_inode_inter_cluster) {
636+
draw_rr_intra_cluster_pin(inode, color, g);
637+
continue;
638+
}
639+
640+
// Draw cluster-level IO Pins
641+
if (rr_type == e_rr_type::OPIN || rr_type == e_rr_type::IPIN) {
642+
draw_cluster_pin(inode, color, g);
643+
continue;
644+
}
636645

637-
for (int i = 0; i < width - 1; i++)
638-
for (int j = 1; j < height - 1; j++)
639-
chany_track[i][j] = (-1);
646+
// Draw Channels
647+
if (rr_type == e_rr_type::CHANY || rr_type == e_rr_type::CHANX) {
648+
draw_rr_chan(inode, color, g);
649+
continue;
650+
}
640651
}
641652

653+
// Draw Edges
642654
for (size_t i = 1; i < rr_nodes_to_draw.size(); ++i) {
655+
643656
RRNodeId inode = rr_nodes_to_draw[i];
644657
auto rr_type = rr_graph.node_type(inode);
658+
bool inode_inter_cluster = is_inter_cluster_node(rr_graph, inode);
659+
int current_node_layer = rr_graph.node_layer(inode);
645660

646661
RRNodeId prev_node = rr_nodes_to_draw[i - 1];
647662
auto prev_type = rr_graph.node_type(RRNodeId(prev_node));
663+
bool prev_node_inter_cluster = is_inter_cluster_node(rr_graph, prev_node);
664+
int prev_node_layer = rr_graph.node_layer(prev_node);
648665

649-
if (!is_inter_cluster_node(rr_graph, prev_node) || !is_inter_cluster_node(rr_graph, inode)) {
666+
t_draw_layer_display edge_visibility = get_element_visibility_and_transparency(prev_node_layer, current_node_layer);
667+
ezgl::color color = draw_state->draw_rr_node[inode].color;
668+
669+
// For 3D architectures, draw only visible layers
670+
if (!draw_state->draw_layer_display[current_node_layer].visible || !edge_visibility.visible) {
650671
continue;
651672
}
652673

653-
auto iedge = find_edge(prev_node, inode);
654-
auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge);
674+
// Skip drawing edges to or from sources and sinks
675+
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) {
676+
continue;
677+
}
655678

656-
int current_node_layer = rr_graph.node_layer(inode);
657-
int prev_node_layer = rr_graph.node_layer(prev_node);
658-
t_draw_layer_display edge_visibility = get_element_visibility_and_transparency(prev_node_layer, current_node_layer);
679+
g->set_color(color, edge_visibility.alpha);
659680

660-
//Don't draw node if the layer of the node is not set to visible on screen
661-
if (!draw_state->draw_layer_display[current_node_layer].visible) {
681+
if (!inode_inter_cluster && !prev_node_inter_cluster) {
682+
draw_intra_cluster_edge(inode, prev_node, g);
662683
continue;
663684
}
664685

665-
ezgl::color color = draw_state->draw_rr_node[inode].color;
666-
667-
switch (rr_type) {
668-
case e_rr_type::OPIN: {
669-
draw_rr_pin(inode, color, g);
670-
break;
686+
// Default side for pin in case none can be found
687+
e_side pin_side = e_side::TOP;
688+
if (!prev_node_inter_cluster && inode_inter_cluster) {
689+
// draw intra-cluster pin to inter-cluster pin
690+
// node i + 1 is the channel node
691+
if (i + 1 < rr_nodes_to_draw.size()) {
692+
pin_side = get_pin_side(inode, rr_nodes_to_draw[i + 1]);
671693
}
672-
case e_rr_type::IPIN: {
673-
draw_rr_pin(inode, color, g);
674-
if (edge_visibility.visible) {
675-
g->set_color(color, edge_visibility.alpha);
676-
if (rr_graph.node_type(prev_node) == e_rr_type::OPIN) {
677-
draw_pin_to_pin(prev_node, inode, g);
678-
} else {
679-
draw_pin_to_chan_edge(inode, prev_node, g);
680-
}
681-
}
682-
break;
683-
}
684-
case e_rr_type::CHANX: {
685-
if (draw_state->draw_route_type == e_route_type::GLOBAL)
686-
chanx_track[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)]++;
687694

688-
draw_rr_chan(inode, color, g);
689-
if (edge_visibility.visible) {
690-
g->set_color(color, edge_visibility.alpha);
691-
switch (prev_type) {
692-
case e_rr_type::CHANX: {
693-
draw_chanx_to_chanx_edge(prev_node, inode, switch_type, g);
694-
break;
695-
}
696-
case e_rr_type::CHANY: {
697-
draw_chanx_to_chany_edge(inode, prev_node, FROM_Y_TO_X, switch_type, g);
698-
break;
699-
}
700-
case e_rr_type::OPIN: {
701-
draw_pin_to_chan_edge(prev_node, inode, g);
702-
break;
703-
}
704-
default: {
705-
VPR_ERROR(VPR_ERROR_OTHER,
706-
"Unexpected connection from an rr_node of type %d to one of type %d.\n",
707-
prev_type, rr_type);
708-
}
709-
}
710-
}
695+
draw_intra_cluster_pin_to_pin(prev_node, inode, FROM_INTRA_CLUSTER_TO_INTER_CLUSTER, pin_side, g);
696+
continue;
697+
}
711698

712-
break;
699+
if (prev_node_inter_cluster && !inode_inter_cluster) {
700+
// draw inter-cluster pin to intra-cluster pin
701+
// node i - 2 is the channel node
702+
if (i >= 2) {
703+
pin_side = get_pin_side(prev_node, rr_nodes_to_draw[i - 2]);
713704
}
714-
case e_rr_type::CHANY: {
715-
if (draw_state->draw_route_type == e_route_type::GLOBAL)
716-
chany_track[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)]++;
717705

718-
draw_rr_chan(inode, color, g);
706+
draw_intra_cluster_pin_to_pin(inode, prev_node, FROM_INTER_CLUSTER_TO_INTRA_CLUSTER, pin_side, g);
707+
continue;
708+
}
719709

720-
if (edge_visibility.visible) {
721-
g->set_color(color, edge_visibility.alpha);
722-
switch (prev_type) {
723-
case e_rr_type::CHANX: {
724-
draw_chanx_to_chany_edge(prev_node, inode,
725-
FROM_X_TO_Y, switch_type, g);
726-
break;
727-
}
728-
case e_rr_type::CHANY: {
729-
draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode),
730-
switch_type, g);
731-
break;
732-
}
733-
case e_rr_type::OPIN: {
734-
draw_pin_to_chan_edge(prev_node, inode, g);
710+
draw_inter_cluster_rr_edge(inode, prev_node, rr_type, prev_type, g);
711+
}
712+
}
735713

736-
break;
737-
}
738-
default: {
739-
VPR_ERROR(VPR_ERROR_OTHER,
740-
"Unexpected connection from an rr_node of type %d to one of type %d.\n",
741-
prev_type, rr_type);
742-
}
743-
}
744-
}
714+
void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, ezgl::renderer* g) {
715+
const RRGraphView& rr_graph = g_vpr_ctx.device().rr_graph;
716+
t_edge_size iedge = find_edge(prev_node, inode);
717+
short switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge);
745718

746-
break;
719+
switch (rr_type) {
720+
case e_rr_type::IPIN: {
721+
if (prev_type == e_rr_type::OPIN) {
722+
draw_pin_to_pin(prev_node, inode, g);
723+
} else {
724+
draw_pin_to_chan_edge(inode, prev_node, g);
747725
}
748-
default: {
749-
break;
726+
break;
727+
}
728+
case e_rr_type::CHANX: {
729+
switch (prev_type) {
730+
case e_rr_type::CHANX: {
731+
draw_chanx_to_chanx_edge(prev_node, inode, switch_type, g);
732+
break;
733+
}
734+
case e_rr_type::CHANY: {
735+
draw_chanx_to_chany_edge(inode, prev_node, FROM_Y_TO_X, switch_type, g);
736+
break;
737+
}
738+
case e_rr_type::OPIN: {
739+
draw_pin_to_chan_edge(prev_node, inode, g);
740+
break;
741+
}
742+
default: {
743+
VPR_ERROR(VPR_ERROR_OTHER,
744+
"Unexpected connection from an rr_node of type %d to one of type %d.\n",
745+
prev_type, rr_type);
746+
}
750747
}
748+
break;
749+
}
750+
case e_rr_type::CHANY: {
751+
switch (prev_type) {
752+
case e_rr_type::CHANX: {
753+
draw_chanx_to_chany_edge(prev_node, inode,
754+
FROM_X_TO_Y, switch_type, g);
755+
break;
756+
}
757+
case e_rr_type::CHANY: {
758+
draw_chany_to_chany_edge(RRNodeId(prev_node), RRNodeId(inode),
759+
switch_type, g);
760+
break;
761+
}
762+
case e_rr_type::OPIN: {
763+
draw_pin_to_chan_edge(prev_node, inode, g);
764+
765+
break;
766+
}
767+
default: {
768+
VPR_ERROR(VPR_ERROR_OTHER,
769+
"Unexpected connection from an rr_node of type %d to one of type %d.\n",
770+
prev_type, rr_type);
771+
}
772+
}
773+
break;
774+
}
775+
default: {
776+
break;
751777
}
752778
}
753779
}

vpr/src/draw/draw_basic.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ void draw_routed_net(ParentNetId net, ezgl::renderer* g);
5757
void draw_partial_route(const std::vector<RRNodeId>& rr_nodes_to_draw,
5858
ezgl::renderer* g);
5959

60+
/** @brief Draws an edge between two rr_nodes, which are both intra-cluster nodes.
61+
* @param inode The current rr_node id
62+
* @param prev_node The previous rr_node id
63+
* @param g The ezgl renderer
64+
*/
65+
void draw_inter_cluster_rr_edge(RRNodeId inode, RRNodeId prev_node, e_rr_type rr_type, e_rr_type prev_type, ezgl::renderer* g);
66+
6067
/**
6168
* @brief Returns the layer number of a timing path node
6269
* @param node

0 commit comments

Comments
 (0)