Skip to content

[RFQ] build: add bazel-orfs beta test for design builds#4094

Draft
oharboe wants to merge 9 commits intoThe-OpenROAD-Project:masterfrom
oharboe:bazel-orfs-beta-test
Draft

[RFQ] build: add bazel-orfs beta test for design builds#4094
oharboe wants to merge 9 commits intoThe-OpenROAD-Project:masterfrom
oharboe:bazel-orfs-beta-test

Conversation

@oharboe
Copy link
Copy Markdown
Collaborator

@oharboe oharboe commented Apr 1, 2026

bazel-orfs Beta Test

This is an early integration of bazel-orfs
into OpenROAD-flow-scripts. It lets you build ORFS designs with Bazel
using the same config.mk files you already have.

Status: beta -- 46 designs across 6 public PDK platforms build and
pass QoR tests. Platforms without public PDK files (gf12, gf55,
rapidus2hp) are not wired up.

Quick Start

# Install bazelisk (one-time) -- see https://github.com/bazelbuild/bazelisk
# Then, from the ORFS root:

# Synthesize gcd on asap7 (downloads Docker image on first run)
bazelisk build //flow/designs/asap7/gcd:gcd_synth

# Run through floorplan
bazelisk build //flow/designs/asap7/gcd:gcd_floorplan

# Full flow through final
bazelisk build //flow/designs/asap7/gcd:gcd_final

# Run the test (includes QoR regression check)
bazelisk test //flow/designs/asap7/gcd:gcd_test

# List all targets for a design
bazelisk query //flow/designs/asap7/gcd:all

Available Targets Per Design

Each enabled design gets these targets automatically from its config.mk:

Target suffix What it does
_synth Yosys synthesis
_floorplan Floorplan + I/O placement
_place Global + detailed placement
_cts Clock tree synthesis
_grt Global routing
_route Detailed routing
_final Final optimization + fill
_generate_abstract LEF/LIB abstract for hierarchical use
_generate_metadata Flow metadata (logs, reports)
_test Full flow + QoR regression check

Each stage depends on the previous one, so building _final runs the
entire flow.

Working Designs (46 passing tests)

All designs below have orfs_design() enabled and pass
bazelisk test with QoR regression checks.

asap7 (16 designs)

Design DESIGN_NAME Notes
gcd gcd smoketest, ~1 min
gcd-ccs gcd CCS lib model
aes aes_cipher_top medium
aes-block aes_cipher_top block variant
aes-mbff aes_cipher_top MBFF
aes_lvt aes_cipher_top LVT cells
ethmac ethmac Ethernet MAC
ethmac_lvt ethmac LVT cells
ibex ibex_core RISC-V core (slang)
jpeg jpeg_encoder JPEG encoder
jpeg_lvt jpeg_encoder LVT cells
uart uart UART
riscv32i riscv_top RISC-V RV32I
mock-cpu mock_cpu mock CPU with FIFO
swerv_wrapper swerv_wrapper SweRV EH1
cva6 cva6 CVA6 RISC-V (~63 min)

sky130hd (7 designs)

Design DESIGN_NAME Notes
gcd gcd smoketest
aes aes_cipher_top medium
ibex ibex_core RISC-V core
jpeg jpeg_encoder JPEG encoder
riscv32i riscv RISC-V RV32I
chameleon soc_core SoC with macros
microwatt microwatt POWER ISA core

nangate45 (7 designs)

Design DESIGN_NAME Notes
gcd gcd smoketest
aes aes_cipher_top medium
ibex ibex_core RISC-V core
jpeg jpeg_encoder JPEG encoder
dynamic_node dynamic_node_top_wrap NoC router
swerv swerv SweRV EH1
tinyRocket RocketTile RISC-V Rocket

gf180 (5 designs)

Design DESIGN_NAME Notes
aes aes_cipher_top medium
aes-hybrid aes_cipher_top hybrid variant
ibex ibex_core RISC-V core
jpeg jpeg_encoder JPEG encoder
riscv32i riscv RISC-V RV32I

ihp-sg13g2 (6 designs)

Design DESIGN_NAME Notes
gcd gcd smoketest
aes aes_cipher_top medium
ibex ibex_core RISC-V core
jpeg jpeg_encoder JPEG encoder
riscv32i riscv RISC-V RV32I
spi spi SPI controller

sky130hs (5 designs)

Design DESIGN_NAME Notes
gcd gcd smoketest
aes aes_cipher_top medium
ibex ibex_core RISC-V core
jpeg jpeg_encoder JPEG encoder
riscv32i riscv RISC-V RV32I

Designs Blocked on bazel-orfs Changes

These designs have BUILD.bazel with a commented-out orfs_design()
and a TODO(bazel-orfs) note. They need changes in bazel-orfs before
they can be enabled.

Hierarchical sub-design targets (riscv32i-mock-sram)

asap7/riscv32i-mock-sram uses include designs/asap7/riscv32i/config.mk
in its config.mk and has a fakeram7_256x32/ sub-design directory.
The orfs_designs rule generates spurious riscv_top_* targets in
the sub-design package from the parent config. This causes a build
failure because the sub-design lacks the parent's rules-base.json.

Fix: orfs_designs should only generate targets from config.mk
files that are directly in the scanned directory, not from included
configs resolved at Make-time.

Specific file references in VERILOG_FILES

Several designs list individual files in VERILOG_FILES from directories
other than the design's own src/ tree (e.g. $(DESIGN_HOME)/src/ariane133/ariane.sv2v.v
or $(DESIGN_HOME)/src/$(DESIGN_NAME)/pickled.v). The orfs_designs
rule resolves $(wildcard ...) patterns but does not handle explicit
file paths that use $(DESIGN_NAME) or $(DESIGN_NICKNAME).

Affected: nangate45: ariane133, ariane136, black_parrot, bp_be_top,
bp_fe_top, bp_multi_top, bp_quad, mempool_group, swerv_wrapper.

Fix: Extend the orfs_designs config.mk parser to resolve
$(DESIGN_NAME) and $(DESIGN_NICKNAME) variable references in
explicit file paths, not just in $(wildcard ...) patterns.

VERILOG_FILES from non-matching src directory

gf180/uart-blocks references src/uart-no-param/*.v -- a different
src directory than its own name.

Fix: The parser already handles $(DESIGN_NICKNAME) in wildcard
patterns; verify it also resolves when the source directory name
differs from the design directory name.

Platform-local verilog in VERILOG_FILES

ihp-sg13g2/i2c-gpio-expander adds $(PLATFORM_DIR)/verilog/sg13g2_io.v
to VERILOG_FILES and also references verilog from its own platform
design directory ($(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/*.v).

Fix: Support $(PLATFORM_DIR)/... file references in VERILOG_FILES
by resolving them against the PDK target.

Generated verilog (mock-alu)

asap7/mock-alu generates its verilog via src/mock-alu/generate_*.py
scripts. Needs a Bazel genrule to run the Python generator before
synthesis.

No VERILOG_FILES (minimal)

asap7/minimal is a test design with no VERILOG_FILES in config.mk
(empty SDC). Not expected to work with orfs_designs.

Platforms without public PDK

gf12, gf55, and rapidus2hp have design directories but no platform
files in the open-source repo. These are skipped entirely.

How to Add More Designs

  1. Create flow/designs/<platform>/<design>/BUILD.bazel:
load("@bazel-orfs//:openroad.bzl", "orfs_design")
load("@orfs_designs//:designs.bzl", "DESIGNS")

exports_files(glob(["*"]))

orfs_design(designs = DESIGNS)
  1. If flow/designs/src/<name>/BUILD.bazel doesn't exist, create it:
exports_files(
    glob(["*.v", "*.sv"], allow_empty = True),
    visibility = ["//visibility:public"],
)

filegroup(
    name = "verilog",
    srcs = glob(include = ["*.v", "*.sv"], allow_empty = True),
    visibility = ["//visibility:public"],
)
  1. Run bazelisk query //flow/designs/<platform>/<design>:all to verify.

Using a Local bazel-orfs Checkout

To iterate on bazel-orfs rules locally, replace the git_override in
MODULE.bazel:

# Comment out the git_override block, then add:
local_path_override(
    module_name = "bazel-orfs",
    path = "/path/to/your/bazel-orfs",
)

Also update the bazel-orfs-verilog override:

local_path_override(
    module_name = "bazel-orfs-verilog",
    path = "/path/to/your/bazel-orfs/verilog",
)

Key Differences from Make

  • Incremental: Bazel caches every stage. Changing PLACE_DENSITY
    in config.mk rebuilds only floorplan onward -- synthesis is cached.
  • Hermetic: Tools come from a Docker image (extracted automatically).
    No make install or PATH setup needed.
  • Parallel: Independent designs build in parallel automatically.
  • Reproducible: Same inputs always produce the same outputs.

Performance Notes

Each OpenROAD invocation uses -threads <nproc> (all available cores).
When Bazel runs many designs in parallel, the machine becomes heavily
overcommitted. On a 48-core machine, 50+ OpenROAD instances may run
simultaneously during a full bazelisk test ..., each requesting 48
threads.

To limit parallelism:

# Limit to 4 concurrent OpenROAD invocations
bazelisk test --jobs=4 ...

A full test suite run (46 designs, 6 platforms) takes roughly 3-4 hours
on a 48-core machine with default parallelism (overcommitted). Individual
design times vary from ~1 minute (gcd) to ~63 minutes (cva6 on asap7).

Updating Metric Thresholds

When OpenROAD or flow scripts change, metric thresholds in
rules-base.json may go stale. To update them for a specific design:

# Rebuilds the design and writes updated thresholds back to source
bazelisk run //flow/designs/asap7/aes-block:aes_cipher_top_update

The target name follows the pattern <design_name>_update where
<design_name> comes from DESIGN_NAME in config.mk.

Equivalence Checking (eqy)

Some designs (e.g. aes) set EQUIVALENCE_CHECK=1 in their
config.mk to enable equivalence checking of repair_timing. The
actual eqy tool invocation is gated by a separate RUN_EQY
variable (default 0), so builds don't fail when eqy is not installed.
CI sets RUN_EQY=1 when eqy is available.

Workflow: Unmerged Commits

This PR serves as a working branch against master. Commits here are
spun off as separate, focused PRs for review. Once a PR merges, this
branch is rebased on master to drop the merged commit. The branch is
force-pushed after each rebase so the PR commit list is always the
source of truth for what's pending.

Filing of PRs is throttled to avoid overwhelming maintainers --
submitting too many at once just causes "maintainer packet dropping"
where reviews stall.

Known Limitations

  • The Docker image is pinned; updating it requires changing
    MODULE.bazel.
  • Platforms without public PDK files (gf12, gf55, rapidus2hp) are not
    supported.
  • Some designs are blocked on bazel-orfs parser improvements (see above).
  • riscv32i-mock-sram hierarchical flow does not work yet.
  • This is a beta -- expect rough edges. File issues at
    https://github.com/The-OpenROAD-Project/bazel-orfs/issues

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 2, 2026

@jhkim-pii Would you take it for a spin and comment?

@oharboe oharboe changed the title [AT YOUR OWN PERIL] build: add bazel-orfs beta test for design builds [RFQ] build: add bazel-orfs beta test for design builds Apr 2, 2026
@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 2, 2026

@hzeller Thoughts?

@oharboe oharboe force-pushed the bazel-orfs-beta-test branch from e0b222d to 42d151d Compare April 2, 2026 06:56
@jhkim-pii
Copy link
Copy Markdown
Contributor

ORFS bazel works.
But there are many BUILD.bazel files. Is there a way to reduce the number of files?

/workspace/ws6/OpenROAD-flow-scripts/flow/designs/src/cva6 $ find . -name BUILD.bazel
./BUILD.bazel
./common/BUILD.bazel
./common/local/BUILD.bazel
./common/local/util/BUILD.bazel
./vendor/BUILD.bazel
./vendor/pulp-platform/BUILD.bazel
./vendor/pulp-platform/tech_cells_generic/BUILD.bazel
./vendor/pulp-platform/tech_cells_generic/src/rtl/BUILD.bazel
./vendor/pulp-platform/tech_cells_generic/src/BUILD.bazel
./vendor/pulp-platform/common_cells/BUILD.bazel
./vendor/pulp-platform/common_cells/src/BUILD.bazel
./vendor/pulp-platform/axi/BUILD.bazel
./vendor/pulp-platform/axi/src/BUILD.bazel
./core/BUILD.bazel
./core/include/BUILD.bazel
./core/pmp/BUILD.bazel
./core/pmp/src/BUILD.bazel
./core/frontend/BUILD.bazel
./core/cvxif_example/BUILD.bazel
./core/cvxif_example/include/BUILD.bazel
./core/cvfpu/BUILD.bazel
./core/cvfpu/src/BUILD.bazel
./core/cvfpu/src/fpu_div_sqrt_mvp/BUILD.bazel
./core/cvfpu/src/fpu_div_sqrt_mvp/hdl/BUILD.bazel
./core/cvfpu/src/common_cells/BUILD.bazel
./core/cvfpu/src/common_cells/include/BUILD.bazel
./core/cvfpu/src/common_cells/include/common_cells/BUILD.bazel
./core/cva6_mmu/BUILD.bazel
./core/cache_subsystem/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/include/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/src/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/src/common/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/src/common/macros/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/src/common/macros/blackbox/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/src/utils/BUILD.bazel
./core/cache_subsystem/hpdcache/rtl/src/hwpf_stride/BUILD.bazel
./core/cache_subsystem/hpdcache/BUILD.bazel

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 2, 2026

ORFS bazel works. But there are many BUILD.bazel files. Is there a way to reduce the number of files?

Not without making the use-case worse, you'd have to write something like bazelisk build @orfs//:..../designs/asap7/....

I think on the balance we're better off with having these copy and paste BUILD files. Over time, they will grow extra features I believe so they won't just be copy and paste.

Yes they pollute a bit, but the cognitive load should be small otherwise...

🤞

@oharboe oharboe force-pushed the bazel-orfs-beta-test branch 2 times, most recently from 9922302 to 5e676e5 Compare April 4, 2026 07:30
@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 5, 2026

@MrAMS Thoughts?

@oharboe oharboe mentioned this pull request Apr 6, 2026
oharboe and others added 7 commits April 7, 2026 21:41
When SYNTH_HIERARCHICAL=1, the yosys stat command reports zero area
for the top module because all cells are in submodules. Adding
-hierarchy makes stat include submodule area, so
synth__design__instance__area__stdcell is no longer N/A.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Updates rules-base.json for: asap7/aes-block, asap7/riscv32i,
asap7/mock-alu, gf180/aes-hybrid, gf180/uart-blocks,
nangate45/tinyRocket, nangate45/ariane133, nangate45/ariane136,
nangate45/bp_be_top, nangate45/bp_fe_top, nangate45/swerv_wrapper,
sky130hd/microwatt.
- Bump bazel-orfs to d998bbff78c4557
- Add bazel-orfs-verilog transitive dependency
- Update rules_python to 1.8.5, remove compatibility_level
- Bump ORFS Docker image to 26Q1-816-gf40d2f346
- Add variables_yaml to orfs.default()
- Add orfs_designs() repo rule for all 6 public-PDK platforms
- Add commented-out OpenROAD-from-source instructions
Add orfs_design() targets and exports_files() to all design
directories across asap7, gf180, ihp-sg13g2, nangate45, sky130hd,
and sky130hs platforms, plus their source directories.
Add bazel-orfs.md with quick start guide, available targets,
build results for 59 designs across 6 platforms, and status
of blocked designs.
Add transitive dependency overrides required by the new bazel-orfs:
openroad, qt-bazel, mock-klayout, glpk, and toolchains_llvm.
The new bazel-orfs builds OpenROAD from source by default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe oharboe force-pushed the bazel-orfs-beta-test branch from 5e676e5 to 9e801c4 Compare April 7, 2026 20:34
oharboe and others added 2 commits April 7, 2026 22:48
Use local_path_override to point the openroad module at the
tools/OpenROAD submodule rather than fetching from GitHub.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The rules_python bootstrap wrapper sets RUNFILES_DIR to its own
runfiles tree. When run_command.py spawned OpenROAD, it inherited
that variable and looked for Tcl init files in the Python runfiles
instead of its own, causing "application-specific initialization
failed" in Bazel builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants