diff --git a/src/pad/src/ICeWall.cpp b/src/pad/src/ICeWall.cpp index 6472300c60c..51643803bcd 100644 --- a/src/pad/src/ICeWall.cpp +++ b/src/pad/src/ICeWall.cpp @@ -256,6 +256,15 @@ void ICeWall::assignBump(odb::dbInst* inst, if (iterm->getNet() != net) { iterm->connect(net); } + + routing_map_.erase(iterm); + if (auto* prop = odb::dbStringProperty::find(iterm, kRdlRouteTargetProperty)) { + odb::dbProperty::destroy(prop); + } + if (auto* prop = odb::dbBoolProperty::find(iterm, kRdlDontRouteProperty)) { + odb::dbProperty::destroy(prop); + } + if (terminal) { auto already_assigned = std::ranges::find_if( routing_map_, @@ -275,10 +284,16 @@ void ICeWall::assignBump(odb::dbInst* inst, terminal->getNet()->getName()); } routing_map_[iterm] = terminal; + const std::string target_name + = std::string(terminal->getInst()->getName()) + "/" + + terminal->getMTerm()->getName(); + odb::dbStringProperty::create( + iterm, kRdlRouteTargetProperty, target_name.c_str()); terminal = nullptr; } if (dont_route) { routing_map_[iterm] = nullptr; + odb::dbBoolProperty::create(iterm, kRdlDontRouteProperty, true); } } diff --git a/src/pad/src/RDLRouter.cpp b/src/pad/src/RDLRouter.cpp index 76abf3c3474..f5657d50828 100644 --- a/src/pad/src/RDLRouter.cpp +++ b/src/pad/src/RDLRouter.cpp @@ -240,6 +240,18 @@ void RDLRouter::buildIntialRouteSet() if (assigned_route->second != nullptr) { iterm_pairs.push_back(assigned_route->second); } + } else if (auto* dont_route + = odb::dbBoolProperty::find(iterm, kRdlDontRouteProperty); + dont_route != nullptr && dont_route->getValue()) { + // Explicit -dont_route intent is persisted on the bump terminal so it + // survives write_db/read_db. + continue; + } else if (auto* target + = odb::dbStringProperty::find(iterm, kRdlRouteTargetProperty); + target != nullptr) { + if (auto* target_iterm = block_->findITerm(target->getValue().c_str())) { + iterm_pairs.push_back(target_iterm); + } } else { for (const auto& [piterm, targets] : iterm_targets) { if (iterm->getInst() != piterm->getInst()) { diff --git a/src/pad/src/RDLRouter.h b/src/pad/src/RDLRouter.h index 54ff722a3df..7511aaab572 100644 --- a/src/pad/src/RDLRouter.h +++ b/src/pad/src/RDLRouter.h @@ -39,6 +39,9 @@ class Logger; namespace pad { +inline constexpr char kRdlRouteTargetProperty[] = "PAD_RDL_ROUTE_TARGET"; +inline constexpr char kRdlDontRouteProperty[] = "PAD_RDL_DONT_ROUTE"; + struct DbNetPtrLess { bool operator()(const odb::dbNet* lhs, const odb::dbNet* rhs) const diff --git a/src/pad/test/rdl_route_assignments.reload.tcl b/src/pad/test/rdl_route_assignments.reload.tcl new file mode 100644 index 00000000000..fffc1753e2f --- /dev/null +++ b/src/pad/test/rdl_route_assignments.reload.tcl @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2026, The OpenROAD Authors + +source "helpers.tcl" + +read_db [make_result_file "rdl_route_assignments.odb"] + +rdl_route -layer metal10 -width 4 -spacing 4 "DVDD" + +set def_file [make_result_file "rdl_route_assignments.def"] +write_def $def_file +diff_files $def_file "rdl_route_assignments.defok" diff --git a/src/pad/test/rdl_route_assignments.tcl b/src/pad/test/rdl_route_assignments.tcl index a779b70f8f5..9ccd6e3519f 100644 --- a/src/pad/test/rdl_route_assignments.tcl +++ b/src/pad/test/rdl_route_assignments.tcl @@ -570,8 +570,10 @@ assign_io_bump -net VDD BUMP_11_11 -dont_route assign_io_bump -net DVDD BUMP_15_10 -terminal u_v18_16/DVDD assign_io_bump -net DVDD BUMP_14_12 -terminal u_v18_14/DVDD -rdl_route -layer metal10 -width 4 -spacing 4 "DVDD" +write_db [make_result_file "rdl_route_assignments.odb"] -set def_file [make_result_file "rdl_route_assignments.def"] -write_def $def_file -diff_files $def_file "rdl_route_assignments.defok" +# Reload in a separate process to verify explicit -terminal/-dont_route bump +# assignments survive a database checkpoint. +puts [exec [info nameofexecutable] -no_splash -no_init -exit \ + -threads [thread_count] \ + [file join [file dirname [info script]] "rdl_route_assignments.reload.tcl"] 2>@1]