-
Notifications
You must be signed in to change notification settings - Fork 419
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
base: master
Are you sure you want to change the base?
Changes from all commits
1d796a5
718e85a
885151a
6c43c20
97f1203
b49ac73
c6f7d0d
9a1a3c4
1aa214c
8577aee
18c377f
571e50d
e51cf20
0be7746
9970b2e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. */ | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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; | ||
} | ||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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; | ||
} | ||
|
||
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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To match the structure of the rest of the code and shorten this routine I think this switch statement should be moved into a helper router (maybe called draw_inter_cluster_rr_edge ) |
||
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: { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. */ | ||
|
@@ -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)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd add a comment here: check for inter-cluster nodes |
||
case e_rr_type::IPIN: | ||
case e_rr_type::OPIN: { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a comment describing what the function does. I think it would be best to make it a Doxygen comment so we can choose to build Doxygen comments for more drawing code in the future. General principle: comment what a function does in the .h file, or (if it is a static function) in its declaration in the .cpp file. Use Doxygen formatting in either case. |
||
/* 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. */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this drawing rr nodes (not just pins)? Suggest changing the comment.