Skip to content

openroad: generate_regfile in the ram module, carried as patch 0010 - #1185

Closed
oharboe wants to merge 4 commits into
mainfrom
regfile/openroad-generate-regfile
Closed

oharboe wants to merge 4 commits into
mainfrom
regfile/openroad-generate-regfile

Conversation

@oharboe

@oharboe oharboe commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Phase A of moving register-file generation into ORFS and OpenROAD: the generator becomes an OpenROAD command, carried here as a patch, and is proven byte-identical to the tool it replaces. Nothing calls it yet, so no flow output changes. Phase B (register files through AUTO_MEMORIES, as macros that dissolve after macro placement) builds on it.

The command

Carried patch 0010-openroad-ram-generate-regfile.patch, in OpenROAD's src/ram, next to generate_ram_netlist:

read_lef <tech.lef>
read_lef <cells.lef>
generate_regfile -spec rf.regfile [-verilog rf.v] [-def rf.def] [-lef rf.lef] [-liberty rf.lib] [-check_ports rtl.v]
  • The code is tools/structured_gen's, moved: the regfile and views sources, in the ram namespace, with exceptions reported as RAM-0050 and a missing -spec as RAM-0051.
  • Both build systems list the new sources: Bazel, which is built here, and CMake, which isn't.
  • Not upstreamed.

Proof: byte for byte

tools/structured_gen/golden_test.sh runs each spec through the tool and the command from the same LEFs, then requires an identical Verilog netlist, DEF, abstract LEF, model liberty and pre-layout liberty.

test specs time result
golden_test (default) five tiny synthetic specs covering every spec feature: banks, bank columns, bit folds, registered read with the RTL's names, banked and interleaved reads, the zero word, netlist mode 4 s all identical
golden_xiangshan_test (manual) the ten specs the flow uses, at real size (RobEntryFile is about 400 k cells) 48 min all identical

The tiny specs, in tools/structured_gen/golden/, are also a fast test case to keep for the phases that follow.

Cost

The openroad binary changes, so every ORFS stage re-runs once. Building it here was 19 local actions (the ram sources and the link) on top of the remote cache.

Next

  • Phase B: AUTO_MEMORIES register files, named explicitly as STRUCTURED_MEMORIES does today (parity first), placed as macros, then dissolved into a FIRM core plus a periphery for OpenROAD. It retires ORFS patches 0071, 0078, 0082 and 0084, and the tool itself.
  • Improvements come after parity: automatic detection, rotation.

🤖 Generated with Claude Code

oharboe and others added 3 commits October 6, 2026 15:40
The register-file generator moves into OpenROAD, a sibling of
generate_ram_netlist in src/ram: `generate_regfile -spec <file>
[-verilog] [-def] [-lef] [-liberty] [-check_ports <rtl.v>]` builds the
spec's register file into the current database, after read_lef as
usual, and writes the views asked for. The code is structured_gen's,
in the ram namespace, its exceptions reported as RAM-0050; Bazel and
CMake both list the new sources. Not upstreamed.

tools/structured_gen:golden_test proves the move: for five tiny
synthetic specs covering every spec feature (banks, bank columns, bit
folds, registered read with the RTL's names, banked and interleaved
reads, the zero word, netlist mode), the command and the tool write the
same Verilog, DEF, abstract LEF and model liberty, byte for byte, in
seconds. golden_xiangshan_test does the same for the ten specs the flow
uses, at real size (manual: minutes per spec). The tool stays until
its callers move to the command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
…ons land

In netlist mode the block's abstract is what a parent's macro placer
sees before the block dissolves into its rows, and the placer orients a
macro by flipping it to shorten the wires to its pins. Edge pins packed
in a corner said nothing about where the wires go: each port's pin now
sits at the centroid of the cells on its net -- a write data bit over
its column's write muxes, a read data bit at its bitline's root, an
address among its inverters and decode. They are never routed; the
block dissolves first. Same edit in the tool and in patch 0010, so the
golden test stays byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
…regression test

Three things the first designs beyond XiangShan's turned up, in the tool
and in patch 0010 alike, so the golden test stays byte for byte:

- A netlist-mode abstract's pins sit at the centroid of their
  connections; off the M4 track grid, rtl_macro_placer refused the
  macro (MPL-0005). They are snapped as the edge pins are.
- The port check read one port per line and missed `input [4:0] ra1,
  ra2, wa3`, riscv32i's register file. It reads the header per comma
  entry, a bare name inheriting the direction and width before it.
- The views and the log name the command, not the tool it came from.

Patch 0010 gains src/ram/test/generate_regfile_asap7: an 8 x 4, two-
bank, 2R2W file with word 0 reading zero, checked against RTL that
declares its ports several to a line, its four views against golden
files. OpenROAD's test targets do not analyse from bazel-orfs (they need
OpenROAD's dev-only repositories); run by hand, the log matches .ok and
the four views their golden files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe

oharboe commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator Author

Two commits added, same edit in the tool and in patch 0010 so the golden test stays byte for byte:

  • Pins where their connections land, on the track grid. In netlist mode the abstract is what the parent's macro placer sees before the file dissolves, and the placer flips a macro by its pins, so each pin now sits at the centroid of its net's cells. Off the M4 track grid, rtl_macro_placer refused the macro (MPL-0005); they are snapped as the edge pins are.
  • Ports declared several to a line. The port check read one port per line and missed input [4:0] ra1, ra2, wa3, which is how riscv32i declares its register file. It now reads one comma entry at a time.
  • An OpenROAD regression test in the patch. src/ram/test/generate_regfile_asap7: an 8 x 4, two-bank, 2R2W file with word 0 reading zero, checked against RTL with comma-declared ports, its four views against golden files. Run by hand (OpenROAD's test targets don't analyse from bazel-orfs), the log matches .ok and all four views match.

The ORFS side that uses this, replacing STRUCTURED_*, is stacked on this branch: see the next PR.

@oharboe

oharboe commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator Author

The stacked PR is #1187.

clang-format in OpenROAD's style, SPDX headers on the new sources, the
command and its spec documented in src/ram/README.md, and the commit
message written for upstream. The binary does not change: the golden
test and the ORFS register-file tests pass from cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe oharboe closed this Oct 6, 2026
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.

1 participant