odb: Add swapMaster sanity checker and fix net internality logic#9505
odb: Add swapMaster sanity checker and fix net internality logic#9505openroad-ci wants to merge 23 commits intoThe-OpenROAD-Project:masterfrom
Conversation
… integrity after `swapMaster` operations and refine `dbNet::isInternalTo` logic Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
…ressions using replace_hier_module or replace_arith_module commands Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
…lement iterative DFS for combinational loop detection, and initialize member pointers. Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Occurrences of `sta_->cmdMode()` should be read as TODOs for proper multi-mode handling later. Signed-off-by: Martin Povišer <povik@cutebit.org>
Now that the command has different behavior (drops constraints) it was breaking the tests. Signed-off-by: Martin Povišer <povik@cutebit.org>
Signed-off-by: Martin Povišer <povik@cutebit.org>
Signed-off-by: Martin Povišer <povik@cutebit.org>
…egrity failures to prevent invalid pointer dereferences and remove redundant dangling `dbModNet` checks. Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Signed-off-by: Martin Povišer <povik@cutebit.org>
…ate/OpenROAD into secure-fix-swap-master
Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Replace std::string concatenation with fmt::format for improved readability, reduced temporary allocations, and elimination of std::to_string calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
- Convert warn()/error() to variadic templates that accept fmt-style format strings directly, eliminating explicit fmt::format() at all call sites. - Replace magic int constants (0/1/2) for DFS state with a local DfsState enum for clarity. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Add NOLINT suppression for spdlog/fmt/fmt.h include which is used by the variadic warn/error templates but not recognized as direct usage by misc-include-cleaner. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
There was a problem hiding this comment.
Code Review
The pull request introduces a dbSwapMasterSanityChecker class to validate hierarchical netlist integrity after swapMaster operations. It also refines dbNet::isInternalTo logic and adds dbModNet::getFirstParentModNet() for improved hierarchical net handling. The sanity checker is integrated into dbModInst::swapMaster and enabled in various regression tests. The changes enhance code quality by adding robust integrity checks and improving hierarchical netlist management.
| dbModITerm* parent_iterm = bterm->getParentModITerm(); | ||
| if (parent_iterm == nullptr) { | ||
| error( | ||
| "{}: ModBTerm '{}' has null parent ModITerm", ctx, bterm->getName()); | ||
| continue; |
There was a problem hiding this comment.
Yes. So the sanity checker will report it as an error.
| if (state[v] == kInPath) { | ||
| // Found a cycle — collect instances in the loop | ||
| std::string loop_path; | ||
| bool in_loop = false; | ||
| for (int idx : path) { | ||
| if (idx == v) { | ||
| in_loop = true; | ||
| } | ||
| if (in_loop) { | ||
| if (loop_path.empty() == false) { | ||
| loop_path += " -> "; | ||
| } | ||
| loop_path += insts[idx]->getName(); | ||
| } | ||
| } | ||
| loop_path += " -> "; | ||
| loop_path += insts[v]->getName(); | ||
| error("{}: combinational loop detected: {}", ctx, loop_path); | ||
| return; |
| if (net->getBlock() != block) { | ||
| error("{}: ITerm '{}' of inst '{}' connected to net in wrong block", | ||
| ctx, | ||
| iterm->getName(), | ||
| inst->getName()); | ||
| } |
| if (iterm_count != bterm_count) { | ||
| error("{}: ModITerm count ({}) != ModBTerm count ({})", | ||
| ctx, | ||
| iterm_count, | ||
| bterm_count); | ||
| } |
| if (child->getMaster() == nullptr) { | ||
| error("{}: child ModInst '{}' has null master", ctx, child->getName()); | ||
| } | ||
| } |
| puts "number instances in verilog is $num_instances" | ||
|
|
||
| #set_debug_level RSZ replace_arith 1 | ||
| set_debug_level ODB replace_design_check_sanity 1 |
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) |
|
|
||
| #set_debug_level RSZ replace_arith 1 | ||
| #set_debug_level ODB replace_design 10 | ||
| set_debug_level ODB replace_design_check_sanity 1 |
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) | ||
| [INFO ODB-0496] swapMaster sanity check passed (0 failures) |
| set num_instances [llength [get_cells -hier *]] | ||
| puts "number instances in verilog is $num_instances" | ||
|
|
||
| set_debug_level ODB replace_design_check_sanity 1 |
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
Related net lookup for modnets existed in two variants: slow which performed consistency checking and fast without checking. Transition isPower/isGround to using the fast variant, and rename the slow variant to emphasize its checking purpose. Signed-off-by: Martin Povišer <povik@cutebit.org>
Provide an alias for a method renamed in OpenSTA 3.0 to fix some bazel-orfs tests. Signed-off-by: Martin Povišer <povik@cutebit.org>
Signed-off-by: Martin Povišer <povik@cutebit.org>
Signed-off-by: Martin Povišer <povik@cutebit.org>
…ate/OpenROAD into secure-fix-swap-master
|
clang-tidy review says "All clean, LGTM! 👍" |
|
Gemini added a bunch of useless comments in this PR. |
| for ([[maybe_unused]] dbModInst* mi : new_master_->getModInsts()) { | ||
| ++set_modinst_count; | ||
| } |
There was a problem hiding this comment.
Why not use new_master_->getModInsts().size() ? Likewise elsewhere.
src/odb/test/replace_hier_mod2.ok
Outdated
| -2.52 slack (VIOLATED) | ||
| -0.76 slack (VIOLATED) |
There was a problem hiding this comment.
Why does this PR change the timing? If it is expected then a secure CI is needed.
There was a problem hiding this comment.
This is the related ORFS PR.
The-OpenROAD-Project/OpenROAD-flow-scripts#3906
- Fortunately, there was no failure in both public & private PDKs.
I'll refresh the OR & ORFS PRs since the MCMM update is merged.
Replace manual counter increments with direct .size() calls for iterm_count and hash table set counts. Remove now-unnecessary loops that only existed for counting. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Merge latest master which includes STA MCMM update and various module changes. Regoldenized odb replace_hier_mod2.ok test output to reflect updated timing results. Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com> # Conflicts: # src/odb/test/replace_hier_mod2.ok
|
clang-tidy review says "All clean, LGTM! 👍" |
1 similar comment
|
clang-tidy review says "All clean, LGTM! 👍" |
Fixes #9489
Summary
dbSwapMasterSanityCheckerclass that validates hierarchical netlist integrity afterswapMasteroperations, running 8 comprehensive checks: structural integrity, port/pin matching, hierarchical net connectivity, flat net connectivity, instance hierarchy, hash table integrity, dangling object detection, and combinational loop detection.dbNet::isInternalTologic incopyModuleInststo correctly skip external nets that cross module boundaries (nets with a parent ModNet), preventing duplicate net creation during hierarchical module replacement.dbModNet::getFirstParentModNet()API to traverse the parent module hierarchy for connected ModNets.set_debug_level ODB replace_design_check_sanity 1and enabled in allreplace_hier_module/replace_arith_moduleregression tests.Test plan
replace_hier_mod{1..6},replace_hier_mod_report_checks,replace_hier_mod_undo2regressions updated with sanity checker outputreplace_arith_modules{1..3}regressions updated with sanity checker outputTestSwapMasterUnusedPortC++ unit test enables sanity checker.okfiles updated to include[INFO ODB-0496] swapMaster sanity check passed (0 failures)messages🤖 Generated with Claude Code