Skip to content

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

Draft
oharboe wants to merge 20 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 20 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

Add BUILD.bazel files for all asap7 and sky130hd designs using the
orfs_design() macro from bazel-orfs, which auto-generates flow targets
from existing config.mk files. Designs that don't yet work have the
orfs_design() call commented out with a note explaining what's missing
(typically a source BUILD.bazel with :verilog filegroup).

Working designs: gcd, gcd-ccs, aes, aes-block, aes-mbff, aes_lvt,
ethmac, ethmac_lvt (asap7); gcd, aes (sky130hd).

Includes bazel-orfs.md guide for beta testers. The full 51-design
patch set remains out-of-tree in bazel-orfs/orfs/ to minimize churn.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@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 and others added 13 commits April 2, 2026 08:56
EQUIVALENCE_CHECK now only controls writing equivalence check files.
The new RUN_EQY variable (default 0) gates actually executing the eqy
tool, so builds don't fail when eqy is not installed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Cherry-pick from PRs The-OpenROAD-Project#4097 and The-OpenROAD-Project#4098. Removes unused
compatibility_level from module() and updates rules_python version
to match resolved dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Update rules-base.json via bazelisk run aes_cipher_top_update.
Hierarchical synth produces no synth area metric and has no clock
at block level, so timing thresholds are all 0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
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>
Update rules-base.json via bazelisk run aes_cipher_top_update.
Restore synth__design__instance__area__stdcell check now that
stat -hierarchy is used. Hierarchical block has no clock, so
timing thresholds are all 0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The plot_congestion Bazel target and .bzl file are unused and cause
a stale reference to @orfs-pip requirements.

Cherry-pick of PR The-OpenROAD-Project#4096.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Use SDC_FILE_EXTRA variable instead of hardcoded paths to source
mock-array/util.tcl. This works correctly in both Make and Bazel.

Cherry-pick of PR The-OpenROAD-Project#4093.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The platform default BLOCKS_grid_strategy.tcl produces empty PDN
grids. Use BLOCK_grid_strategy.tcl which has M4-M5 connections
matching the block's MAX_ROUTING_LAYER=M4 constraint.

Cherry-pick of PR The-OpenROAD-Project#4091.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Explicitly declare IO pad verilog, LEF, lib (all corners), and GDS
files for robustness, rather than relying on platform config.mk
conditional logic.

Cherry-pick of PR The-OpenROAD-Project#4090.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Update rules-base.json via bazelisk run aes_cipher_top_update.
Remove synth__design__instance__area__stdcell (not produced for
hierarchical synth in cached build). Hierarchical block has no
clock, so timing thresholds are all 0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Add documentation for updating metric thresholds via _update targets
and the EQUIVALENCE_CHECK/RUN_EQY separation. Update status to
reflect all 8 asap7 designs passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Explain that commits are spun off as separate PRs and this branch
is rebased as they merge.

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 e0b222d to 42d151d Compare April 2, 2026 06:56
Enable nangate45, gf180, ihp-sg13g2, and sky130hs platforms in
MODULE.bazel and flow/BUILD.bazel. Create BUILD.bazel files for all
design source directories and platform design directories. Unblock
previously blocked asap7/sky130hd designs that only needed src/
BUILD.bazel files.

Smoke-tested: gcd_test passes on all 4 new platforms.

Skipped platforms without public PDK: gf12, gf55, rapidus2hp.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@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

- Add exports_files(glob(["platforms/**"])) to flow/BUILD.bazel for
  ADDITIONAL_LEFS/LIBS from PLATFORM_DIR
- Add :verilog filegroups to chameleon, cva6, microwatt subdirs
- Add :include filegroups for VERILOG_INCLUDE_DIRS targets
- Add :lef/:lib/:gds filegroups for design-local macro files
- Add .cfg and .sv extensions to platform PDK globs
- Add BUILD.bazel for riscv32i-mock-sram/fakeram7_256x32 sub-design
- Add BUILD.bazel for src/mock-array (needed by mock-cpu)

All 701 targets pass analysis, builds are running.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@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 and others added 4 commits April 2, 2026 16:46
- Use specific file extensions in lef/lib/gds BUILD files to prevent
  BUILD.bazel from being picked up as a liberty/gds file
- Remove common_cells/include/common_cells package boundary so parent
  include filegroup can glob recursively into subdirectories
- Add allow_empty to gds globs (only .gds.gz files exist)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Update rules-base.json to match current flow output:
- Remove synth__design__instance__area__stdcell (N/A with
  SYNTH_HIERARCHICAL=1)
- Update constraints__clocks__count to 0 (hierarchical flow)
- Update area, timing, and wirelength thresholds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
…ket, sky130hd/microwatt

Update rules-base.json to match current flow output for newly
enabled bazel-orfs designs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
…orms

- Replace old 10-design list with full 46-design table across asap7,
  sky130hd, nangate45, gf180, ihp-sg13g2, sky130hs
- Document blocked designs with specific bazel-orfs fixes needed:
  hierarchical sub-design targets, specific file references,
  platform-local verilog, generated verilog
- Add performance notes on thread overcommitment and --jobs flag
- Update known limitations

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