Skip to content

flow: add OpenROAD built-in synth as _syn variant of every flat design#4253

Open
oharboe wants to merge 3 commits into
The-OpenROAD-Project:masterfrom
oharboe:orfs-syn-variant
Open

flow: add OpenROAD built-in synth as _syn variant of every flat design#4253
oharboe wants to merge 3 commits into
The-OpenROAD-Project:masterfrom
oharboe:orfs-syn-variant

Conversation

@oharboe
Copy link
Copy Markdown
Collaborator

@oharboe oharboe commented May 22, 2026

Summary

Adds OpenROAD's integrated synthesizer (sv_elaborate + synthesize,
introduced by 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
— 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, …):

bazelisk build //flow/designs/asap7/gcd:gcd_syn_synth   # OpenROAD-built-in synth
bazelisk build //flow/designs/asap7/gcd:gcd_synth       # existing Yosys synth (unchanged)
bazelisk test  //flow/designs/asap7/gcd:gcd_syn_test    # QoR check when RULES_JSON present

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. 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 (new target do-syn-synth) — one phony recipe that
    invokes $(OPENROAD_CMD) -no_init -exit $(SCRIPTS_DIR)/synth_syn.tcl.
    No existing recipe touched.
  • patches/bazel-orfs/0002-add-orfs_openroad_synth-…patch — 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.bzldesign() 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.

Test Plan

  • bazelisk build //flow/designs/asap7/gcd:gcd_syn_synth — runs
    OpenROAD on synth_syn.tcl via do-syn-synth; produces
    1_synth.odb + 1_synth.sdc under the _syn variant's results
    dir; log shows sv_elaborate / synthesize / syn::stats.
  • bazelisk build //flow/designs/asap7/gcd:gcd_synth — unchanged
    Yosys path; no regression.
  • bazelisk build //flow/designs/asap7/gcd:gcd_syn_final
    downstream _syn_* stages chain from the syn-produced
    1_synth.odb and reach 6_final.gds.
  • bazelisk build //...manual-tagged _syn variants stay
    out of wildcard builds; pre-existing chains build as before.

Why this layout vs. PR 10479's genrule + SYNTH_NETLIST_FILES

PR 10479 used a genrule to produce a Verilog netlist and fed it
through the existing Yosys-aware SYNTH_NETLIST_FILES escape hatch.
That works for Verilog-emitting drivers like its
synthesize_gcd.tcl. povik's synth_syn.tcl instead writes
1_synth.odb directly — so it slots in cleaner as a separate synth
rule alongside orfs_synth_rule rather than as a netlist feeder.

Notes for follow-up

  • The integrated synth tool is brand new; expect _syn_test
    baselines to drift until #10473 stabilises. The manual tag
    keeps that drift out of routine CI.
  • Hierarchical designs are deliberately skipped pending BLOCKS
    support in the integrated synthesizer.
  • When this lands upstream in bazel-orfs, drop
    patches/bazel-orfs/0002-…patch and bump BAZEL_ORFS_COMMIT.

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>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

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.

Comment thread flow/scripts/synth_syn.tcl Outdated
read_lef $lef
}
}
set_dont_use $::env(DONT_USE_CELLS)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The script will fail if the DONT_USE_CELLS environment variable is not defined in the environment. It should be guarded with a check to ensure robustness across different PDKs and designs.

if { [env_var_exists_and_non_empty DONT_USE_CELLS] } {
  set_dont_use $::env(DONT_USE_CELLS)
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

no

Comment thread flow/scripts/synth_syn.tcl Outdated
}
}

lappend elaborate_args {*}$::env(SYNTH_SLANG_ARGS)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The script will crash if SYNTH_SLANG_ARGS is not defined in the environment. Using env_var_or_empty provides a safe fallback for optional variables.

lappend elaborate_args {*}[env_var_or_empty SYNTH_SLANG_ARGS]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

no

Comment thread flow/scripts/synth_syn.tcl Outdated
Comment on lines +18 to +24
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]
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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"
  }
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yes

Comment thread flow/scripts/synth_syn.tcl Outdated
Comment on lines +62 to +64
if {$::env(DESIGN_NAME) == "cva6"} {
syn::remove_ports rvfi_probes_o
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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)
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

not for now

oharboe added 2 commits May 22, 2026 14:24
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant