Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
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());
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.

Copy link
Contributor Author

@w0lek w0lek May 27, 2025

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.

I just tested this approach, and it's not robust. It seems the net_status structure is filled only on --route stage, and never is filled with, let's say if we run vpr viewer in --analysis only stage. Due to this, if we run vpr viewer in analysis mode, the each net id will be reported as not routed if we attempt to use net_status structure.
With respect of this information, could i continue use

route_ctx.route_trees[net_id].has_value()

? I also may add TODO and comment explaining this.
Or we should think how to fix filling net_stats structure for all possible cases? About fixing net_status filling case, i think it more looks like separate issue.

Copy link
Contributor Author

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.

done 80675e3

Copy link
Contributor Author

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.

added 2e9a2d6

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems the net_status structure is filled only on --route stage

If you can file an issue on it, that would be good. Thanks!


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