flow: add OpenROAD built-in synth as _syn variant of every flat design#4253
flow: add OpenROAD built-in synth as _syn variant of every flat design#4253oharboe wants to merge 3 commits into
Conversation
Adds OpenROAD's integrated synthesizer (sv_elaborate + synthesize,
OpenROAD #10473) as a universal "_syn" variant of every flat
design driven by design() in flow/designs/design.bzl. Relocates
and generalises the throwaway smoke target from OpenROAD #10479,
which explicitly said the proper home for this was bazel-orfs /
ORFS, not OpenROAD's test tree.
Purely additive: no existing Makefile recipe, bazel rule, design,
or target's behaviour is altered. Pieces:
- flow/scripts/synth_syn.tcl (new) -- povik's driver. Reads
LEF/Liberty/SDC via the ORFS env vars and writes 1_synth.odb +
1_synth.sdc directly, bypassing the Yosys 1_2_yosys.v ->
synth_odb.tcl chain.
- flow/Makefile gains one new phony target do-syn-synth that
invokes openroad on synth_syn.tcl. No existing recipe touched.
- patches/bazel-orfs/0002-...patch adds a parallel
orfs_openroad_synth_rule + orfs_openroad_synth macro in
bazel-orfs. OrfsInfo shape matches orfs_synth_rule, so
orfs_flow(previous_stage = {"floorplan": ":<name>_syn_synth"})
chains downstream stages unchanged. Vendored here until the
integrated syn tool stabilises and this lands upstream.
- flow/designs/design.bzl -- design() now also emits the _syn
chain for every flat design via a DESIGNS lookup + helper.
Hierarchical designs (blocks non-empty) are skipped -- the
built-in synthesizer doesn't handle BLOCKS yet. All _syn
targets are tagged manual so bazel build //... is unaffected.
End state for every flat design:
bazelisk build //flow/designs/asap7/gcd:gcd_syn_synth # OpenROAD synth
bazelisk build //flow/designs/asap7/gcd:gcd_synth # Yosys (unchanged)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
There was a problem hiding this comment.
Code Review
This pull request introduces support for OpenROAD's integrated synthesizer as a parallel synthesis path. Key changes include a new Makefile target, a Tcl script for synthesis, and updates to the Bazel build logic to automatically generate a _syn variant for flat designs. Review feedback highlighted several opportunities to improve the robustness of the synth_syn.tcl script, such as adding guards for optional environment variables like DONT_USE_CELLS and SYNTH_SLANG_ARGS, improving path handling for include directories, and replacing design-specific hardcoding with generic configuration variables.
| read_lef $lef | ||
| } | ||
| } | ||
| set_dont_use $::env(DONT_USE_CELLS) |
There was a problem hiding this comment.
| } | ||
| } | ||
|
|
||
| lappend elaborate_args {*}$::env(SYNTH_SLANG_ARGS) |
| set vIdirsArgs "" | ||
| if { [env_var_exists_and_non_empty VERILOG_INCLUDE_DIRS] } { | ||
| foreach dir $::env(VERILOG_INCLUDE_DIRS) { | ||
| lappend vIdirsArgs "-I$dir" | ||
| } | ||
| set vIdirsArgs [join $vIdirsArgs] | ||
| } |
There was a problem hiding this comment.
Joining the list into a string and then using {*} to expand it later is redundant and can lead to issues if any directory paths contain spaces. It is better to keep vIdirsArgs as a list throughout.
set vIdirsArgs [list]
if { [env_var_exists_and_non_empty VERILOG_INCLUDE_DIRS] } {
foreach dir $::env(VERILOG_INCLUDE_DIRS) {
lappend vIdirsArgs "-I$dir"
}
}
| if {$::env(DESIGN_NAME) == "cva6"} { | ||
| syn::remove_ports rvfi_probes_o | ||
| } |
There was a problem hiding this comment.
Hardcoding design-specific logic like this reduces the maintainability and reusability of the script. Consider using a generic environment variable (e.g., SYNTH_REMOVE_PORTS) that can be set in the design's configuration (e.g., in cva6/config.mk).
if { [env_var_exists_and_non_empty SYNTH_REMOVE_PORTS] } {
syn::remove_ports $::env(SYNTH_REMOVE_PORTS)
}
Reformat with tclfmt 0.7.0 — normalize line endings, replace tab
indentation with two spaces, and add spaces inside the `if { ... }`
brace expression. Pure formatting; no behavior change. Fixes the
Tclint CI job on PR The-OpenROAD-Project#4253.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Build vIdirsArgs with `[list]` + `lappend` and let `{*}` expand it
directly into elaborate_args. The previous code joined the list into
a space-separated string and re-expanded it, which would corrupt any
include directory path containing whitespace.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Summary
Adds OpenROAD's integrated synthesizer (
sv_elaborate+synthesize,introduced by OpenROAD #10473)
as a universal
_synvariant of every flat design driven bydesign()inflow/designs/design.bzl. Relocates and generalisesthe throwaway smoke target from
OpenROAD #10479
— that PR explicitly said the proper home for this was
bazel-orfs / ORFS, not OpenROAD's test tree.
End state for every flat design (gcd, aes, ibex, jpeg, …):
Design
Purely additive. No existing Makefile recipe, bazel rule, design,
or target's behaviour is altered. The Yosys path stays exactly as it
is. Pieces:
flow/scripts/synth_syn.tcl(new) — povik's driver. ReadsLEF/Liberty/SDC via the ORFS env vars and writes
1_synth.odb+1_synth.sdcdirectly, bypassing the Yosys1_2_yosys.v→synth_odb.tclchain.flow/Makefile(new targetdo-syn-synth) — one phony recipe thatinvokes
$(OPENROAD_CMD) -no_init -exit $(SCRIPTS_DIR)/synth_syn.tcl.No existing recipe touched.
patches/bazel-orfs/0002-add-orfs_openroad_synth-…patch— parallelorfs_openroad_synth_rule+orfs_openroad_synthmacro inbazel-orfs. OrfsInfo shape matches
orfs_synth_rulesoorfs_flow(previous_stage = {"floorplan": ":<name>_syn_synth"})chains downstream stages unchanged. Vendored here until the
integrated syn tool stabilises and this lands upstream.
flow/designs/design.bzl—design()now also emits the_synchain for every flat design via a
DESIGNSlookup + helper.Hierarchical designs (
blocksnon-empty) are skipped — thebuilt-in synthesizer doesn't handle BLOCKS yet. All
_syntargets are tagged
manualsobazel build //...is unaffected.Test Plan
bazelisk build //flow/designs/asap7/gcd:gcd_syn_synth— runsOpenROAD on
synth_syn.tclviado-syn-synth; produces1_synth.odb+1_synth.sdcunder the_synvariant's resultsdir; log shows
sv_elaborate/synthesize/syn::stats.bazelisk build //flow/designs/asap7/gcd:gcd_synth— unchangedYosys path; no regression.
bazelisk build //flow/designs/asap7/gcd:gcd_syn_final—downstream
_syn_*stages chain from the syn-produced1_synth.odband reach6_final.gds.bazelisk build //...—manual-tagged_synvariants stayout of wildcard builds; pre-existing chains build as before.
Why this layout vs. PR 10479's
genrule + SYNTH_NETLIST_FILESPR 10479 used a genrule to produce a Verilog netlist and fed it
through the existing Yosys-aware
SYNTH_NETLIST_FILESescape hatch.That works for Verilog-emitting drivers like its
synthesize_gcd.tcl. povik'ssynth_syn.tclinstead writes1_synth.odbdirectly — so it slots in cleaner as a separate synthrule alongside
orfs_synth_rulerather than as a netlist feeder.Notes for follow-up
_syn_testbaselines to drift until #10473 stabilises. The
manualtagkeeps that drift out of routine CI.
support in the integrated synthesizer.
patches/bazel-orfs/0002-…patchand bumpBAZEL_ORFS_COMMIT.