Skip to content

AUTO_MEMORIES: generated memory macros from RTL (experimental)#4367

Open
oharboe wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
oharboe:auto-memories
Open

AUTO_MEMORIES: generated memory macros from RTL (experimental)#4367
oharboe wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
oharboe:auto-memories

Conversation

@oharboe

@oharboe oharboe commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

AUTO_MEMORIES: generated memory macros from RTL (experimental)

AUTO_MEMORIES=1 detects memory-shaped modules in the design's RTL
before synthesis, inventories them in results/.../memories.json, and
generates .lib/.lef macro views for the ones idiomatic as SRAM
macros. Synthesis blackboxes the converted modules so the liberty view
wins over their behavioral bodies; floorplan through final read the
generated views. Together with RTL-MP macro placement this gives
macro-based physical design results on an existing design without a
memory compiler or hand-maintained fakeram files.

ADDITIONAL_MEMORIES lists user-supplied .memories files (same JSON
schema as memories.json) merged onto the detected set — e.g. to
force-convert a memory the idiomatic gate rejects.

Documentation: docs/user/AutoMemories.md.

How it works

  • A new pre-synthesis step runs flow/scripts/memories/gen_memories.py
    over VERILOG_FILES. Detection is a fast Python scan for modules
    whose entire port list follows the firtool (CIRCT) memory port
    convention (R0_addr, W0_en, RW0_wdata, subword-split
    RW0_wdata_3 / W0_mask_2), i.e. module-boundary memories.
  • An idiomatic gate (min depth/capacity, port limit) decides
    macro-vs-flops; rejected memories stay behavioral RTL and are
    reported with a reason.
  • The generated .lib mirrors the OpenROAD abstract-writer shape
    (bus() groups with per-bit pins — required for yosys bus
    elaboration — per-port clocks with clock-tree-path arcs, setup/hold,
    internal_power under a power_lut_template). Both a regular and an
    ideal-clock _pre_layout variant are emitted. The .lef follows the
    asap7 fakeram conventions (M4 pin pads, interleaved M4 PG straps the
    platform PDN macro grid connects to, full-footprint OBS). Timing/area
    come from parametric models anchored to published 7 nm SP-SRAM IP.
  • Everything downstream keys off the generated files (memories.json,
    memories/*.lib|*.lef, blackboxes.txt) — a file-based handoff that
    also lets build systems (e.g. bazel-orfs) declare the artifacts as
    ordinary stage outputs and transitive dependencies of later stages.
  • Emitters are split into general structure (liberty.py, lef.py,
    parameterized by PdkParams) and asap7 constants (pdk_asap7.py) as
    a first pass at separating PDK concerns. asap7 only for now; any
    other platform errors out.

Demo design

flow/designs/asap7/tinyRocket — the generic tinyRocket RTL with no
platform memory-mapping file and no checked-in fakerams (contrast
with flow/designs/nangate45/tinyRocket). Its tag_array (4 entries)
is rejected by the gate but has no behavioral fallback in this RTL, so
the design forces its conversion via tag_array.memories
demonstrating ADDITIONAL_MEMORIES. Example only; not enrolled in CI.

bazel-orfs consumption

bazel-orfs runs each stage in a sandbox where only declared outputs
survive, so it needs to declare memories.json + the memories/
directory (a directory artifact — file names only known at run time)
as canonicalize outputs and stage them into every downstream stage.
That change is carried in this PR as
flow/scripts/memories/bazel-orfs-auto-memories.patch so both sides
review together; it will be upstreamed to bazel-orfs once this lands.

Deliberately out of scope (documented)

  • Memories embedded inside a larger module: yosys memory inference
    could be wired up as the detector (and would catch those), but
    OpenROAD SYN has no memory inference pass — perhaps it could grow
    into such a detector. Punted here with the fast, simple Python
    scanner; see the note at the top of detect.py.
  • Banking / multi-macro decomposition.
  • Other PDKs (the PdkParams seam exists; the calibration work does
    not).

Testing

Fast unit tests, orthogonal to the classic full-flow tests — the value
here is correct detection and handing synthesis/later stages the right
files, not QoR:

bazelisk test //flow:memories_tests

(detector fixtures incl. subword-split style, schema round-trip/merge,
idiomatic gate, structural .lib/.lef assertions, the flow contract, and
the area model; also runnable directly with python3.)

End-to-end sanity, run locally:

make DESIGN_CONFIG=designs/asap7/tinyRocket/config.mk place

synthesis blackboxes the four memory wrappers, the OpenROAD stages read
the four generated lib/lef, RTL-MP places the three reachable macros,
and the PDN macro grid connects to the generated straps.

Support posture

Experimental. Intended for flows built on top of ORFS (e.g. bazel-orfs
based in-house flows) that need early results on designs whose memories
exist only as behavioral RTL. If it works for you, great; if it needs
fixing, the report is itself a welcome signal that someone is using it.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces AUTO_MEMORIES, an experimental feature for the asap7 platform that automatically detects memory modules in RTL pre-synthesis and generates abstract .lib and .lef macro views for them. The feedback focuses on improving the robustness and correctness of the newly added Python scripts. Specifically, the reviewer recommends stripping comments in detect.py to prevent parsing errors, handling parameterized bus widths safely instead of silently corrupting the memory model, wrapping file operations in gen_memories.py with exception handling, and extending schema validation in schema.py to ensure address and data pins are present before emitting views.

Comment thread flow/scripts/memories/detect.py
Comment thread flow/scripts/memories/detect.py
Comment thread flow/scripts/memories/gen_memories.py Outdated
Comment thread flow/scripts/memories/schema.py Outdated
Detect memory-shaped modules (firtool R*/W*/RW*_ port convention) in
the RTL before synthesis, inventory them in results/memories.json, and
generate .lib/.lef macro views for the ones idiomatic as SRAM macros.
Synthesis blackboxes the converted modules so the liberty view wins
over their behavioral bodies; floorplan through final read the
generated views. ADDITIONAL_MEMORIES merges user-supplied .memories
files onto the detected set, e.g. to force-convert a memory the
idiomatic gate rejects.

Together with RTL-MP macro placement this gives macro-based physical
design results on an existing design without a memory compiler or
hand-maintained fakeram files. asap7 only; the emitters are split into
general structure and asap7 parameters as a first pass at separating
PDK concerns. Banking and yosys/OpenROAD-SYN-based memory detection
are documented as future work.

The new designs/asap7/tinyRocket design demonstrates the flow end to
end with no platform memory-mapping file and no checked-in fakerams;
its tag_array forces conversion via a .memories override because the
generic RTL has no behavioral fallback for it.

Tested with `bazelisk test //flow:memories_tests` (detector, schema,
idiomatic gate, and .lib/.lef emitter unit tests) and
`make DESIGN_CONFIG=designs/asap7/tinyRocket/config.mk floorplan`.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
bazel-orfs runs each flow stage in a sandbox where only declared
outputs survive, so the generated memories.json and memories/ views
must be declared as canonicalize outputs and propagated to every
downstream stage. Carried here as a patch so the bazel-orfs side can
be reviewed together with the feature; to be upstreamed to bazel-orfs
once this lands.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe requested a review from povik July 19, 2026 17:01
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