Repository navigation
Conversation
CoreMiniAxi.sv is regenerated from coralnpu b50b85a9 by src/coralnpu/generate, and the design is configured for it: - The five TCM banks (ITCM one, DTCM four) are coralnpu's Sram, 512 x 128 with one read-write port and a 16-lane byte mask. sram.memories names its pins (ADDITIONAL_MEMORIES) and AUTO_MEMORIES replaces it with a generated macro, write mask and all. The previous build swapped in USE_ASAP7 fakerams, which have no write mask, so a masked write wrote all 16 bytes. - Regfile and FRegfile keep their words as separate registers, with no array for yosys to infer. surgery.py (SYNTH_VERILOG_SURGERY) moves them into Regfile_rf and FRegfile_rf, which AUTO_MEMORIES_REGFILES has generate_ram build as standard cells, every word with its asynchronous reset: Regfile 32 x 32 with x0 reading zero, nine reads and six writes; FRegfile 32 x 32, four reads and two writes. - The clock is 1,900 ps in the platform's picoseconds (it was 10.00), with the platform's set_max_delay IO budgets; the asynchronous reset is not timed. The kept hierarchy is coralnpu's units by name, with OPENROAD_HIERARCHICAL=1. - The divider's 128 x 83 SRT table is a ROM yosys maps to logic; a ROM is not counted against SYNTH_MEMORY_MAX_BITS. surgery.py recognises each register file token for token and stops the build on anything else. Each was simulated before and after the surgery, and generate_ram's netlists against the behavioural modules the surgery writes, on the same random inputs, every output compared every cycle, with a negative control for each that is caught. Needs AUTO_MEMORIES_REGFILES (The-OpenROAD-Project#4781), the supply pins of dont_touch instances connected (The-OpenROAD-Project#4782) and a parameterized module as a macro (The-OpenROAD-Project#4783). 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 register files in the AUTO_MEMORIES flow, allowing them to be built as arrays of placed standard cells rather than synthesized into flip-flops. It adds new configuration variables (AUTO_MEMORIES_REGFILES, AUTO_MEMORIES_MACRO_PLACE), updates the build flow to handle register file generation and dissolution, and includes robust scripts for netlist translation and placement. Review feedback suggests adding more comprehensive validation for spec files, correcting a typo in an error message, and improving the robustness of the Yosys JSON parsing.
…t by generate_ram 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. memories/regfile_ram.py translates each to OpenROAD's generate_ram_netlist options (ports, banks, folds, the zero word, reset, read latency, write style and priority, cells), checks it against the module's ports from synthesis (a stray, missing or mis-sized port stops the build), and writes a wrapper in the module's place around the RAM, <m>_ram: an active-high reset inverted for an active-low flop, addresses narrowed or widened. A register file is inlined unless AUTO_MEMORIES_MACRO_PLACE names it: its cells are then placed, sized and buffered with the rest of the design. A named one is a macro to synthesis and macro placement (an abstract LEF and a liberty of its area beside the FakeRAM views, in blackboxes.txt; a parameterized module's instances lose parameters the netlist does not declare), and 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 periphery left to global placement and the resizer; then eliminate_dead_logic. Where a row holds several words they sit side by side, and a word whose bits would run more than 150 um is folded into more rows: XiangShan's RobEntryFile and RenameBufferFile, dissolved into a parent, did not legalize otherwise (the parent buffers the word's selects inside the full array). `mode netlist`, the default, is the only mode. A spec with `mode macro` stops: a timing model written from generate_ram's netlist before any clock tree is built has the whole unbuffered clock net as its clock pin, 8.5 pF for 64 words of 256 bits on asap7, 32 pF for XiangShan's 954-bit Ftq queue, whose clock then arrived 7.7 ns late in its parent. A register file wanted as a macro is a design of its own: run it through the flow, where CTS builds its clock tree, and give the parent its abstract as a macro. A module named in a spec whose memory has an initial value stops the build: generate_ram's storage has none, and the value would be lost without a word. The spec's read_latency is generate_ram's -register_read_address. The RAMs the wrappers instantiate as macros are listed in regfile_cores.txt: they are in blackboxes.txt but no module of the sources, so the check that every AUTO_MEMORIES module is a black box after read_slang skips them. Uses generate_ram's register-file options (OpenROAD#11723), in tools/OpenROAD. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
b9008ea to
e82ccee
Compare
CoreMiniAxi.sv is regenerated from coralnpu b50b85a9 by src/coralnpu/generate, and the design is configured for it: - The five TCM banks (ITCM one, DTCM four) are coralnpu's Sram, 512 x 128 with one read-write port and a 16-lane byte mask. sram.memories names its pins (ADDITIONAL_MEMORIES) and AUTO_MEMORIES replaces it with a generated macro, write mask and all. The previous build swapped in USE_ASAP7 fakerams, which have no write mask, so a masked write wrote all 16 bytes. - Regfile and FRegfile keep their words as separate registers, with no array for yosys to infer. surgery.py (SYNTH_VERILOG_SURGERY) moves them into Regfile_rf and FRegfile_rf, which AUTO_MEMORIES_REGFILES has generate_ram build as standard cells, every word with its asynchronous reset: Regfile 32 x 32 with x0 reading zero, nine reads and six writes; FRegfile 32 x 32, four reads and two writes. - The clock is 1,900 ps in the platform's picoseconds (it was 10.00), with the platform's set_max_delay IO budgets; the asynchronous reset is not timed. The kept hierarchy is coralnpu's units by name, with OPENROAD_HIERARCHICAL=1. - The divider's 128 x 83 SRT table is a ROM yosys maps to logic; a ROM is not counted against SYNTH_MEMORY_MAX_BITS. surgery.py recognises each register file token for token and stops the build on anything else. Each was simulated before and after the surgery, and generate_ram's netlists against the behavioural modules the surgery writes, on the same random inputs, every output compared every cycle, with a negative control for each that is caught. Needs AUTO_MEMORIES_REGFILES (The-OpenROAD-Project#4781), the supply pins of dont_touch instances connected (The-OpenROAD-Project#4782) and a parameterized module as a macro (The-OpenROAD-Project#4783). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
🔍 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), 1 without a comparable baseline. |
Before, a register file in an ORFS design was synthesised to flops and mux trees, placed by a placer that does not know they are an array, or rewritten as a FakeRAM macro whose single-port model does not describe it.
Now
AUTO_MEMORIES_REGFILESlists register-file specs, and OpenROAD'sgenerate_rambuilds each one from placed standard cells, using its register-file options (OpenROAD#11723, intools/OpenROAD).This wires up more of generate_ram's experimental features in the flow. It is one of three changes needed before asap7/coralnpu (#4653) can go in, with #4782 (pdn: the supply pins of dont_touch instances) and #4783 (a parameterized memory module as a macro). The three are independent of each other.
memories/regfile_ram.pytranslates it togenerate_ram_netlistoptions and checks it against the module's ports from synthesis; a stray, missing or mis-sized port stops the build.AUTO_MEMORIES_MACRO_PLACE: a macro to synthesis and macro placement, which dissolves into its cells after macro placement (regfile_dissolve.tcl). The core stays FIRM where the macro placer put it; global placement and the resizer handle the periphery.mode netlistis the only mode. A spec withmode macrostops: a timing model written before any clock tree would have the whole unbuffered clock net as one pin. A register file wanted as a macro is run through the flow as its own design.Tests:
detect_test.pyandgen_memories_test.pycover the spec checks, the initial-value stop and the mode check.variables.jsonandFlowVariables.mdare the generators' output.🤖 Generated with Claude Code