This project demonstrates a practical bazel-orfs workflow for a large RISC-V CPU design (MegaBoom from Chipyard) using the ASAP7 open PDK. It shows how to mock RAM macros to get early PPA (power, performance, area) results and refine them iteratively.
The top-level target is BoomTile, which synthesizes through routing with 15+ mocked SRAM macros and 2 register files.
Prerequisites:
- Bazelisk (or Bazel 8.3.1+)
- Docker (the ORFS tools run in a container)
Dependencies:
The bazel-orfs dependency and ORFS Docker image are configured in MODULE.bazel. To pin a different bazel-orfs version, update the git_override commit there.
Build the full flow (synthesis through routing):
bazelisk build BoomTile_routeView the design after clock tree synthesis in the OpenROAD GUI:
bazel run BoomTile_cts $(pwd)/tmp gui_ctsBuild time is on the order of 24 hours without a pre-built artifact cache.
rtl/ RTL source files (.sv, .v) generated from Chipyard
mock/ Mock SRAM implementations (.sv) replacing real SRAM compilers
snapshots/
kept.bzl List of modules preserved during hierarchical synthesis
macro_placement.tcl Macro placement from hierarchical floorplanning
BUILD.bazel All Bazel target definitions
MODULE.bazel Bazel module dependencies (bazel-orfs, Python, etc.)
constraints*.sdc Timing constraints
io-*.tcl IO pin placement constraints
util.tcl TCL utilities for pin matching
Real SRAM compilers are typically not available in open PDKs. This project mocks each RAM as synthesizable logic, sized to approximate a real SRAM's area. This lets you run the full physical design flow and get meaningful PPA estimates.
Each SRAM is defined in BUILD.bazel with parameters:
| Parameter | Description |
|---|---|
mock_area |
Target area multiplier for the mocked SRAM |
aspect_ratio |
Width/height ratio of the SRAM block |
core_utilization |
Cell utilization percentage (alternative to mock_area) |
SRAMs are synthesized through CTS (clock tree synthesis) and abstracted as macro LEF/LIB for use by the top-level BoomTile flow. To check SRAM metrics:
bazelisk build sram_reportThis generates a markdown table comparing each SRAM's dimensions and timing.
BoomTile uses hierarchical synthesis: the design is partitioned into ~96 sub-modules (listed in snapshots/kept.bzl) that are synthesized independently, then cleaned with najaeda (constant propagation and dead logic elimination) before physical design.
Key settings in BOOMTILE_VARIABLES:
- Die area: 1000x1000 um
- Placement density: 0.40
- Clock period: 1200 ps (833 MHz), defined in constraints-boomtile.sdc
- Timing margins: Relaxed (
SETUP_SLACK_MARGIN: -2500) to prioritize completing the flow
The flow generates three variants via orfs_sweep:
- base: Timing-driven placement with retiming
- macro: Provides macro placement for manual tuning
- hierarchical: Full hierarchical synthesis
The workflow for tuning the design:
-
Start with rough SRAM sizing. Set
mock_areaconservatively. Runbazelisk build sram_reportto compare mocked area against synthesized area. -
Adjust SRAM parameters. Tune
mock_areaandaspect_ratioto better match expected real SRAM dimensions. Smaller SRAMs useaspect_ratio; larger ones may needcore_utilizationinstead. -
Tune macro placement. The hierarchical flow auto-places macros. Extract placement with
bazelisk build write_macro_placement, copy snapshots withbazel run update, and manually adjust if needed. -
Visualize timing. After CTS, use
bazelisk build xy_statsandbazel run show_skewfor a 3D visualization of timing slack across the chip. -
Tighten timing margins. As the design converges, reduce
SETUP_SLACK_MARGINandHOLD_SLACK_MARGINfor more realistic results.
To use this project as a template for your own design:
-
Replace the RTL. Put your Verilog/SystemVerilog files in
rtl/. -
Identify RAM macros. Find memories in your design that should be treated as macros. Create mock implementations in
mock/and add them tomock_filesand the SRAM dictionaries inBUILD.bazel. -
Set up timing constraints. Create an SDC file with your clock period and IO timing. Update the
constraints-*filegroups. -
Set up IO constraints. Define pin placement in
io-*.tclfiles usingset_io_pin_constraint. -
Configure the top-level flow. Adjust
DIE_AREA,CORE_AREA,PLACE_DENSITY, and timing margins inBOOMTILE_VARIABLES(rename as appropriate for your design). -
Start coarse, refine iteratively. Begin with relaxed timing margins and generous die area. Tighten as results improve.
| Target | Description |
|---|---|
BoomTile_route |
Full flow: synthesis through routing |
BoomTile_synth |
Synthesis only |
BoomTile_cts |
Through clock tree synthesis |
BoomTile_cleaned_netlist |
Hierarchical netlist with naja optimization |
sram_report |
SRAM metrics comparison table |
<sram>_generate_abstract |
Individual SRAM abstract (LEF/LIB) |
write_macro_placement |
Extract macro placement from hierarchical flow |
write_kept |
Extract kept module list from hierarchical synthesis |
update |
Copy generated snapshots to snapshots/ |
xy_stats |
Timing slack position data |
show_skew |
3D timing slack visualization |
kpi |
Key performance indicators |
The rtl/ folder was generated from Chipyard using the MegaBoom configuration:
make CONFIG=MegaBoomConfig tech_name=asap7 VLSI_TOP=ChipTop \
INPUT_CONFS=example-asap7.yml TOP_MACROCOMPILER_MODE='--mode synflops' verilog