DRT reroute#10800
Conversation
Signed-off-by: osamahammad21 <osama@precisioninno.com>
There was a problem hiding this comment.
Code Review
This pull request enables detailed routing to resume from a configured iteration (skipping initial rip-up passes) when DRC markers are already present in the loaded design. It implements database parsing of DRC markers, registers them in the region query, and aligns the routing strategy loop with the starting iteration. The review feedback highlights three key areas for improvement: resolving a potential memory leak/overhead by clearing gcell2BoundaryPin_ when resuming from an iteration greater than 0, preventing undefined behavior/out-of-bounds access if iter_ is negative, and ensuring DRC markers on cut layers are not silently ignored by falling back to the layer's short constraint when the recheck constraint is null.
| const int num_db_markers = getDesign()->getTopBlock()->getNumMarkers(); | ||
| if (num_db_markers > 0) { | ||
| iter_ = router_cfg_->REROUTE_VIOLATIONS_START_ITER; | ||
| if (router_cfg_->VERBOSE > 0) { | ||
| logger_->info(DRT, | ||
| 627, | ||
| "Found {} DRC marker(s) in the database; resuming detailed " | ||
| "routing from iteration {}.", | ||
| num_db_markers, | ||
| iter_); | ||
| } | ||
| } |
There was a problem hiding this comment.
If iter_ starts at REROUTE_VIOLATIONS_START_ITER (which is greater than 0), the boundary pin query data structure gcell2BoundaryPin_ is initialized in init() but never cleared, because removeGCell2BoundaryPin() is only called at the end of iteration 0 (when !iter_ is true). This results in a significant memory overhead/leak for the entire routing process.
To prevent this, we should immediately clear gcell2BoundaryPin_ if we resume from an iteration greater than 0.
const int num_db_markers = getDesign()->getTopBlock()->getNumMarkers();
if (num_db_markers > 0) {
iter_ = std::max(0, router_cfg_->REROUTE_VIOLATIONS_START_ITER);
if (iter_ > 0) {
removeGCell2BoundaryPin();
}
if (router_cfg_->VERBOSE > 0) {
logger_->info(DRT,
627,
"Found {} DRC marker(s) in the database; resuming detailed "
"routing from iteration {}.",
num_db_markers,
iter_);
}
}| = strategy(router_cfg_->ROUTESHAPECOST, router_cfg_->MARKERCOST); | ||
| // iter_ may start > 0 when resuming from imported DRC markers; index the | ||
| // strategy table by iter_ so the per-iteration parameters stay aligned. | ||
| while (iter_ < static_cast<int>(search_repair_args.size())) { |
There was a problem hiding this comment.
If iter_ is configured to a negative value, the loop condition iter_ < static_cast<int>(search_repair_args.size()) will evaluate to true, but accessing search_repair_args[iter_] inside the loop will result in an out-of-bounds vector access. We should ensure iter_ >= 0 in the loop condition to prevent undefined behavior.
while (iter_ >= 0 && iter_ < static_cast<int>(search_repair_args.size())) {| auto* recheck = layer->getRecheckConstraint(); | ||
| if (recheck == nullptr) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
DRC markers on cut layers (vias) will be silently ignored because cut layers do not have a recheck constraint configured (unlike routing layers). To support rechecking and rerouting via violations, we should fall back to using the layer's short constraint if the recheck constraint is null.
| auto* recheck = layer->getRecheckConstraint(); | |
| if (recheck == nullptr) { | |
| continue; | |
| } | |
| auto* recheck = layer->getRecheckConstraint(); | |
| if (recheck == nullptr) { | |
| recheck = layer->getShortConstraint(); | |
| } | |
| if (recheck == nullptr) { | |
| continue; | |
| } |
Summary
io::Parser::setMarkers()reads markers from the"DRC"marker category in the DB and createsfrMarkers using each layer's recheck constraint, so DRT re-runs its own DRC over the marked regions and reroutes them.frRegionQuery::init()now registers the block's markers into the marker RTree so workers pick them up.FlexDR::main(): strategy loop is index-based oniter_; when the loaded design has DRC markers, routing resumes fromREROUTE_VIOLATIONS_START_ITER(default 3), skipping the initial full rip-up passes.RouterConfiguration::REROUTE_VIOLATIONS_START_ITER(serialized for distributed mode).ispd18_sample_rerouteregression test (registered in CMake + Bazel).Type of Change
Impact
detailed_routeimports them and reroutes only the violating regions, starting from iteration 3.Verification
./etc/Build.sh).Related Issues