grt: add updateNet for topology refresh in CUGR incremental routing#9671
grt: add updateNet for topology refresh in CUGR incremental routing#9671sparsh-karna wants to merge 9 commits intoThe-OpenROAD-Project:masterfrom
Conversation
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>
There was a problem hiding this comment.
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>
src/grt/src/cugr/src/CUGR.cpp
Outdated
| 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); |
There was a problem hiding this comment.
warning: argument name 'ripup' in comment does not match parameter name 'rip_up' [bugprone-argument-comment]
| 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)); |
There was a problem hiding this comment.
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); } |
There was a problem hiding this comment.
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>
|
clang-tidy review says "All clean, LGTM! 👍" |
| } | ||
| } | ||
|
|
||
| std::vector<CUGRPin> Design::readNetPins(odb::dbNet* db_net) |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
Instead of return, you can use an else here. It makes the code clearer and easier to follow.
| if (!tree) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
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.
| if (!node) { | ||
| return; | ||
| } |
| void GlobalRouter::updateNet(odb::dbNet* net) | ||
| { | ||
| if (use_cugr_) { | ||
| cugr_->updateNet(net); | ||
| } | ||
| } |
There was a problem hiding this comment.
This function seems CUGR specific. Make it clear in function name, with something like updateCUGRNet.
| void | ||
| update_net(odb::dbNet* net) | ||
| { | ||
| getGlobalRouter()->updateNet(net); | ||
| } |
There was a problem hiding this comment.
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.
| if (use_cugr_) { | ||
| cugr_->endIncremental(); | ||
| routes_ = cugr_->getRoutes(); | ||
| updatePinAccessPoints(); |
There was a problem hiding this comment.
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.
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, andlayer range from ODB in-place; handles brand-new nets created by
buffer insertion (net splits)
CUGR::updateNet(dbNet*)— rips up old routing tree, rebuildsCUGRNet/GRNet from scratch, registers new nets in gr_nets_,
net_indices_, and db_net_map_
GridGraph::commitTree()to prevent crash on freshlyallocated nets with no existing routing tree
endIncremental()so topology refresh happens beforererouteNets() runs
grt::update_netTcl command exposed via GlobalRouter.i SWIG bindingsrc/grt/test/incremental_update_net.tclTesting
asserts guides exist for the new net