Skip to content

Local OpenROAD-SYN QoR signal: forced-engine variants, fast synth tier, asap7 suites, syn-dashboard#4365

Open
oharboe wants to merge 8 commits into
The-OpenROAD-Project:masterfrom
oharboe:syn-local-signal
Open

Local OpenROAD-SYN QoR signal: forced-engine variants, fast synth tier, asap7 suites, syn-dashboard#4365
oharboe wants to merge 8 commits into
The-OpenROAD-Project:masterfrom
oharboe:syn-local-signal

Conversation

@oharboe

@oharboe oharboe commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

The local counterpart of the Jenkins QoR signal (https://dashboard.precisioninno.com/), built through Bazel so the OpenROAD-SYN loop can be sharpened onto exactly the design, engine, and stage being worked on — fast enough for an agent (e.g. Claude) to iterate against. Supersedes #4363, which bundled status graphs and opt-in LEC (closed, parked there for revival).

What this adds

Every design gets manual forced-engine flow variants from the config.mk DSL, regardless of the engine its config.mk selects: <name>_syn_* pins SYNTH_USE_SYN=1 so any design can be tested under OpenROAD-SYN before its config.mk officially switches, and <name>_yosys_* pins yosys so the baseline stays reproducible after a switch (asap7/gcd today). gcd's single-process comparison now consumes the generated gcd_yosys_* variant instead of hand-rolling its own yosys flow.

Designs with a rules-base.json get two QoR tiers per variant, both checking the design's regular rules file with the regular checkMetadata.py — congruent with what Jenkins measures because the fast tier is a subset of the same gate, never a different metric:

  • <name>_<engine>_synth_test — synthesis only, gated on the synth__/constraints__ subset of the rules (make metadata-check-synth). Minutes. QoR-only: without LEC it cannot prove correctness, so it's for iterating, not concluding.
  • <name>_<engine>_test — the full flow against all rules: the real, dashboard-equivalent gate. It reuses the fast tier's synthesis action, so escalating from fast to full never repeats synthesis.
bazelisk test //flow/designs/asap7/jpeg:jpeg_encoder_syn_synth_test   # fastest signal, one design
bazelisk test //flow/designs/asap7/jpeg:jpeg_encoder_syn_test         # the real gate
bazelisk build //flow/designs/asap7/jpeg:jpeg_encoder_syn_route       # stage-level triage
bazelisk test --keep_going //flow/designs/asap7:syn_synth_test        # fast suite (14 designs)
bazelisk test --keep_going //flow/designs/asap7:syn_test              # full-flow suite

Displaying what you have is a separate concern from deciding what to build. bazelisk run //flow/designs:syn-dashboard prints a GitHub-markdown TL;DR over every forced-engine result already in bazel-testlogs — pass/fail per tier and engine, failing rule fields, result age — building nothing, pasteable into a PR as-is. See flow/designs/README.md for the loop.

The suites deliberately include designs that fail OpenROAD-SYN today — they are a status signal, not a green-only gate (see SYN_TEST_DESIGNS / SYN_SLOW_DESIGNS in flow/designs/asap7/BUILD).

Mechanism

  • bazel-orfs bump picks up Syn fast qor bazel-orfs#771 (no patches carried): SYNTH_USE_SYN=1 engine selection with logs/1_synth.json declared (without it, no Bazel test could gate synth__* metrics), the generic fast synthesis-stage QoR pre-check (its own <variant>_synth sub-variant sharing the flow's synth action), the orfs_update cp fix, and the orfs_design(extra=) hook the DSL uses.
  • ORFS side: metadata-check-synth / metadata-synth make targets (checkMetadata.py --only-prefix), genMetrics.py tolerance for synthesis-only trees, synth_syn.tcl always writing the 1_synth.v netlist (write_lec_verilog), the forced-engine variants in flow/designs/design.bzl, the two asap7 suites, and the dashboard.

Verified

Full flow under forced SYN and forced yosys on gcd (plus the regular gcd_test), fast tier green on uart and aes, aes-block failing its area rule honestly (synth__design__instance__area__stdcell), mock-alu failing to build (slang rejects). Sample dashboard output:

design SYN synth SYN flow yosys synth yosys flow failing rules last run
asap7/aes 1h ago
asap7/aes-block synth__design__instance__area__stdcell 1h ago
asap7/gcd just now
asap7/uart 1h ago

Full-suite syn_test status across all 14 designs will be reported here once the multi-hour run completes.

🤖 Generated with Claude Code

oharboe and others added 5 commits July 17, 2026 12:32
make metadata-check-synth gates a synthesis-only run on the
synth__/constraints__ subset of the design's regular RULES_JSON
(checkMetadata.py --only-prefix), and make metadata-synth runs
synth + metadata-generate + that check. No per-variant rules files:
the same rules-base.json that gates the full flow gates the fast
signal, keeping the two congruent.

genMetrics.py tolerates a synthesis-only tree (SDC falls back to
1_synth.sdc; grt/finish extraction is guarded; empty placeholder
netlists hash as absent, matching a make run that never wrote them).

synth_syn.tcl always writes the 1_synth.v gate-level netlist
(write_lec_verilog, stripping physical-only masters) so the Bazel
synth stage can declare it as an output in SYN mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Every design() gets manual full-flow variants that pin the synthesis
engine regardless of the config.mk default: <name>_syn_* forces
SYNTH_USE_SYN=1 so any design can be tested under OpenROAD-SYN before
its config.mk switches, and <name>_yosys_* forces the yosys engine so
the baseline stays reproducible after a switch (asap7/gcd today).

Designs with a rules-base.json get two QoR gates per variant, both
checking the design's regular rules file with the regular
checkMetadata.py — the local counterpart of the Jenkins/dashboard
signal: <name>_<engine>_test runs the full flow against all rules;
<name>_<engine>_synth_test is the minutes-scale iteration tier,
checking only the synth__/constraints__ subset while sharing its
synthesis action with the full-flow test.

//flow/designs/asap7:syn_test and :syn_synth_test aggregate the 14
suite designs (fastest first, known failures included by design — the
suites are a status signal, not a green-only gate; slow designs are
documented in SYN_SLOW_DESIGNS and reproduced individually).

gcd's single-process comparison consumes the generated gcd_yosys_*
variant instead of hand-rolling its own yosys-engine flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
bazelisk run //flow/designs:syn-dashboard prints a GitHub-flavored
markdown status table over the forced-engine QoR tests already built
in this workspace: per design, pass/fail for the fast synthesis tier
and the full flow under each engine, the failing rule fields harvested
from checkMetadata.py output, and the age of the newest result. It
reads bazel-testlogs only — builds nothing, so it is instant — and the
output pastes into a PR or issue as-is: the local TL;DR counterpart of
https://dashboard.precisioninno.com/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Documents the forced-engine variants, the two QoR tiers and their
congruence with the Jenkins dashboard signal, and the loop philosophy:
deciding what to test/build is a separate concern from displaying what
exists (bazelisk run //flow/designs:syn-dashboard).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Picks up The-OpenROAD-Project/bazel-orfs#771: SYNTH_USE_SYN=1 engine
selection in the synth stage (with logs/1_synth.json declared so QoR
tests can gate synth__* metrics), the fast synthesis-stage QoR
pre-check emitted for any flow with rules, the orfs_update
single-source cp fix, and the orfs_design extra hook that
flow/designs/design.bzl uses for the forced-engine variants.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>

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

Copy link
Copy Markdown
Contributor

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 a local OpenROAD-SYN testing loop, including a local status dashboard (syn-dashboard), test suites for asap7, and support for synthesis-only QoR checks. Feedback on the changes highlights three main areas for improvement: correcting the output path of write_lec_verilog in synth_syn.tcl to prevent Bazel build failures, executing metadata-synth prerequisites sequentially in utils.mk to avoid parallel make race conditions, and explicitly specifying UTF-8 encoding when reading log files in synDashboard.py to ensure cross-platform compatibility.

Comment thread flow/scripts/synth_syn.tcl
Comment thread flow/util/utils.mk Outdated
Comment thread flow/util/synDashboard.py Outdated
metadata-synth ran synth/metadata-generate/metadata-check-synth as
plain prerequisites, which race under make -j; run them as sequential
sub-makes instead. synDashboard.py reads test logs with an explicit
utf-8 encoding so non-UTF-8 host defaults cannot break parsing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe

oharboe commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

/gemini review

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

Copy link
Copy Markdown
Contributor

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 a fast local OpenROAD-SYN testing loop, including new test suites for asap7 designs, synthesis-only metadata checks, and a local markdown dashboard utility (synDashboard.py) to display test results. Feedback on the new dashboard script suggests making the XML parsing more robust against malformed attributes and renaming a generator variable to avoid shadowing an outer scope variable.

Comment thread flow/util/synDashboard.py Outdated
Comment thread flow/util/synDashboard.py Outdated
…loop var

Malformed failures/errors attributes now make the whole test.xml count
as "no result" (—) like a ParseError, instead of raising — or worse,
being swallowed per-attribute and rendering a green cell for a corrupt
file. Rename the generator variable shadowing the outer result.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe

oharboe commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

/gemini review

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

Copy link
Copy Markdown
Contributor

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 a fast local OpenROAD-SYN testing loop and a local QoR dashboard. It adds forced-engine flow variants (syn and yosys) for designs, defines test suites for asap7, and implements a synDashboard tool to display test results from bazel-testlogs. Additionally, it updates metadata checking and metrics generation to support synthesis-only runs. Feedback on the changes points out that the generated gate-level netlist in synth_syn.tcl is written to the current working directory instead of the designated results directory, which will cause Bazel builds to fail.

Comment thread flow/scripts/synth_syn.tcl
@oharboe

oharboe commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Full asap7 suite status (first complete run of both tiers)

bazelisk test --keep_going //flow/designs/asap7:syn_synth_test10/14 pass (mock-alu, mock-cpu, riscv32i fail to build — slang rejects; aes-block fails the area gate).

bazelisk test --keep_going //flow/designs/asap7:syn_test5/14 pass. This is the first time the synth-green designs meet the full-flow gates under OpenROAD-SYN, and it's the headline finding: synthesis QoR parity does not yet translate to flow QoR parity — aes, aes-mbff, ethmac, ethmac_lvt and uart all synthesize within their yosys-derived synth gates but fail timing from CTS onward.

bazelisk run //flow/designs:syn-dashboard (pasted as-is):

design SYN synth SYN flow yosys synth yosys flow failing rules last run
asap7/aes cts__timing__setup__tns 15m ago
asap7/aes-block synth__design__instance__area__stdcell, placeopt__design__instance__count__stdcell, detailedroute__route__wirelength 17m ago
asap7/aes-mbff cts__timing__setup__tns, globalroute__timing__setup__tns 15m ago
asap7/aes_lvt 17m ago
asap7/ethmac cts__timing__setup__ws, cts__timing__setup__tns, globalroute__timing__setup__ws, +3 more just now
asap7/ethmac_lvt cts__timing__setup__ws, cts__timing__setup__tns, globalroute__timing__setup__ws, +3 more just now
asap7/gcd 48m ago
asap7/gcd-ccs 19m ago
asap7/jpeg 3m ago
asap7/jpeg_lvt 3m ago
asap7/uart cts__timing__setup__ws, cts__timing__setup__tns, globalroute__timing__setup__ws, +3 more 22m ago

(mock-alu, mock-cpu, riscv32i are absent: their synthesis fails to build, so bazel records no test result — the FAILED TO BUILD entries in the suite output are the signal for those.)

Full-flow pass: gcd, gcd-ccs, aes_lvt, jpeg, jpeg_lvt. Interesting pair: aes fails cts__timing__setup__tns while aes_lvt (same RTL, LVT libs) passes — and jpeg passes end-to-end while ethmac misses timing broadly. These per-design, per-stage rule failures are exactly the loop targets this PR is meant to expose.

🤖 Generated with Claude Code

The bare-filename call keeps getting flagged in review as writing to
the CWD; state the proc's contract at the call site.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe requested a review from povik July 17, 2026 11:52
@oharboe

oharboe commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Small consumability note from testing this PR's head as a bazel-orfs git_override pin: flow/designs/gf180/aes fails to load — its BUILD passes a DESIGN_TYPE argument that isn't registered in flow/scripts/variables.yaml, so bazel-orfs's check_variables errors the package and any @orfs//... wildcard along with it (Unknown ORFS variable(s) in arguments: DESIGN_TYPE). Every package we actually consume loads clean; registering the variable (or dropping the argument) would make wildcards usable again.

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