Repository navigation
Conversation
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>
There was a problem hiding this comment.
Code Review
This pull request introduces support for generating and placing register files as standard cells or macros using OpenROAD's generate_regfile tool, adding new configuration variables, documentation, and a Tcl script to dissolve macro-placed register files back into standard cells. The review feedback focuses on improving code robustness and performance, including preventing potential IndexError and "None" string conversions in Python scripts, extracting side-effect functions from f-strings for better readability, and caching processed nets in Tcl to avoid redundant computations.
c5dd9be to
b8ff330
Compare
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>
b8ff330 to
6affa8a
Compare
🔍 QoR checkMetrics reflect the PR merge build — i.e. what will land on the target branch. Commit 62 design(s) checked — 0 with regression(s), 0 without a comparable baseline. |
…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>
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>
A register file, many ports over few words, is not an SRAM: FakeRAM's single-port model does not describe it, and synthesised to flops its mux trees are placed by a placer that does not know they are an array. AUTO_MEMORIES_REGFILES lists spec files, one per RTL module. gen_memories.py runs OpenROAD's generate_regfile on each: it checks the spec against the module's ports and writes the cells (<m>.v), an abstract whose pins sit where their connections land in the array (<m>.lef) and a timing model (<m>.lib, <m>_pre_layout.lib) beside the FakeRAM views. The module joins blackboxes.txt with the area its .lib states, so synthesis and macro placement see a macro that SYNTH_MINIMUM_KEEP_SIZE can cost, and memories.json records it with kind `regfile` (the others get `fakeram` or `flops`). In `mode netlist` the macro dissolves into its cells at the end of macro placement (regfile_dissolve.tcl): the core FIRM where the placer put the macro, flipped as it was, row parity kept; the address decode left to global placement and the resizer; the core's own cells and nets dont_touch except the flops (CTS rewires them) and the cells on the core's boundary (repair_design buffers their nets); then eliminate_dead_logic, as at synthesis. `mode macro` keeps the macro. designs/asap7/regfile is the smallest example: one 16x8 2R2W file in a parent of flops, seconds to global route. Moving parts into OpenROAD, the dissolve in particular, is left for later: faster, unit-testable, maintained with the database it edits. Needs OpenROAD's generate_regfile: The-OpenROAD-Project/OpenROAD#11669 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
AUTO_MEMORIES_REGFILES built every register file as a macro: blackboxed in synthesis, placed by the macro placer and, in `mode netlist`, dissolved into its cells after macro placement. On a small design the macro's outline and channels cost more core than the array saves: riscv32i's register file as a macro does not fit riscv32i's own 62 % utilisation beside its four FakeRAMs (MPL-0003). AUTO_MEMORIES_MACRO_PLACE lists the register files to place as macros. Any other is inlined: gen_memories.py writes only its generated netlist (no abstract, model liberty or taps) and inline.txt, and synthesis reads the RTL module as a blackbox and the netlist in its place. Its cells are then placed, sized and buffered with the rest of the design. A name no spec builds stops the build. asap7/regfile lists its RegFile, which keeps the dissolve its tests exercise. asap7/riscv32i-regfile lists nothing, takes riscv32i's own utilisation, and its spec writes through a clock gate per word (`write_style clock_gate`, OpenROAD#11669): 955 ps at global route against the flip-flops' 954, on a core 12 % smaller. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
…rized module An inlined register file's generated netlist has no parameters; a parameterized RTL module (ibex_register_file_ff #(RV32E, DataWidth, DummyInstructions)) is instantiated with them, and hierarchy refused: "does not have a parameter named ...". The netlist is the module at the widths generate_regfile's port check confirmed, so the parameters are dropped from its instances before it is read. Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6affa8a to
468db41
Compare
…ells AUTO_MEMORIES_REGFILES lists register-file specs; OpenROAD's generate_regfile builds each as placed standard cells during canonicalization. In mode netlist a file is a macro through synthesis and macro placement and then dissolves into its cells. AUTO_MEMORIES_MACRO_PLACE names the files placed as macros; the others are inlined in synthesis. Carried: - OpenROAD 0010: The-OpenROAD-Project/OpenROAD#11669, its net diff at its head, as one patch. - ORFS 0089, 0091, 0099: the three commits of The-OpenROAD-Project/OpenROAD-flow-scripts#4651 as rebuilt on #4650 (blackboxes.txt lines carry each register file's area), without its example designs (asap7/regfile, asap7/riscv32i-regfile, src/regfile). They apply after 0090 (#4650, #1205). 0090 loses the hunks it carried for the retired 0071 (its register files' DEF die area); the rest of it is unchanged. STRUCTURED_MEMORIES and STRUCTURED_PLACEMENT (ORFS patches 0071, 0078, 0082, 0084) are retired. A flow that still sets either one fails and the error names the replacement: at load time in arguments or sources, and at analysis in user_arguments or on a stage rule. test/structured_netlist, test/planned_parent, the XiangShan flows, tools/structured_gen/test and tools/macro_select move to the new variables. test/regfile is the flow's own fixture: the dissolve, every register clocked (macro and inlined), global route, simulation against the RTL, and synthesis with SYNTH_MINIMUM_KEEP_SIZE=1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
Closing for now: the register-file support moved onto OpenROAD's generate_ram (The-OpenROAD-Project/OpenROAD#11723), and the ORFS side is carried in The-OpenROAD-Project/bazel-orfs#1234 until OpenROAD has it. This can be reopened or reworded then. |
AUTO_MEMORIES_REGFILES: register files built by OpenROAD'sgenerate_regfile(The-OpenROAD-Project/OpenROAD#11669) in place of the flip-flops synthesis would make.Draft until that PR merges and ORFS's OpenROAD submodule is bumped.
Depends on #4650, and is built on its branch: a register file's line in
blackboxes.txtis<module> <area>, the format #4650 introduces, soSYNTH_MINIMUM_KEEP_SIZEcan cost a register-file macro like a FakeRAM one. Until #4650 merges, this PR's commit list starts with #4650's commits; review only the three below.On asap7/riscv32i at global route (
asap7/riscv32i-regfilein this PR), against the same design with flip-flops: minimum period 923 → 922 ps, standard-cell area −24 %, power −24 %. Results on more designs are in the integration test, The-OpenROAD-Project/bazel-orfs#1187, which runs these changes with the OpenROAD PR on ORFS's own designs.One commit per concern:
AUTO_MEMORIES_REGFILES: spec files, one per register file.gen_memories.pychecks each against its RTL module and generates it. The register file is a macro (abstract and timing model, and its.libarea inblackboxes.txt) or, inmode netlist, dissolves into its cells after macro placement.designs/asap7/regfileis the smallest example;designs/asap7/riscv32i-regfileis riscv32i with its register file generated.AUTO_MEMORIES_MACRO_PLACE: register files not listed are inlined. Synthesis reads the generated netlist in the module's place, and its cells are placed, sized and buffered with the rest of the design, which is the better shape for a small design.ibex_register_file_ff): the instances' parameters are dropped before the netlist is read.Tests:
gen_memories_test.pychecks the contract files each commit adds (regfiles.txt,inline.txt), that a register file's area is the cell area its.libstates, and that a.libstating none stops the build.🤖 Generated with Claude Code