Repository navigation
AUTO_MEMORIES (experimental): wire up mask_lane_width, a write mask with a ragged last lane - #4776
Conversation
A memory's write mask lanes had to split its word evenly, so pulp's tc_sram, whose byte enables cover a word that is not whole bytes, could not become a macro: cva6's I-cache tag RAM is 25 bits with 4 byte enables, 8, 8, 8 and 1 bit wide. A memory may now declare mask_lane_width: every lane is that wide but the last, which holds the rest (lanes * width >= bits > (lanes - 1) * width). FakeRAM builds the mask bus as before, one pin per lane, and its Verilog model writes each lane's own bit range. Without a width the lanes split the word evenly, as before, and an uneven split is refused as before. 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 ragged write mask lanes (where the last lane can be narrower than the others) in memory configurations and Verilog generation. It adds a mask_lane_width parameter to the schema, updates validation logic, and modifies the Verilog exporter to handle uneven splits. The review feedback suggests three key improvements: validating even splits in validate_emittable when mask_lane_width is zero, robustly handling potential null values in JSON parsing to prevent TypeError, and clarifying the error message in memory_config.py when mask_lane_width is provided without mask_lanes.
validate_emittable checked the lanes only when mask_lane_width was given, so a memory whose bits do not split evenly over mask_lanes got past the schema and failed later in FakeRAM. It is now refused in the schema, naming the memory. FakeRAM names a mask_lane_width given without mask_lanes, instead of reporting zero lanes that do not cover the word. gen_memories_test's 512 x 17 memory kept the 4 write enable bits and 32 data bits of the 128 x 32 it was made from; it now has one of each per bit, as yosys writes it. 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), 0 without a comparable baseline. |
An override entry may set mask_lane_width for a word that is not a whole number of write-mask lanes; say so where the overrides are documented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
FakeRAM takes a memory's lane count from its mask pin's width and never reads mask_lanes, and merge keeps the detected pins unless an override brings its own. An override that set mask_lanes on a detected memory passed the schema and then failed in FakeRAM with an error that did not point at the cause, such as "mask_lane_width without mask_lanes" when mask_lanes was set. validate_emittable now refuses a mask pin whose width is not mask_lanes, and mask_lanes on a memory with no mask pin, naming the memory. Detected memories already agree: yosys's mask pin is mask_lanes wide, and a firtool memory takes mask_lanes from its pin. The guard before lane_width_check goes; that check returns by itself when there are no lanes and no width. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The mask_lane_width example was a bare override, which on a detected memory keeps the detected pins and is now refused. Show the whole entry, pins with a mask pin mask_lanes wide among them, and say that an override changing mask_lanes must bring its pins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
Thanks, all three check out against the code.
Tested: |
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Wires up one more experimental AUTO_MEMORIES feature:
mask_lane_widthon a.memoriesoverride entry (ADDITIONAL_MEMORIES). It sets the bits per write-mask lane, with the last lane holding the rest, so a RAM whose byte enables cover a word that is not whole bytes can become a macro. The case that needs it is pulp'stc_sramas cva6's I-cache tag RAM: 25 bits, with 4 byte enables of 8, 8, 8 and 1 bit (asap7/cva6 in #4777).No current design is asked to change anything. AUTO_MEMORIES is experimental and asap7-only, and no design sets
mask_lane_width. Without the field, behaviour is as before:LANE_WIDTH.With the field:
lanes * width >= bits > (lanes - 1) * width; anything else is refused, as is a width without lanes.docs/user/AutoMemories.mddocuments it next to the other overrides.Smoke test it needs: asap7/tinyRocket, the one design with
AUTO_MEMORIES = 1, builds as before, and the existing memories and FakeRAM tests pass.New tests:
flow/scripts/memories/schema_test.pycovers the check and the field surviving merge and dump.tools/FakeRAM2.0/test/spsram_mask_test.pycovers the config, the model's lanes and the even split.gen_memories_test's 512 × 17 fixture now has one write-enable bit and one data bit per bit, as yosys writes it; the earlier fixture only passed because the uneven split went unchecked.Integration: The-OpenROAD-Project/bazel-orfs#1484 carries this and builds asap7/cva6 to global route with the tag RAM as a macro.
🤖 Generated with Claude Code