synth: blackbox SYNTH_BLACKBOXES modules before hierarchy check#4212
synth: blackbox SYNTH_BLACKBOXES modules before hierarchy check#4212oharboe wants to merge 1 commit intoThe-OpenROAD-Project:masterfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for blackboxing modules during synthesis to facilitate parallel synthesis partitions. It adds logic to synth.tcl and synth_preamble.tcl to iterate through SYNTH_BLACKBOXES and apply the blackbox command with error handling. Feedback was provided regarding synth_preamble.tcl, noting that the hierarchy command should be moved outside the conditional block to ensure the design is elaborated regardless of whether blackboxing is performed.
89dc67e to
1cce1c4
Compare
Adds a checkpoint-based code path for SYNTH_BLACKBOXES to synth.tcl, distinct from the existing source-based path in synth_preamble.tcl in two intentional ways: it runs before `hierarchy -check -top` (the design is already elaborated when read from RTLIL, so blackbox operates on resolved modules), and it wraps `blackbox` in `catch` (unknown names are silently skipped because the same SYNTH_BLACKBOXES list is shared across partitions). The synth_preamble.tcl path keeps its existing strict behaviour: `hierarchy -check -top` first to elaborate the deferred verilog top, and `blackbox` errors loudly so a typo in a single-design SYNTH_BLACKBOXES list surfaces immediately. Why this is needed: parallel partition synthesis with slang. When `--keep-hierarchy` is used (required for partition flows that preserve internal hierarchy), the slang frontend mangles module names by their elaboration path so different parameterizations get distinct names — `Foo` instantiated at `top.unit.foo` becomes `Foo$top.unit.foo` in the elaborated RTLIL. The parent design references those mangled names. A "per-partition canonicalize from RTL" approach therefore can't just elaborate `Foo` as a fresh top — that would emit a module named `Foo`, but the parent design instantiates `Foo$top.unit.foo`, and the link fails. The driver has to canonicalize the full design once (so all parameterized instances get their elaborated names), and each partition then loads that shared checkpoint and blackboxes the modules outside its scope. That's the orchestrator pattern: every partition reads the same canonical RTLIL checkpoint and blackboxes the modules that belong to other partitions, so it only synthesises its own subhierarchy. SYNTH_BLACKBOXES is already documented in variables.yaml. No behaviour change when the env var is unset. Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
1cce1c4 to
269cfcb
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces logic to blackbox modules specified in SYNTH_BLACKBOXES when loading a design from an RTLIL checkpoint in flow/scripts/synth.tcl, supporting parallel synthesis flows. Feedback suggests improving the blackboxing mechanism to handle module name mangling (e.g., from the slang frontend) using pattern-based selection. Additionally, the PR description should be updated to resolve a contradiction with the code comments regarding the harmonization of this logic with synth_preamble.tcl.
Re-opening of #4211 after measuring the cost of the alternative.
Summary
Adds a checkpoint-based code path for
SYNTH_BLACKBOXEStosynth.tcland aligns the existing source-based path insynth_preamble.tclso all flows behave identically (usecatch, blackbox beforehierarchy -check -top).Why this is needed: parallel partition synthesis with slang
When
--keep-hierarchyis used (required for partition flows that preserve internal hierarchy), the slang frontend mangles module names by their elaboration path so different parameterizations get distinct names —Fooinstantiated attop.unit.foobecomesFoo$top.unit.fooin the elaborated RTLIL. The parent design references those mangled names.A "per-partition canonicalize from RTL" approach therefore can't just elaborate
Fooas a fresh top — that would emit a module namedFoo, but the parent design instantiatesFoo$top.unit.foo, and the link fails.The orchestrator pattern instead is: canonicalize the full design once (so all parameterized instances get their elaborated names), and each partition then loads that shared checkpoint and blackboxes the modules outside its scope. Every partition reads the same canonical RTLIL and only synthesises its own subhierarchy.
The same
SYNTH_BLACKBOXESlist can be reused across all partitions because unknown names are skipped silently withcatch { blackbox $m }instead of erroring.Cost evidence
Measured on an test case I can't share (46 partitions, ~3,500 s of synth CPU compressed into ~5 min wall via 12× parallelism): the shared canonicalize is 7 s (read_liberty 2 s + opt_clean 1.9 s + read_slang 1.5 s + misc) — necessary for slang to consistently mangle parameterised names across partitions, not optional bookkeeping.
Test plan
SYNTH_BLACKBOXESis unset