Skip to content

grt: add updateNet for topology refresh in CUGR incremental routing#9671

Draft
sparsh-karna wants to merge 9 commits intoThe-OpenROAD-Project:masterfrom
sparsh-karna:grt/incremental-update-net
Draft

grt: add updateNet for topology refresh in CUGR incremental routing#9671
sparsh-karna wants to merge 9 commits intoThe-OpenROAD-Project:masterfrom
sparsh-karna:grt/incremental-update-net

Conversation

@sparsh-karna
Copy link

Summary

Extends the incremental CUGR routing API (introduced in #9645) with
topology refresh support. When buffer insertion changes a net's pin
list or adds new nets, the existing GRNet objects are stale. This PR
re-reads net topology from ODB before rerouting so the incremental
path operates on correct data.

Depends On

#9645 — must be reviewed/merged first.

Changes

  • Design::updateNet(dbNet*) — re-reads pins, BTerms, ITerms, and
    layer range from ODB in-place; handles brand-new nets created by
    buffer insertion (net splits)
  • CUGR::updateNet(dbNet*) — rips up old routing tree, rebuilds
    CUGRNet/GRNet from scratch, registers new nets in gr_nets_,
    net_indices_, and db_net_map_
  • Null guard in GridGraph::commitTree() to prevent crash on freshly
    allocated nets with no existing routing tree
  • Wired into endIncremental() so topology refresh happens before
    rerouteNets() runs
  • grt::update_net Tcl command exposed via GlobalRouter.i SWIG binding
  • Regression test: src/grt/test/incremental_update_net.tcl

Testing

  • Regression test splits a net, calls update_net, runs end_incremental,
    asserts guides exist for the new net
  • All existing grt regression tests unaffected

sparsh-karna and others added 7 commits March 5, 2026 23:03
Add addDirtyNet(), startIncremental(), and endIncremental() methods
to support incremental global routing in the CUGR engine, along with
dirty_net_indices_ and incremental_mode_ state tracking.

Signed-off-by: TheUnnamedOne-design <aditya07.11.04.12@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Signed-off-by: TheUnnamedOne-design <aditya07.11.04.12@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
…rtion

When repair_timing inserts a buffer, a net is split into two. The previous
incremental flow rerouted the stale GRNet objects from init() — pin list,
access points, and bounding box all predated the insertion.

Implement Design::updateNet() and CUGR::updateNet() to refresh per-net
CUGRNet/GRNet state from the database before rerouting. Wire into
endIncremental() and expose as grt::update_net Tcl command.

Also add null guard in GridGraph::commitTree() for freshly rebuilt nets
and a regression test exercising the full incremental update path.

Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for topology refresh in the incremental CUGR router, which is crucial for handling netlist changes from buffer insertion. The changes include new APIs to update net information from the database, integration into the incremental routing flow, and a new regression test. My review focuses on potential performance improvements and code maintainability. I've identified a few areas with redundant operations and code duplication that could be refactored for better efficiency and clarity.

Note: Security Review did not run due to the size of the PR.

Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

auto it = db_net_map_.find(db_net);
if (it != db_net_map_.end()) {
GRNet* gr_net = it->second;
grid_graph_->commitTree(gr_net->getRoutingTree(), /*ripup=*/true);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: argument name 'ripup' in comment does not match parameter name 'rip_up' [bugprone-argument-comment]

Suggested change
grid_graph_->commitTree(gr_net->getRoutingTree(), /*ripup=*/true);
grid_graph_->commitTree(gr_net->getRoutingTree(), /*rip_up=*/true);
Additional context

src/grt/src/cugr/src/GridGraph.h:117: 'rip_up' declared here

  void commitTree(const std::shared_ptr<GRTreeNode>& tree, bool rip_up = false);
                                                                ^


auto it = db_net_to_design_idx_.find(db_net);
if (it != db_net_to_design_idx_.end()) {
nets_[it->second].setPins(std::move(pins));
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "std::move" is directly included [misc-include-cleaner]

src/grt/src/cugr/src/Design.cpp:5:

- #include <vector>
+ #include <utility>
+ #include <vector>

int getNumPins() const { return pins_.size(); }
std::string getName() const { return db_net_->getName(); }
LayerRange getLayerRange() const { return layer_range_; }
void setPins(std::vector<CUGRPin> pins) { pins_ = std::move(pins); }
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "std::move" is directly included [misc-include-cleaner]

src/grt/src/cugr/src/Netlist.h:6:

- #include <vector>
+ #include <utility>
+ #include <vector>

… detours

Signed-off-by: Sparsh Karna <sparsh2005karna@gmail.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 2026

clang-tidy review says "All clean, LGTM! 👍"

@eder-matheus eder-matheus self-requested a review March 8, 2026 15:16
}
}

std::vector<CUGRPin> Design::readNetPins(odb::dbNet* db_net)
Copy link
Member

Choose a reason for hiding this comment

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

Good code refactoring. I'd suggest renaming the function to makeNetPins.

if (it != db_net_to_design_idx_.end()) {
nets_[it->second].setPins(std::move(pins));
nets_[it->second].setLayerRange(layer_range);
return;
Copy link
Member

Choose a reason for hiding this comment

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

Instead of return, you can use an else here. It makes the code clearer and easier to follow.

Comment on lines +603 to +605
if (!tree) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

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

It's odd to call this function for a tree that doesn't exists. I prefer having this check before the function call, only in the context where it makes sense.

Comment on lines +16 to +18
if (!node) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

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

Why is it needed?

Comment on lines +5861 to +5866
void GlobalRouter::updateNet(odb::dbNet* net)
{
if (use_cugr_) {
cugr_->updateNet(net);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This function seems CUGR specific. Make it clear in function name, with something like updateCUGRNet.

Comment on lines +161 to +165
void
update_net(odb::dbNet* net)
{
getGlobalRouter()->updateNet(net);
}
Copy link
Member

Choose a reason for hiding this comment

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

Add a comment expliciting that this function is only used for debug. I don't think we'll need a Tcl interface for the incremental CUGR project.

Also, rename it to be CUGR specific, similar to my other comment.

Comment on lines +342 to +345
if (use_cugr_) {
cugr_->endIncremental();
routes_ = cugr_->getRoutes();
updatePinAccessPoints();
Copy link
Member

Choose a reason for hiding this comment

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

This is consistent with how end incremental works for FastRouteCore, but you'll also need to look at how the IncrementalGRoute works. I would suggest to leave these changes in startIncremental and endIncremental out for now, and work on it in a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants