Repository navigation
gen-verilog: hold a module-level array of structs as a memory, not one packed register (t27core: 134,217,728 bits) #8151
Copy link
Copy link
Closed
Labels
Description
Owner decision, 2026-10-09: repair the generator instead of growing the ledger. See #2566, #8024.
What is wrong
t27c gen-verilog holds a module-level var whose type is an array of structs as ONE packed register. Since #8020 rewrote specs/compiler/core/t27core.t27's parallel arrays into arrays of structs, its tables come out as:
reg [50331647:0] toks; // 262144 * 192 bits
reg [134217727:0] nodes; // 262144 * 512 bits
reg [28671:0] mods;
reg [524287:0] pulls;
reg [786431:0] syms;
The arithmetic is exact (#8024), and no hardware carries a 134,217,728-bit register. #8025 recorded the spec in tools/verilog_width_baseline.txt, whose header says adding a line is a regression.
Before #8020 the same tables were parallel i64 arrays, which gen-verilog already holds as memories (W531: reg signed [63:0] scope_arr[0:4095];). A source refactor changed the hardware form.
Plan
- Hold such a var as an unpacked memory,
reg [W-1:0] name[0:N-1], with W the struct's packed width: one word per element, the form W531 already gives an array of primitives, and the form synthesis maps to RAM. Element and field accesses becomename[i]andname[i][off +: w]. - Keep the packed vector where the value arrives packed: a var initialized by a function call (W589, as W545 for primitives). Keep it for an empty list too:
[0:-1]declares nothing. - The decision is a
.t27spec lowered witht27c gen-rustand mounted by#[path];compiler.rsonly prints it, within the 40/80 hand-written line budget (Only-t27 gate: a foreign-line budget the label cannot lift; local hook reads exceptions from origin/master #7371). - Remove
specs/compiler/core/t27core.t27fromtools/verilog_width_baseline.txtin the same PR; the gate must report no new absurd width. - Reseal every seal whose output changes, and explain each change. Update
bootstrap/stage0/FROZEN_HASH.
Out of scope
- The two older ledger lines (
specs/compiler/stdlib.t27,specs/base/ternary_memory.t27) are a single struct that is itself millions of bits wide. A memory does not shrink one element; whether such a type should lower at all stays the question in Owner decision: emitted Verilog carries widths that cannot be real, and the release build is the one that hides it #2566. - Function locals, parameters and returns stay packed: a Verilog-2001 function takes and returns vectors, not memories.
User Scenarios
- Given a module-level
varof typeNode[262144]whereNodeis a struct of 512 bits, whent27c gen-verilogruns, then it emitsreg [511:0] nodes[0:262143];instead ofreg [134217727:0] nodes;. - Given a module-level
varinitialized by a function call returning a packed struct array, whent27c gen-verilogruns, then it keeps the packed vector form for that var. - Given an empty array
var toks: Token[0], whent27c gen-verilogruns, then it emits no declaration fortoks(equivalent to[0:-1]).
Requirements
- FR-001: The Verilog generator MUST lower a module-level array-of-struct
varto an unpacked memoryreg [W-1:0] name[0:N-1]where W is the struct's packed width and N the element count. - FR-002: The generator MUST keep a packed vector for a module-level
varwhose initializer is a function call (packed input) or an empty list. - FR-003: The generator MUST preserve existing memory lowering for arrays of primitives (e.g.,
i64[4096]→reg signed [63:0] name[0:4095]). - FR-004: The file
tools/verilog_width_baseline.txtMUST no longer contain a line forspecs/compiler/core/t27core.t27. - FR-005: Every seal whose Verilog output changes MUST be resealed with an explanation in the commit message.
- FR-006:
bootstrap/stage0/FROZEN_HASHMUST be updated to the new bootstrap hash.
Success Criteria
t27c gen-verilog specs/compiler/core/t27core.t27emits no register wider than 512 bits (exit 0, grep forreg \[shows max index ≤ 511).tools/verilog_width_baseline.txthas no line mentioningt27core.t27(exit 0,grep -c t27core tools/verilog_width_baseline.txtoutputs 0).- All existing Verilog generation tests pass (5 tests in
cli/t27b/tests/memory.rs). t27c seal verifypasses for all resealed files (exit 0).bootstrap/stage0/FROZEN_HASHmatches the new stage0 hash (exit 0,cat bootstrap/stage0/FROZEN_HASHequalst27c bootstrap hashoutput).
Boundary
- specs/compiler/core/t27core.t27
- tools/verilog_width_baseline.txt
- bootstrap/stage0/FROZEN_HASH
- cli/t27b/tests/memory.rs
- .trinity/seals/Memory.json
- specs/tri/collections/array.t27
- specs/fpga/memory.t27
- specs/tri/agent/memory.t27
- specs/compiler/stdlib.t27
- specs/base/ternary_memory.t27
- specs/port/browseros/trios/agent-server/apps/server/src/api/routes/memory.t27
- bootstrap/tests/fixtures/trinity_matrix/structs.t27
Reactions are currently unavailable
Activity
Merge master into fix/verilog-array-of-structs (Closes #8151)
t27b ledger: list specs/compiler/verilog_aos_memory.t27 as pass (Closes