Skip to content

Vpr viewer and flat routing on #3070

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 10 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) {
}

// TODO: Placer still assumes that cluster net list is used - graphics can not work with flat routing yet
vpr_init_graphics(vpr_setup, arch, false);
bool is_flat = vpr_setup.RouterOpts.flat_routing;
vpr_init_graphics(vpr_setup, arch, is_flat);

vpr_init_server(vpr_setup);

Expand Down Expand Up @@ -468,7 +469,6 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) {
block_locs);
}

bool is_flat = vpr_setup.RouterOpts.flat_routing;
const Netlist<>& router_net_list = is_flat ? (const Netlist<>&)g_vpr_ctx.atom().netlist() : (const Netlist<>&)g_vpr_ctx.clustering().clb_nlist;
if (is_flat) {
VTR_LOG_WARN("Disabling port equivalence in the architecture since flat routing is enabled.\n");
Expand Down
8 changes: 7 additions & 1 deletion vpr/src/draw/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ void alloc_draw_structs(const t_arch* arch) {
t_draw_state* draw_state = get_draw_state_vars();
auto& device_ctx = g_vpr_ctx.device();
auto& cluster_ctx = g_vpr_ctx.clustering();
const AtomContext& atom_ctx = g_vpr_ctx.atom();

/* Allocate the structures needed to draw the placement and routing-> Set *
* up the default colors for blocks and nets. */
Expand All @@ -498,7 +499,12 @@ void alloc_draw_structs(const t_arch* arch) {
/* For sub-block drawings inside clbs */
draw_internal_alloc_blk();

draw_state->net_color.resize(cluster_ctx.clb_nlist.nets().size());
if (draw_state->is_flat) {
draw_state->net_color.resize(atom_ctx.netlist().nets().size());
} else {
draw_state->net_color.resize(cluster_ctx.clb_nlist.nets().size());
}

draw_state->block_color_.resize(cluster_ctx.clb_nlist.blocks().size());
draw_state->use_default_block_color_.resize(
cluster_ctx.clb_nlist.blocks().size());
Expand Down
24 changes: 17 additions & 7 deletions vpr/src/draw/draw_basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ void drawroute(enum e_draw_net_type draw_net_type, ezgl::renderer* g) {
/* Next free track in each channel segment if routing is GLOBAL */

auto& cluster_ctx = g_vpr_ctx.clustering();
const AtomContext& atom_ctx = g_vpr_ctx.atom();

t_draw_state* draw_state = get_draw_state_vars();

Expand All @@ -546,14 +547,23 @@ void drawroute(enum e_draw_net_type draw_net_type, ezgl::renderer* g) {
g->set_color(ezgl::BLACK, ezgl::BLACK.alpha * NET_ALPHA);

/* Now draw each net, one by one. */
if (draw_state->is_flat) {
for (AtomNetId net_id : atom_ctx.netlist().nets()) {
if (draw_net_type == HIGHLIGHTED
&& draw_state->net_color[net_id] == ezgl::BLACK)
continue;

draw_routed_net((ParentNetId&)net_id, g);
} /* End for (each net) */
} else {
for (ClusterNetId net_id : cluster_ctx.clb_nlist.nets()) {
if (draw_net_type == HIGHLIGHTED
&& draw_state->net_color[net_id] == ezgl::BLACK)
continue;

for (auto net_id : cluster_ctx.clb_nlist.nets()) {
if (draw_net_type == HIGHLIGHTED
&& draw_state->net_color[net_id] == ezgl::BLACK)
continue;

draw_routed_net((ParentNetId&)net_id, g);
} /* End for (each net) */
draw_routed_net((ParentNetId&)net_id, g);
} /* End for (each net) */
}
}

void draw_routed_net(ParentNetId net_id, ezgl::renderer* g) {
Expand Down
10 changes: 8 additions & 2 deletions vpr/src/draw/draw_searchbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ void deselect_all() {

t_draw_state* draw_state = get_draw_state_vars();
const auto& cluster_ctx = g_vpr_ctx.clustering();
const AtomContext& atom_ctx = g_vpr_ctx.atom();
const auto& device_ctx = g_vpr_ctx.device();

/* Create some colour highlighting */
Expand All @@ -239,8 +240,13 @@ void deselect_all() {
draw_reset_blk_color(blk_id);
}

for (auto net_id : cluster_ctx.clb_nlist.nets())
draw_state->net_color[net_id] = ezgl::BLACK;
if (draw_state->is_flat) {
for (auto net_id : atom_ctx.netlist().nets())
draw_state->net_color[net_id] = ezgl::BLACK;
} else {
for (auto net_id : cluster_ctx.clb_nlist.nets())
draw_state->net_color[net_id] = ezgl::BLACK;
}

for (RRNodeId inode : device_ctx.rr_graph.nodes()) {
draw_state->draw_rr_node[inode].color = DEFAULT_RR_NODE_COLOR;
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/draw/draw_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ struct t_draw_state {
char default_message[vtr::bufsize];

///@brief color in which each net should be drawn. [0..cluster_ctx.clb_nlist.nets().size()-1]
vtr::vector<ClusterNetId, ezgl::color> net_color;
vtr::vector<ParentNetId, ezgl::color> net_color;

/**
* @brief stores the state information of each routing resource.
Expand Down
106 changes: 89 additions & 17 deletions vpr/src/draw/search_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "intra_logic_block.h"
#include "atom_netlist.h"
#include "search_bar.h"
#include "old_traceback.h"
#include "physical_types.h"
#include "place_macro.h"

Expand All @@ -41,6 +42,34 @@

extern std::string rr_highlight_message;

bool is_net_unrouted(AtomNetId atomic_net_id) {
RoutingContext& route_ctx = g_vpr_ctx.mutable_routing();
return !route_ctx.route_trees[atomic_net_id].has_value();
}

bool is_net_fully_absorbed(AtomNetId atomic_net_id) {
const RRGraphView& rr_graph = g_vpr_ctx.device().rr_graph;
RoutingContext& route_ctx = g_vpr_ctx.mutable_routing();

bool is_absorbed = true;

t_trace* head = TracebackCompat::traceback_from_route_tree(route_ctx.route_trees[atomic_net_id].value());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more common approach in VTR for iterating over the routing path of a net is to use the route tree (in routing context), which can also be used to check whether a net is routed. I’d suggest using that instead of constructing the net trace manually.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, add a comment and explain how you determine whether a net is completely absorbed.

t_trace* tptr = head;
while (tptr != nullptr) {
RRNodeId inode = RRNodeId(tptr->index);
e_rr_type rr_type = rr_graph.node_type(inode);

if (rr_type == e_rr_type::CHANX || rr_type == e_rr_type::CHANY) {
is_absorbed = false;
break;
}
tptr = tptr->next;
}
free_traceback(head);

return is_absorbed;
}

void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) {
auto& device_ctx = g_vpr_ctx.device();
auto& cluster_ctx = g_vpr_ctx.clustering();
Expand All @@ -59,6 +88,8 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) {
// reset
deselect_all();

t_draw_state* draw_state = get_draw_state_vars();

if (search_type == "RR Node ID") {
int rr_node_id = -1;
ss >> rr_node_id;
Expand Down Expand Up @@ -122,32 +153,73 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) {
else if (search_type == "Net ID") {
int net_id = -1;
ss >> net_id;

// valid net id check
if (!cluster_ctx.clb_nlist.valid_net_id(ClusterNetId(net_id))) {
warning_dialog_box("Invalid Net ID");
app->refresh_drawing();
return;
if (draw_state->is_flat) {
AtomNetId atom_net_id = AtomNetId(net_id);
if (!atom_ctx.netlist().valid_net_id(atom_net_id)) {
warning_dialog_box("Invalid Net ID");
app->refresh_drawing();
return;
}
if (is_net_unrouted(atom_net_id)) {
warning_dialog_box("Net is unrouted");
app->refresh_drawing();
return;
}
if (is_net_fully_absorbed(atom_net_id)) {
warning_dialog_box("Net is fully absorbed");
app->refresh_drawing();
return;
}
highlight_nets((ClusterNetId)net_id);
} else {
// valid net id check
if (!cluster_ctx.clb_nlist.valid_net_id(ClusterNetId(net_id))) {
warning_dialog_box("Invalid Net ID");
app->refresh_drawing();
return;
}
highlight_nets((ClusterNetId)net_id);
}

highlight_nets((ClusterNetId)net_id);
}

else if (search_type == "Net Name") {
//in this case, all nets (clb and non-clb) are contained in the atom netlist
//So we only need to search this one
std::string net_name;
ss >> net_name;
AtomNetId atom_net_id = atom_ctx.netlist().find_net(net_name);

if (atom_net_id == AtomNetId::INVALID()) {
warning_dialog_box("Invalid Net Name");
return; //name not exist
}

const auto clb_nets = atom_ctx.lookup().clb_nets(atom_net_id);
for (auto clb_net_id : clb_nets.value()) {
highlight_nets(clb_net_id);
if (draw_state->is_flat) {
AtomNetId atom_net_id = atom_ctx.netlist().find_net(net_name);
if (atom_net_id == AtomNetId::INVALID()) {
warning_dialog_box("Invalid Net Name");
app->refresh_drawing();
return;
}
if (is_net_unrouted(atom_net_id)) {
warning_dialog_box("Net is unrouted");
app->refresh_drawing();
return;
}
if (is_net_fully_absorbed(atom_net_id)) {
warning_dialog_box("Net is fully absorbed");
app->refresh_drawing();
return;
}
highlight_nets(convert_to_cluster_net_id(atom_net_id));
} else {
AtomNetId atom_net_id = atom_ctx.netlist().find_net(net_name);

if (atom_net_id == AtomNetId::INVALID()) {
warning_dialog_box("Invalid Net Name");
app->refresh_drawing();
return;
}
auto clb_net_ids_opt = atom_ctx.lookup().clb_nets(atom_net_id);
if (clb_net_ids_opt.has_value()) {
for (auto clb_net_id : clb_net_ids_opt.value()) {
highlight_nets(clb_net_id);
}
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions vpr/src/draw/search_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

#include "ezgl/application.hpp"

bool is_net_unrouted(AtomNetId atomic_net_id);
bool is_net_fully_absorbed(AtomNetId atomic_net_id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding Doxygen comments for these two functions would be better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a bit of digging through the codebase and found that the routing context includes a data structure called net_status, which has a method called is_routed. I think it would be better to use that instead of writing a custom function to determine whether a net is routed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functionality of is_net_fully_absorbed isn't specific to drawing, so I think it would be better to move it to the route_utils file rather than defining it here.


void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app);
bool highlight_rr_nodes(RRNodeId hit_node);
void auto_zoom_rr_node(RRNodeId rr_node_id);
Expand Down