Replies: 3 comments 2 replies
-
|
@MrAMS FYI |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
This is cool! I'd be interested to try it out. |
Beta Was this translation helpful? Give feedback.
1 reply
-
|
It sounds useful. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
The Problem
You change
PLACE_DENSITYin your config.mk. You run the flow. You wait 2 hours. It fails with a cryptic Make error because you also had a typo inADDITIONAL_LEFS. You fix it. Another 2 hours. This time it fails because the SDC file path was wrong.Every config.mk edit costs hours of wall-clock time before you find out if it's correct.
config.mk Is a DSL
If you look at config.mk files across ORFS designs, they all follow the same pattern: export a fixed set of variables (
PLATFORM,DESIGN_NAME,VERILOG_FILES,SDC_FILE,CORE_UTILIZATION, ...) that control the flow. This isn't freeform Make — it's a domain-specific language for configuring chip builds. Recognizing this means we can parse it, validate it, and catch errors without running the actual flow.What If You Could Know in Seconds?
I, with the help of Claude, built a linting flow that validates your entire config.mk — all stages, synthesis through final — in under 1 second per design. It catches:
It does this by running the real ORFS Makefile and scripts with lightweight mock tools that create stub outputs instead of doing actual EDA processing.
RTLIL: Fast Precursor to Full Synthesis
The one step that does run for real is yosys RTLIL generation — a fast pass that reads all your verilog, resolves the module hierarchy, and writes out an intermediate representation. This takes seconds even for large designs, compared to hours for full synthesis with technology mapping and optimization. But it tells us almost everything we need: are all files found? do all modules exist? do port connections match? is the hierarchy complete?
After RTLIL, the remaining stages (floorplan through final) run with mock-openroad — a ~100 line Python stub that creates empty output files so Make thinks each stage completed. The whole flow, all stages, completes in seconds.
Results So Far
51 ORFS designs across 6 platforms (asap7, sky130hd, sky130hs, nangate45, ihp-sg13g2, gf180) all pass the linting flow. Total time: under 30 seconds for all 51 designs.
Along the way, the linting flow caught real bugs in ORFS configs that had been hiding because nobody runs the full flow on every design regularly:
VERILOG_FILES(riscv32i, swerv_wrapper)specifyblocks that yosys can't parse (nangate45 fakeram .v)How It Works
The linting flow uses bazel-orfs, which wraps the same ORFS Makefile and scripts you already use. Your config.mk stays exactly the same — no changes needed. A parser reads it and generates build targets automatically. For each design you get two sets of targets: the real flow (uses the Docker image, takes hours) and the lint flow (uses mock tools, takes seconds). You can run either without touching any files.
What's Next
Better Error Messages
Right now, errors come from yosys or Make — not always human-friendly. The mock tools can be extended to validate ORFS variables (is
CORE_UTILIZATIONin range? does the SDC clock name match a port?), check file existence upfront, and report clear diagnostics before the flow even starts.Incremental Caching
Because each stage is a separate build target, changing
PLACE_DENSITYonly rebuilds placement and later stages — synthesis is cached. This works for both real and lint flows.Flow Rules Check (FRC)
Think of this like Design Rule Check but for flow configuration. Each check is a unit test against the mock tools. Over time we build up a library of checks:
Interested in Trying This?
I'm keeping this work in bazel-orfs for now rather than sending patches to ORFS directly. The ORFS changes needed (config.mk parser, BUILD files, some config.mk fixes) are maintained as patches inside bazel-orfs. This has a couple of advantages:
origin/mainof bazel-orfs — it pulls in ORFS and applies the patches automatically. No need to maintain a custom ORFS fork or juggle branches.Once the linting flow is stable and the ORFS patches are minimal and well-tested, I'll file them as individual PRs to ORFS.
Thoughts? Questions?
Beta Was this translation helpful? Give feedback.
All reactions