Skip to content

AUTO_MEMORIES: a macro's blackbox costs its generated view's area - #4650

Merged
maliberty merged 7 commits into
The-OpenROAD-Project:masterfrom
oharboe:auto-memories-keep-cost
Oct 11, 2026
Merged

maliberty merged 7 commits into
The-OpenROAD-Project:masterfrom
oharboe:auto-memories-keep-cost

Conversation

@oharboe

@oharboe oharboe commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

With SYNTH_MINIMUM_KEEP_SIZE, synthesis picks the modules to keep with keep_hierarchy -min_cost, which needs a cost for every instanced blackbox. convert_liberty_areas gives Liberty cells one, but an AUTO_MEMORIES macro is a blackbox made from the RTL's own module and has none. Any AUTO_MEMORIES design with a keep threshold stopped with "Missing cost information on instanced blackbox".

Each AUTO_MEMORIES blackbox now gets the gate equivalent of the area FakeRAM writes beside its name in blackboxes.txt, <module> <area> per line, the area its .lib states. The view is not read in the module's place: its pins need not be the module's (FakeRAM names its own).

A listed module that is in the design but not a blackbox is an error: its name did not match its definition (slang's --keep-hierarchy names each elaborated module <definition>$<instance path>, and --blackboxed-module matches only the definition), so its body was elaborated into flip-flops.

asap7/riscv32i hits this once its register file is a generated macro. The integration test is The-OpenROAD-Project/bazel-orfs#1187.

🤖 Generated with Claude Code

With SYNTH_MINIMUM_KEEP_SIZE, synthesis decides which modules to keep
with keep_hierarchy -min_cost, which needs a cost for every instanced
blackbox. convert_liberty_areas gives Liberty cells one, as a gate
equivalent of their area, but an AUTO_MEMORIES macro is a blackbox made
from the RTL's own module and has none: any AUTO_MEMORIES design with a
keep threshold stopped with "Missing cost information on instanced
blackbox". asap7/riscv32i is such a design once its register file is a
macro (AUTO_MEMORIES_REGFILES).

Each AUTO_MEMORIES blackbox now gets the gate equivalent of the area its
generated .lib states. The view is not read in the module's place: its
pins need not be the module's (FakeRAM names its own).

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

@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 updates flow/scripts/synth_preamble.tcl to parse the area of AUTO_MEMORIES blackboxes from their generated Liberty files and assign their gate_cost_equivalent attribute. Feedback on this change highlights that the regular expression used to parse the .lib file is fragile because it can fail on nested groups or special characters in module names, and suggests a more robust regex pattern.

Comment thread flow/scripts/synth_preamble.tcl Outdated
oharboe and others added 2 commits October 8, 2026 07:52
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Only `$` was escaped; yosys and slang module names also carry `\`,
`[` and `.`, each a regular-expression metacharacter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe requested a review from maliberty October 8, 2026 06:12
@openroad-ci

openroad-ci commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

🔍 QoR check

Metrics reflect the PR merge build — i.e. what will land on the target branch.

Commit 4a1c199 · Jenkins build #5 · Baseline: build · View build on dashboard

62 design(s) checked — 0 with regression(s), 0 without a comparable baseline.

@oharboe

oharboe commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

@vvbandeira please retrigger, CI snag

@maliberty

Copy link
Copy Markdown
Member

Claude:
== Priority 1 (correctness) ==

  • synth_preamble.tcl:+275 question: the catch around rtlil::set_attr swallows every
    failure, not just "module not in design". If a name is mangled differently between
    extract_memories and synthesis, or set_attr -uint rejects the value, the cost is
    silently skipped and keep_hierarchy -min_cost fails later with the same opaque
    "Missing cost information" error this PR is meant to fix. Could you check the module
    exists explicitly (e.g. select -list-mod =$m returning empty) and let any other
    error propagate?
  • synth_preamble.tcl:+267 suggestion: getting the area by regex over Liberty text is
    fragile. [^\x7d]*? stops at the first }, and area has no word boundary, so
    foo_area : would match. In Tcl AREs the first quantifier (\s*, greedy) sets the
    whole RE's preference, so the *? doesn't make it shortest-match the way it reads.
    It works today only because FakeRAM writes area : as the first line of the cell
    group. gen_memories.py already drives FakeRAM and knows each macro's size. Could it
    write the area next to the name (e.g. a second column in blackboxes.txt, or in
    memories.json)? That removes the regex, the hex-escaped braces, and the
    metacharacter escaping, and makes the value testable in gen_memories_test.py.
  • nit: if the regex stays, add \m before area.

@oharboe

oharboe commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for running Claude: your seeding of Claude gives a different result than mine, obviously. Helpful. Also, it looks like you curated the output. 😌

oharboe and others added 3 commits October 9, 2026 07:56
…cost

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The cost loop caught every set_attr failure as "not in the design", so a
listed module whose name did not match its definition went unnoticed.
slang's --keep-hierarchy names each elaborated module
`<definition>$<instance path>` and --blackboxed-module matches only the
definition, so such a name is in the design with its body elaborated:
set_attr succeeded on it and the memory became flip-flops.

A listed module absent from the design is skipped (slang imports a
blackboxed module only where it is instanced); one present but not a
blackbox stops synthesis by name; set_attr is no longer caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The cost loop read a macro's area out of its .lib with a regular
expression that matched only because FakeRAM writes `area :` first in
the cell group. FakeRAM knows the area when it writes the view, so it now
writes it beside the module name, `<module> <area>` in um^2 per line, and
synthesis reads it from there. A line of any other shape is an error.

gen_memories_test.py checks the area against the one the .lib states.

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

oharboe commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Both done.

  • The name concern is real on slang. --keep-hierarchy names each elaborated module <definition>$<instance path>, one per instance, even with no parameters, and --blackboxed-module matches only the definition. Such a module is in the design with its body elaborated, so the catch never fired: set_attr succeeded and the memory became flip-flops. Now a listed module absent from the design is skipped (slang imports a blackboxed module only where it is instanced), one present but not a blackbox is an error naming it, and set_attr is not caught. The detector fix for those names is being upstreamed separately.
  • FakeRAM writes the area beside the name, <module> <area> per line in blackboxes.txt. The regex is gone, a malformed line is an error, and gen_memories_test.py checks the area against the .lib.

Merged master for #4618.

The cost loop looked each blackboxes.txt name up in the module list as
a Tcl list. yosys lists an escaped module with its leading backslash,
`\1d_ram`, which list parsing reads as an escape, and blackboxes.txt
names it as read_slang takes it, `1d_ram`; the lookup missed, the
module was taken for absent and skipped, and keep_hierarchy -min_cost
stopped with "Missing cost information on instanced blackbox \1d_ram".
The list is now read one name per line, without the backslash.

Checked with read_slang on a design with `ram` and `\1d_ram`
blackboxed: before, the error above; now both get their cost and
keep_hierarchy -min_cost runs.

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

oharboe commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

The detector fix for slang's per-instance names is #4658.

b59c1d1: the cost loop missed an escaped module. yosys lists \1d_ram, blackboxes.txt has 1d_ram (read_slang's spelling), and the Tcl list lookup read \1 as an escape, so the module was skipped and keep_hierarchy -min_cost stopped with "Missing cost information on instanced blackbox \1d_ram". Checked with read_slang on a design with ram and \1d_ram: both now get their cost.

oharboe added a commit to The-OpenROAD-Project/bazel-orfs that referenced this pull request Oct 9, 2026
With SYNTH_MINIMUM_KEEP_SIZE, hierarchy discovery picks the modules to
keep with keep_hierarchy -min_cost, which needs a cost for every
instanced blackbox. An AUTO_MEMORIES macro is a blackbox made from the
RTL's own module, not a Liberty cell, so any AUTO_MEMORIES design with a
keep threshold stopped with "Missing cost information on instanced
blackbox".

ORFS patch 0090 carries The-OpenROAD-Project/OpenROAD-flow-scripts#4650
at its head: blackboxes.txt carries `<module> <area>` per line and
synthesis gives each AUTO_MEMORIES blackbox that area's gate
equivalent. Beyond the upstream pull request, STRUCTURED_MEMORIES
(patch 0071) writes its modules' areas too, and FakeRAM's
spsram_mask_test (patch 0073) reads the new format.

test/auto_memories:am_top_keep_synth_test synthesizes the AUTO_MEMORIES
fixture with a keep threshold of 1; it fails without the patch on the
missing cost and passes with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@maliberty
maliberty merged commit 4ca4b38 into The-OpenROAD-Project:master Oct 11, 2026
12 checks passed
@vvbandeira

Copy link
Copy Markdown
Member

@oharboe Thanks. This PR has merged, so a retrigger is no longer needed.

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.

4 participants