Skip to content

Flat Routing Visualization #3159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vpr/src/draw/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ int get_track_num(int inode, const vtr::OffsetMatrix<int>& 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) {
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/draw/draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ ezgl::color to_ezgl_color(vtr::Color<float> 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<RRNodeId> trace_routed_connection_rr_nodes(
ClusterNetId net_id,
int driver_pin,
Expand Down
194 changes: 98 additions & 96 deletions vpr/src/draw/draw_basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,24 +569,20 @@ 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;

std::vector<RRNodeId> rr_nodes_to_draw;
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. */
Expand Down Expand Up @@ -616,133 +612,139 @@ void draw_partial_route(const std::vector<RRNodeId>& rr_nodes_to_draw, ezgl::ren
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

static vtr::OffsetMatrix<int> chanx_track; /* [1..device_ctx.grid.width() - 2][0..device_ctx.grid.height() - 2] */
static vtr::OffsetMatrix<int> chany_track; /* [0..device_ctx.grid.width() - 2][1..device_ctx.grid.height() - 2] */
if (draw_state->draw_route_type == e_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<int>({{{1, width - 1}, {0, height - 1}}});
// Draw Pins
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;
}

if (chany_track.empty()) {
chany_track = vtr::OffsetMatrix<int>({{{0, width - 1}, {1, height - 1}}});
// Draw intra-cluster nodes
if (!is_inode_inter_cluster) {
draw_rr_intrapin(inode, color, g);
continue;
}

for (int i = 1; i < width - 1; i++)
for (int j = 0; j < height - 1; j++)
chanx_track[i][j] = (-1);
// Draw IO Pins
if (rr_type == e_rr_type::OPIN || rr_type == e_rr_type::IPIN) {
draw_rr_pin(inode, color, g);
continue;
}

for (int i = 0; i < width - 1; i++)
for (int j = 1; j < height - 1; j++)
chany_track[i][j] = (-1);
// 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_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;

if (!is_inter_cluster_node(rr_graph, prev_node) || !is_inter_cluster_node(rr_graph, inode)) {
// For 3D architectures, draw only visible layers
if (!draw_state->draw_layer_display[current_node_layer].visible || !edge_visibility.visible) {
continue;
}

auto iedge = find_edge(prev_node, inode);
auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge);
// Skip drawing 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;
}

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);
g->set_color(color, edge_visibility.alpha);

//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) {
if (!is_inode_inter_cluster && !is_prev_node_inter_cluster) {
draw_intrapin_to_intrapin(inode, prev_node, g);
continue;
}

ezgl::color color = draw_state->draw_rr_node[inode].color;
if (!is_inode_inter_cluster || !is_prev_node_inter_cluster) {
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: {
if (draw_state->draw_route_type == e_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);
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: {
if (draw_state->draw_route_type == e_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) {
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: {
Expand Down
44 changes: 44 additions & 0 deletions vpr/src/draw/draw_rr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,26 @@ 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_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);

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. */
Expand Down Expand Up @@ -683,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: {
Expand Down
1 change: 1 addition & 0 deletions vpr/src/draw/draw_rr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
Loading