Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ bazel_dep(name = "bazel-orfs")
# To bump version, run: bazelisk run @bazel-orfs//:bump
git_override(
module_name = "bazel-orfs",
commit = "f8a4b694b37c8f5322323eba9a9ae37f9541ee17",
commit = "d998bbff78c455718bd1a0191b4aa89ef9addac1",
remote = "https://github.com/The-OpenROAD-Project/bazel-orfs.git",
)

# Transitive dep of bazel-orfs (lives in its verilog/ subdirectory).
bazel_dep(name = "bazel-orfs-verilog")
archive_override(
module_name = "bazel-orfs-verilog",
strip_prefix = "bazel-orfs-e46fca0214def95ecfbada54a8028da7d47fd122/verilog",
urls = ["https://github.com/The-OpenROAD-Project/bazel-orfs/archive/e46fca0214def95ecfbada54a8028da7d47fd122.tar.gz"],
)

bazel_dep(name = "rules_python", version = "1.8.5")
bazel_dep(name = "rules_shell", version = "0.6.1")

Expand All @@ -35,12 +43,50 @@ orfs = use_extension("@bazel-orfs//:extension.bzl", "orfs_repositories")

# To bump version, run: bazelisk run @bazel-orfs//:bump
orfs.default(
image = "docker.io/openroad/orfs:v3.0-3273-gedf3d6bf",
image = "docker.io/openroad/orfs:26Q1-816-gf40d2f346",
# Use local files instead of docker image
makefile = "//flow:makefile",
makefile_yosys = "//flow:makefile_yosys",
pdk = "//flow:asap7",
sha256 = "f5692c6325ebcf27cc348e033355ec95c82c35ace1af7e72a0d352624ada143e",
sha256 = "2b05a14ae8062b4af82b245d648e95fa0293e09b61b57468518b66578744afb8",
variables_yaml = "//flow:scripts/variables.yaml",
)
use_repo(orfs, "com_github_nixos_patchelf_download")
use_repo(orfs, "docker_orfs")

# Uncomment to build OpenROAD from source instead of using the ORFS image.
# This is useful to test the latest OpenROAD before the ORFS image is updated.
# See: https://github.com/The-OpenROAD-Project/bazel-orfs/blob/main/docs/openroad.md
#
# bazel_dep(name = "openroad")
# git_override(
# module_name = "openroad",
# commit = "df79404cd806cc435b3c3b53678ebf2441c31313",
# init_submodules = True,
# patch_strip = 1,
# patches = ["@bazel-orfs//:openroad-llvm-root-only.patch", "@bazel-orfs//:openroad-visibility.patch"],
# remote = "https://github.com/The-OpenROAD-Project/OpenROAD.git",
# )
# bazel_dep(name = "qt-bazel")
# git_override(
# module_name = "qt-bazel",
# commit = "df022f4ebaa4130713692fffd2f519d49e9d0b97",
# remote = "https://github.com/The-OpenROAD-Project/qt_bazel_prebuilts",
# )
# bazel_dep(name = "toolchains_llvm", version = "1.5.0")

# Auto-generate orfs_flow() targets from config.mk files.
# See bazel-orfs.md for usage.
orfs_designs = use_repo_rule("@bazel-orfs//private:designs.bzl", "orfs_designs")

orfs_designs(
name = "orfs_designs",
designs_dir = "//flow/designs:BUILD.bazel",
platforms = [
"asap7",
"gf180",
"ihp-sg13g2",
"nangate45",
"sky130hd",
"sky130hs",
],
)
4,289 changes: 401 additions & 3,888 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

292 changes: 292 additions & 0 deletions bazel-orfs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
# bazel-orfs Beta Test

This is an early integration of [bazel-orfs](https://github.com/The-OpenROAD-Project/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 -- 59 designs across 6 public PDK platforms have
`orfs_design()` enabled. 53 pass QoR tests; 6 designs are blocked on
upstream fixes (see below). Platforms without public PDK files (gf12,
gf55, rapidus2hp) are not wired up.

## Quick Start

```bash
# 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 (53 passing tests + 6 blocked)

All designs below have `orfs_design()` enabled. Designs marked
**(blocked)** fail due to upstream issues in bazel-orfs or the
design's verilog sources.

### asap7 (18 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 |
| `riscv32i-mock-sram` | riscv_top | **(blocked)** PSM-0069 VDD connectivity |
| `mock-cpu` | mock_cpu | mock CPU with FIFO |
| `swerv_wrapper` | swerv_wrapper | SweRV EH1 |
| `cva6` | cva6 | CVA6 RISC-V (~63 min) |
| `mock-alu` | MockAlu | mock ALU |

### 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 (16 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 |
| `ariane133` | ariane | hierarchical |
| `ariane136` | ariane | hierarchical |
| `black_parrot` | black_parrot | **(blocked)** MPL-0020 macro name mismatch |
| `bp_be_top` | bp_be_top | BP back-end |
| `bp_fe_top` | bp_fe_top | BP front-end |
| `bp_multi_top` | bp_multi_top | **(blocked)** OpenROAD crash in CTS |
| `bp_quad` | black_parrot | **(blocked)** yosys check -assert fails |
| `mempool_group` | mempool_group | **(blocked)** SV macro undefined in synth |
| `swerv_wrapper` | swerv_wrapper | SweRV wrapped |

### gf180 (6 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 |
| `uart-blocks` | uart | hierarchical with uart_rx block |

### ihp-sg13g2 (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 |
| `spi` | spi | SPI controller |
| `i2c-gpio-expander` | I2cGpioExpanderTop | **(blocked)** PAD-0102 IO pad instance not found |

### 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 Not Supported

### 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`:

```starlark
load("@bazel-orfs//:openroad.bzl", "orfs_design")
load("@orfs_designs//:designs.bzl", "DESIGNS")

exports_files(glob(["*"]))

orfs_design(designs = DESIGNS)
```

2. If `flow/designs/src/<name>/BUILD.bazel` doesn't exist, create it:

```starlark
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"],
)
```

3. 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`:

```starlark
# 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:

```starlark
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:

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

A full test suite run (53 designs, 6 platforms) takes roughly 4-5 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:

```bash
# 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.
- **black_parrot**: macro_placement.tcl references macro names that
don't match the synthesized netlist (MPL-0020).
- **bp_multi_top**: OpenROAD crashes (SIGSEGV) during CTS timing
analysis.
- **bp_quad**: yosys `check -assert` finds 9 problems during synthesis.
- **i2c-gpio-expander**: IO pad instance `sg13g2_IOPad_io_gpio_3` not
found during floorplan (PAD-0102).
- **mempool_group**: SystemVerilog macros (`AXI_TYPEDEF_RESP_T` etc.)
are undefined -- likely a missing include path in the bazel build.
- **riscv32i-mock-sram**: VDD connectivity check fails at final stage
(PSM-0069) -- fakeram macro power pins are unconnected.
- This is a beta -- expect rough edges. File issues at
https://github.com/The-OpenROAD-Project/bazel-orfs/issues
4 changes: 3 additions & 1 deletion docs/user/FlowVariables.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ configuration file.
| <a name="DPO_MAX_DISPLACEMENT"></a>DPO_MAX_DISPLACEMENT| Specifies how far an instance can be moved when optimizing.| 5 1|
| <a name="EARLY_SIZING_CAP_RATIO"></a>EARLY_SIZING_CAP_RATIO| Ratio between the input pin capacitance and the output pin load during initial gate sizing.| |
| <a name="ENABLE_DPO"></a>ENABLE_DPO| Enable detail placement with improve_placement feature.| 1|
| <a name="EQUIVALENCE_CHECK"></a>EQUIVALENCE_CHECK| Enable running equivalence checks to verify logical correctness of repair_timing.| 0|
| <a name="EQUIVALENCE_CHECK"></a>EQUIVALENCE_CHECK| Enable writing equivalence check files to verify logical correctness of repair_timing. Set RUN_EQY to actually run the eqy tool.| 0|
| <a name="FASTROUTE_TCL"></a>FASTROUTE_TCL| Specifies a Tcl script with commands to run before FastRoute.| |
| <a name="FILL_CELLS"></a>FILL_CELLS| Fill cells are used to fill empty sites. If not set or empty, fill cell insertion is skipped.| |
| <a name="FILL_CONFIG"></a>FILL_CONFIG| JSON rule file for metal fill during chip finishing.| |
Expand Down Expand Up @@ -253,6 +253,7 @@ configuration file.
| <a name="RTLMP_RPT_DIR"></a>RTLMP_RPT_DIR| Path to the directory where reports are saved.| |
| <a name="RTLMP_WIRELENGTH_WT"></a>RTLMP_WIRELENGTH_WT| Weight for half-perimiter wirelength.| 100.0|
| <a name="RULES_JSON"></a>RULES_JSON| json files with the metrics baseline regression rules. In the ORFS Makefile, this defaults to $DESIGN_DIR/rules-base.json, but ORFS does not mandate the users source directory layout and this can be placed elsewhere when the user sets up an ORFS config.mk or from bazel-orfs.| |
| <a name="RUN_EQY"></a>RUN_EQY| Actually run the eqy equivalence checking tool. Requires EQUIVALENCE_CHECK to be enabled and eqy to be installed.| 0|
| <a name="RUN_LOG_NAME_STEM"></a>RUN_LOG_NAME_STEM| Stem of the log file name, the log file will be named `$(LOG_DIR)/$(RUN_LOG_NAME_STEM).log`.| run|
| <a name="RUN_SCRIPT"></a>RUN_SCRIPT| Path to script to run from `make run`, python or tcl script detected by .py or .tcl extension.| |
| <a name="SC_LEF"></a>SC_LEF| Path to technology standard cell LEF file.| |
Expand Down Expand Up @@ -489,6 +490,7 @@ configuration file.
- [PRE_CTS_TCL](#PRE_CTS_TCL)
- [REMOVE_CELLS_FOR_EQY](#REMOVE_CELLS_FOR_EQY)
- [REPORT_CLOCK_SKEW](#REPORT_CLOCK_SKEW)
- [RUN_EQY](#RUN_EQY)
- [SETUP_REPAIR_SEQUENCE](#SETUP_REPAIR_SEQUENCE)
- [SETUP_SLACK_MARGIN](#SETUP_SLACK_MARGIN)
- [SKIP_CRIT_VT_SWAP](#SKIP_CRIT_VT_SWAP)
Expand Down
Loading
Loading