Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
261a625
odb: Add `dbSwapMasterSanityChecker` to validate hierarchical netlist…
jhkim-pii Feb 19, 2026
4542c51
test: Add `set_debug_level ODB replace_design_check_sanity 1` for reg…
jhkim-pii Feb 19, 2026
d6b5f06
odb: Fix lint issues
jhkim-pii Feb 19, 2026
15b1c01
odb: Refactor `dbSwapMasterSanityChecker` methods to return void, imp…
jhkim-pii Feb 19, 2026
1a601fa
Update to build with multi-mode STA
povik Jan 28, 2026
0b2e66e
Drop `sta::network_changed` from tests
povik Jan 29, 2026
c332706
Regolden tests after STA update
povik Feb 19, 2026
962c5e0
Update flow metrics after STA update
povik Feb 19, 2026
64a82a8
odb: Ensure `dbSwapMasterSanityChecker` exits early on structural int…
jhkim-pii Feb 19, 2026
a998009
rsz: Resolve compile warnings
povik Feb 19, 2026
c8adaaa
Merge branch 'master' of https://github.com/The-OpenROAD-Project-priv…
jhkim-pii Feb 20, 2026
8f86e2c
Fix clang-tidy warning: add missing <utility> header
jhkim-pii Feb 20, 2026
3096f08
Refactor dbSwapMasterSanityChecker to use fmt::format
jhkim-pii Feb 20, 2026
63a6f3b
Make warn/error variadic and use DfsState enum in sanity checker
jhkim-pii Feb 20, 2026
0c364cf
Fix clang-tidy misc-include-cleaner warning in sanity checker header
jhkim-pii Feb 20, 2026
61f8934
dbSta: Use fast related net lookup
povik Feb 20, 2026
21d54bd
dbSta: Provide sta::endpoint_path_count alias
povik Feb 20, 2026
805a1d9
Pull fix for write_timing_model crash
povik Feb 21, 2026
1b3a3b6
Update mock-array script for new STA
povik Feb 21, 2026
66f9499
Merge branch 'master' of https://github.com/The-OpenROAD-Project-priv…
jhkim-pii Feb 22, 2026
4659217
Use .size() directly instead of manual loop counting in sanity checker
jhkim-pii Feb 23, 2026
9a75c4e
Merge origin/master into secure-fix-swap-master
jhkim-pii Feb 23, 2026
9bb980a
Merge commit '1b3a3b6a76' into secure-fix-swap-master
jhkim-pii Feb 23, 2026
a3180cb
test/orfs/gcd: relax cts__timing__setup__tns threshold
jhkim-pii Feb 23, 2026
afade03
Merge branch 'master' of https://github.com/The-OpenROAD-Project-priv…
jhkim-pii Feb 24, 2026
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
10 changes: 9 additions & 1 deletion src/odb/include/odb/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -2555,7 +2555,10 @@ class dbNet : public dbObject
///
/// Check if this net is internal to the given module.
/// A net is internal if all its iterms belong to instances within the module
/// and it has no bterms.
/// (excluding sub-modules) and it has no bterms.
/// - A dbNet is also considered internal if it has a corresponding modnet
/// connected to a module output port that is unconnected in its parent
/// module (isInternalTo == true).
Comment on lines +2558 to +2561
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The comment for isInternalTo is updated to reflect the new logic, but the phrasing "(excluding sub-modules)" might be slightly ambiguous. It could be clearer to state that it refers to iterms directly within instances of the given module, not recursively within sub-modules instantiated inside it. Also, the second bullet point is a bit long and could be rephrased for better readability.

Suggested change
/// (excluding sub-modules) and it has no bterms.
/// - A dbNet is also considered internal if it has a corresponding modnet
/// connected to a module output port that is unconnected in its parent
/// module (isInternalTo == true).
/// A net is internal if all its iterms belong to instances directly within
/// the module (not recursively in sub-modules) and it has no bterms.
/// - A dbNet is also considered internal if it has a corresponding modnet
/// connected to an output port of the module that is unconnected in its
/// parent module (isInternalTo == true).

///
bool isInternalTo(dbModule* module) const;

Expand Down Expand Up @@ -8619,6 +8622,11 @@ class dbModNet : public dbObject
///
std::vector<dbModNet*> getNextModNetsInFanout() const;

///
/// Returns the first connected dbModNet in the parent module hierarchy.
///
dbModNet* getFirstParentModNet() const;

///
/// Traverses the hierarchy in search of the first mod net that satisfies the
/// given condition.
Expand Down
1 change: 1 addition & 0 deletions src/odb/src/db/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ add_library(db
dbGroupPowerNetItr.cpp
dbGroupGroundNetItr.cpp
dbGDSLib.cpp
dbSwapMasterSanityChecker.cpp
# Generator Code Begin cpp
dbAccessPoint.cpp
dbBusPort.cpp
Expand Down
6 changes: 6 additions & 0 deletions src/odb/src/db/dbModInst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "dbModNet.h"
#include "dbModuleModInstItr.h"
#include "dbModuleModInstModITermItr.h"
#include "dbSwapMasterSanityChecker.h"
#include "odb/dbBlockCallBackObj.h"
#include "odb/dbObject.h"
#include "odb/dbSet.h"
Expand Down Expand Up @@ -775,6 +776,11 @@ dbModInst* dbModInst::swapMaster(dbModule* new_module)
}
}

if (logger->debugCheck(utl::ODB, "replace_design_check_sanity", 1)) {
dbSwapMasterSanityChecker checker(new_mod_inst, new_module, logger);
checker.run();
}
Comment on lines +779 to +782
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The dbSwapMasterSanityChecker is instantiated and run here. This is a good place for the check, ensuring that the integrity of the netlist is maintained after a swapMaster operation. The debug level gating is also appropriate for controlling its execution.


return new_mod_inst;
}

Expand Down
21 changes: 21 additions & 0 deletions src/odb/src/db/dbModNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,15 @@ void dbModNet::dump() const
getParent()->getName(),
getParent()->getId());

dbNet* related_net = findRelatedNet();
if (related_net != nullptr) {
logger->report(" Related dbNet: {} (id={})",
related_net->getName(),
related_net->getId());
} else {
logger->report(" Related dbNet: <null>");
}
Comment on lines +267 to +274
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Adding the related_net information to the dump() method is very helpful for debugging hierarchical net connectivity. It provides immediate insight into the flat net associated with the dbModNet.


logger->report(" ModITerms ({}):", getModITerms().size());
for (dbModITerm* moditerm : getModITerms()) {
// For dbModITerm, get types from child dbModBTerm
Expand Down Expand Up @@ -730,6 +739,18 @@ std::vector<dbModNet*> dbModNet::getNextModNetsInFanout() const
return next_modnets;
}

dbModNet* dbModNet::getFirstParentModNet() const
{
for (dbModBTerm* mod_bterm : getModBTerms()) {
if (dbModITerm* parent_iterm = mod_bterm->getParentModITerm()) {
if (dbModNet* parent_net = parent_iterm->getModNet()) {
return parent_net;
}
}
}
return nullptr;
Comment on lines +742 to +751
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The getFirstParentModNet() implementation correctly iterates through dbModBTerms and their parent_iterms to find the connected dbModNet. This is a crucial helper function for the new isInternalTo logic.

}

dbModNet* dbModNet::findInHierarchy(
const std::function<bool(dbModNet*)>& condition,
dbHierSearchDir dir) const
Expand Down
22 changes: 22 additions & 0 deletions src/odb/src/db/dbModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,12 @@ void _dbModule::copyModuleInsts(dbModule* old_module,
}

// Check if the flat net is an internal net within old_module
// - If the old net is an internal net, a new net should be created.
// - If the old net is an external net, a new net will be created later
// by boundary IO handling logic.
// - Note that if old modnet is connected to a dbModBTerm and its
// corresponding dbModITerm is unconnected (has_parent_modnet == false),
// a new net should be created.
// - If old_module is uninstantiated module, every net in the module is
Comment on lines +892 to 898
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The updated comments provide a much clearer explanation of the isInternalTo logic and how it affects net creation during copyModuleInsts. This is essential for understanding the behavior of hierarchical module replacement.

// an internal net.
// e.g., No module instance.
Expand All @@ -901,6 +907,22 @@ void _dbModule::copyModuleInsts(dbModule* old_module,
// net_name = u0/_001_ <-- External net crossing module
// boundary.
std::string old_net_name = old_net->getName();
dbModNet* old_mod_net = old_iterm->getModNet();
bool has_parent_modnet
= (old_mod_net && old_mod_net->getFirstParentModNet());
if (old_net->isInternalTo(old_module) == false && has_parent_modnet) {
// Skip external net crossing module boundary.
// It will be connected later.
debugPrint(logger,
utl::ODB,
"replace_design",
3,
" Skip: non-internal dbNet '{}' of old_module '{}'.\n",
old_net_name,
old_module->getHierarchicalName());
continue;
Comment on lines +910 to +923
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The new logic correctly identifies and skips external nets that cross module boundaries, preventing duplicate net creation. This directly addresses the issue of incorrect net handling during hierarchical module replacement, which is a significant correctness improvement.

}

new_net_name += block->getBaseName(old_net_name.c_str());
auto it = new_net_name_map.find(new_net_name);
if (it != new_net_name_map.end()) {
Expand Down
Loading