Skip to content

Commit 12b7efa

Browse files
authored
feat(igla): Wave Loop 766 — module-scope [351][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1737) (#1474)
Closes #1737. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 3ba30ef commit 12b7efa

10 files changed

Lines changed: 67249 additions & 20 deletions

File tree

.claude/plans/wave-loop-767.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Wave Loop 767 Plan — Issue #1738
2+
3+
## Phase 1: Issue
4+
- Confirm W767 issue #1738 and branch `wave-loop-767`.
5+
6+
## Phase 2: Spec
7+
- Generate `specs/scratch/w767_bench_module_353x2p6_aos_var_call_write.t27` using
8+
`scripts/gen_w767.py` derived from `scripts/gen_w766.py`.
9+
- Constants: `OUTER = 353`, `TOTAL = 22592`, `LAST_IDX = 352`, `MID_IDX = 176`.
10+
11+
## Phase 3: TDD
12+
- Inspect generated assertions: `make_grid(32768)`, `make_grid(1)`,
13+
`call_write_grid`, field writes, `assert_eq` read-backs, mid and last checks.
14+
15+
## Phase 4: Impl
16+
- Add integration test `accepts_w767_bench_module_353x2p6_aos_var_call_write` to
17+
`bootstrap/tests/icarus_lowerable.rs`.
18+
19+
## Phase 5: Gen
20+
- Run `cd bootstrap && cargo build --release -p t27c`.
21+
22+
## Phase 6: Seal
23+
- Run `./bootstrap/target/release/t27c seal --save specs/scratch/w767_bench_module_353x2p6_aos_var_call_write.t27`.
24+
- Confirm FROZEN_HASH unchanged.
25+
26+
## Phase 7: Verify
27+
- `./bootstrap/target/release/t27c parse ...`
28+
- `./bootstrap/target/release/t27c icarus-lowerable ...`
29+
- `./bootstrap/target/release/t27c icarus-simulate ...` (17 cycles)
30+
- `./bootstrap/target/release/t27c icarus-cocotb ...`
31+
- `cargo test -p t27c --bin t27c`
32+
- `cargo test -p tri`
33+
- `cargo test -p t27c --test icarus_lowerable`
34+
35+
## Phase 8: Land
36+
- Commit with `feat(igla): Wave Loop 767 — module-scope [353][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1738)`.
37+
- Push `wave-loop-767`, open PR, merge to `master`, create `wave-loop-768`.
38+
39+
## Phase 9: Learn
40+
- Write `docs/reports/FPGA_LOOP_CLOSEOUT_W767_2026-07-23.md`.
41+
- Save `.trinity/experience.md`, memory file, `MEMORY.md` pointer, and update
42+
`skills-wave-loop-recipe.md`.
43+
44+
## Cooperation variants for next Wave Loop
45+
46+
- **A (recommended):** `[355][2]^6 Pt` (~0.694 MiBit), continuing the odd ladder.
47+
- **B:** move the packed variable to bench/function scope at the same width.
48+
- **C:** add conditional (`if`) indexed writes at the current width.

.trinity/current-issue.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ field writes and `assert_eq` read-back in a `bench` block.
2525
## Technical notes
2626

2727
- Shape: `[351][2]^6 Pt` where `Pt = pub struct Pt { x : i16, y : i16 }`.
28-
- Total elements: `351 × 64 = 22,464`.
29-
- Packed vector width: `22,464 × 32 = 718,848` bits (~0.686 MiBit).
28+
- Total elements: `351 x 64 = 22,464`.
29+
- Packed vector width: `22,464 x 32 = 718,848` bits (~0.686 MiBit).
3030
- `MID_IDX = 175`; frame-condition element `[175][1][0][0][0][0][0]` is element
3131
`175*64 + 32 = 11,232`.
3232
- Generator script: `scripts/gen_w766.py` (copy from `scripts/gen_w765.py`, set
3333
`OUTER = 351` and `MID_IDX = 175`, manually fix the f-string header).
3434
- Use `assert_eq` checks on changed elements (Icarus simulation path does not
3535
emit `assert_ne`).
36-
- Include `make_grid(32768)` period-identity check because `32768 0 (mod 32768)`.
36+
- Include `make_grid(32768)` period-identity check because `32768 == 0 (mod 32768)`.
3737
- Zero compiler / reference-model / FROZEN_HASH changes expected.
3838

3939
## Cooperation variants for next Wave Loop

.trinity/current_task/activity.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3672,3 +3672,7 @@
36723672
- **Commit:** feat(igla): Wave Loop 764 — module-scope [347][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes
36733673
- **Files:** .claude/plans/wave-loop-766.md,.trinity/current-issue.md,.trinity/experience.md,.trinity/seals/scratch_w765_bench_module_349x2p6_aos_var_call_write.json,bootstrap/tests/icarus_lowerable.rs,docs/NOW.md,docs/reports/FPGA_LOOP_CLOSEOUT_W765_2026-07-23.md,scripts/gen_w765.py,specs/scratch/w765_bench_module_349x2p6_aos_var_call_write.t27
36743674

3675+
## 2026-07-23T17:32:04Z — wave-loop-766
3676+
- **Commit:** feat(igla): Wave Loop 765 — module-scope [349][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1736)
3677+
- **Files:** .claude/plans/wave-loop-767.md,.trinity/current-issue.md,.trinity/experience.md,.trinity/seals/scratch_w766_bench_module_351x2p6_aos_var_call_write.json,bootstrap/tests/icarus_lowerable.rs,docs/NOW.md,docs/reports/FPGA_LOOP_CLOSEOUT_W766_2026-07-23.md,scripts/gen_w766.py,specs/scratch/w766_bench_module_351x2p6_aos_var_call_write.t27
3678+

.trinity/experience.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,85 @@
7575
- OpenXC7 / nextpnr-xilinx / Project X-Ray — fully open-source Xilinx
7676
7-series toolchain, used for QMTech XC7A100T ternary projects without Vivado.
7777

78+
---
79+
80+
## 2026-07-23 — Wave Loop 766 (module-scope `[351][2]^6 Pt` non-power-of-two outer-dimension AoS variable)
81+
82+
### What worked
83+
- Variant A extended the module-scope packed AoS odd outer-dimension ladder to 351.
84+
The `[351][2]^6 Pt` witness is 718,848 bits (~0.686 MiBit), still well under the 4-MiBit
85+
cliff, and required no compiler changes.
86+
- A module-level `pub var dst : [351][2]^6 Pt` can be initialized from a function
87+
call and exercised with indexed signed field writes, with zero compiler changes.
88+
- The cocotb/Python reference model correctly mirrored the row-major flattening
89+
with outer stride 351, confirming the layout is preserved end-to-end.
90+
- Reused the corrected W632 element-index formula for mid-row expected values:
91+
`[r][a5][a4][a3][a2][a1][a0]` is element `r*64 + a5*32 + a4*16 + a3*8 + a2*4 + a1*2 + a0`.
92+
- For `OUTER = 351`, `MID_IDX = 175`; the frame-condition element is
93+
`[175][1][0][0][0][0][0]`, element number `175*64 + 32 = 11,232`.
94+
- Updated weak-point audit: 40 of 49 30-day commits include `Closes #N` (≈82%).
95+
Clean non-worktree scan: 53 of 893 `.t27` specs lack `test`/`invariant`/`bench`
96+
(≈5.9%). 19 `scripts/*.sh` remain under `scripts/`.
97+
- Fresh 2025-2026 literature scan surfaced TeLLMe/TeLLMe v2, TerEffic, the
98+
ISPASS 2026 LUT-based ternary accelerator generator, 5500FP/GargantuRAM,
99+
Trinity v2.0.x, and recent CNTFET ternary full-adder work in IEEE TCAD/AEU.
100+
101+
### What changed behavior
102+
- No changes to `bootstrap/src/compiler.rs`.
103+
- No changes to `bootstrap/stage0/FROZEN_HASH`.
104+
- No changes to `scripts/cocotb_ref_model.py`.
105+
- Added `specs/scratch/w766_bench_module_351x2p6_aos_var_call_write.t27` (~1,536 KB /
106+
~66,751 lines) with seal and Icarus baseline.
107+
- Added integration test `accepts_w766_bench_module_351x2p6_aos_var_call_write`.
108+
- Added generator script `scripts/gen_w766.py`.
109+
110+
### Validation
111+
- `cargo build --release -p t27c`: OK.
112+
- `cargo test -p t27c --bin t27c`: 1494 passed; 0 failed; 2 ignored.
113+
- `cargo test -p tri`: 78 passed; 0 failed.
114+
- `cargo test -p t27c --test icarus_lowerable`: 226 passed; 0 failed.
115+
- Direct `t27c parse` W766: PASS.
116+
- Direct `t27c icarus-lowerable` W766: PASS (`lowerable`).
117+
- Direct `t27c icarus-simulate` W766: PASS (17 cycles, PASSED).
118+
- Direct `t27c icarus-cocotb` W766: PASS (`reference-model OK`).
119+
120+
### Scientific / engineering background
121+
- IEEE 1800-2017 7.4.1/7.4.3 define packed-array total width as the product of
122+
packed dimensions, with no power-of-two restriction. Variant A emits a single
123+
718,848-bit packed vector, which is legal SystemVerilog.
124+
- Lutsig verified array lowering and CIRCT `HWLegalizeModules` show that
125+
flattening nested arrays to wide packed vectors is a well-founded compiler
126+
discipline, even when outer dimensions are non-power-of-two.
127+
- Icarus issue #1134 documents assertion failures for unpacked arrays of packed
128+
structs; t27 scalar flattening avoids that construct entirely.
129+
- Yosys issue #2677 / #4653 confirm that arrays of packed structs remain
130+
unsupported in the native frontend; t27 packed-vector lowering avoids the
131+
gap.
132+
- 2025-2026 ternary/MVL literature scan found:
133+
- TeLLMe v2 / TeLLMe — end-to-end ternary LLM accelerators on AMD KV260 using
134+
table-lookup matmul (25/143 tok/s decode/prefill under 5 W; arXiv 2025).
135+
- TerEffic — Alveo U280 ternary LLM accelerator, 16,300 tok/s at 455 tok/s/W
136+
for 370M model (arXiv 2025).
137+
- Hardware Generation and Exploration of LUT-Based Accelerators for 1.58-bit
138+
LLM Inference — open-source generator + cost model, TSMC 16 nm, accepted at
139+
IEEE ISPASS 2026 (arXiv 2026).
140+
- 5500FP / GargantuRAM — 24-trit balanced ternary RISC processor on Efinix
141+
Trion FPGA at 20 MHz, 120-instruction ISA, real ±3.3 V ternary I/O,
142+
CERN-OHL-P v2 board, commercially available (Zenodo/GitHub 2026).
143+
- Trinity B002 / Trinity v2.0.x — zero-DSP ternary-weight autoregressive LLM
144+
inference on Xilinx Artix-7 via OpenXC7, ~63 tok/s @ ~1 W, QMTech XC7A100T
145+
(Zenodo 2026).
146+
- Unbalanced ternary full adder in CNTFET — 42-transistor multi-threshold
147+
design with 35.8–75.2% power reduction (IEEE TCAD 2026).
148+
- CNTFET-based ternary full adder — 76/55 CNTFET complete/partial adders with
149+
~24% delay improvement (IEEE TCAD 2025).
150+
- Energy-optimized ternary full adder using capacitive threshold logic and
151+
CNTFETs for DSP (AEU 2026).
152+
- OpenXC7 / nextpnr-xilinx / Project X-Ray — fully open-source Xilinx
153+
7-series toolchain, used for QMTech XC7A100T ternary projects without Vivado.
154+
155+
---
156+
78157
## 2026-07-23 — Wave Loop 764 (module-scope `[347][2]^6 Pt` non-power-of-two outer-dimension AoS variable)
79158

80159
### What worked
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"gen_hash_c": "sha256:bfe7bc95931823b883a3c8edbe65fb23ca5ebc200731b697628d51b04765b140",
3+
"gen_hash_rust": "sha256:9f3d730eda5fb82ff5499b6f43cd965bc2661c015b7d94d8ce324f61d2321444",
4+
"gen_hash_verilog": "sha256:a392cffc872b8c42e9b5207e6edb2e8cc6461c154b0b22070b91ccc885d8e463",
5+
"gen_hash_zig": "sha256:9a525b5462011d62abd9c6fb0c4e15b459e0a0a910d9fc2e04b80fb0d43f0003",
6+
"module": "w766_bench_module_351x2p6_aos_var_call_write",
7+
"ring": 12,
8+
"sealed_at": "2026-07-23T17:25:48Z",
9+
"spec_hash": "sha256:25fb588ab39e321ee5e315dd7e0e4882ab4cd2d25cfc74617b7ea7d7fd598570",
10+
"spec_path": "specs/scratch/w766_bench_module_351x2p6_aos_var_call_write.t27"
11+
}

bootstrap/tests/icarus_lowerable.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4081,6 +4081,24 @@ fn accepts_w765_bench_module_349x2p6_aos_var_call_write() {
40814081
}
40824082
}
40834083

4084+
#[test]
4085+
fn accepts_w766_bench_module_351x2p6_aos_var_call_write() {
4086+
let dir = scratch_dir();
4087+
for name in &[
4088+
"w766_bench_module_351x2p6_aos_var_call_write.t27",
4089+
] {
4090+
let p = dir.join(name);
4091+
assert!(p.exists(), "missing W766 witness {}", p.display());
4092+
let (lowerable, json) = run_icarus_lowerable(&p);
4093+
assert!(
4094+
lowerable,
4095+
"expected {} to be lowerable, got: {}",
4096+
p.display(),
4097+
json
4098+
);
4099+
}
4100+
}
4101+
40844102
#[test]
40854103
fn accepts_known_lowerable_witnesses() {
40864104
let dir = scratch_dir();

docs/NOW.md

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
# NOW — Wave Loop 765 close-out / Wave Loop 766 setup (2026-07-23)
1+
# NOW — Wave Loop 766 close-out / Wave Loop 767 setup (2026-07-23)
22

33
Last updated: 2026-07-23
44

5-
## Wave Loop 765 — module-scope `[349][2]^6 Pt` packed array-of-struct from call with indexed signed writes (Closes #1736)
5+
## Wave Loop 766 — module-scope `[351][2]^6 Pt` packed array-of-struct from call with indexed signed writes (Closes #1737)
66

7-
- Branch: `wave-loop-765`
8-
- Issue: #1736
7+
- Branch: `wave-loop-766`
8+
- Issue: #1737
99
- PR: to open
10-
- Report: `docs/reports/FPGA_LOOP_CLOSEOUT_W765_2026-07-23.md`
11-
- Plan: `.claude/plans/wave-loop-765.md`
12-
- Cooperation W766: `.claude/plans/wave-loop-766.md`
10+
- Report: `docs/reports/FPGA_LOOP_CLOSEOUT_W766_2026-07-23.md`
11+
- Plan: `.claude/plans/wave-loop-766.md`
12+
- Cooperation W767: `.claude/plans/wave-loop-767.md`
1313

1414
### What landed
15-
- `specs/scratch/w765_bench_module_349x2p6_aos_var_call_write.t27`
16-
- 22,336 elements, 714,752-bit packed vector (~0.682 MiBit).
17-
- Module-scope `pub var dst : [349][2]^6 Pt` initialized from a function call and
15+
- `specs/scratch/w766_bench_module_351x2p6_aos_var_call_write.t27`
16+
- 22,464 elements, 718,848-bit packed vector (~0.686 MiBit).
17+
- Module-scope `pub var dst : [351][2]^6 Pt` initialized from a function call and
1818
exercised with indexed signed field writes.
1919
- `assert_eq` read-back in a `bench` block (Icarus path does not emit `assert_ne`).
20-
- `scripts/gen_w765.py`
21-
- Generator for the W765 witness; `OUTER = 349`, `MID_IDX = 174`.
20+
- `scripts/gen_w766.py`
21+
- Generator for the W766 witness; `OUTER = 351`, `MID_IDX = 175`.
2222
- `bootstrap/tests/icarus_lowerable.rs`
23-
- Added `accepts_w765_bench_module_349x2p6_aos_var_call_write`.
24-
- `.trinity/experience.md`, `.trinity/current-issue.md`, `.claude/plans/wave-loop-766.md`
25-
- W765 learnings saved and W766 issue/plan created.
23+
- Added `accepts_w766_bench_module_351x2p6_aos_var_call_write`.
24+
- `.trinity/experience.md`, `.trinity/current-issue.md`, `.claude/plans/wave-loop-767.md`
25+
- W766 learnings saved and W767 issue/plan created.
2626

2727
### Not changed
2828
- `bootstrap/src/compiler.rs` — zero compiler changes.
@@ -33,8 +33,21 @@ Last updated: 2026-07-23
3333
- `cargo build --release -p t27c`: OK.
3434
- `cargo test -p t27c --bin t27c`: 1494/0/2.
3535
- `cargo test -p tri`: 78/0.
36-
- `cargo test -p t27c --test icarus_lowerable`: 225/0.
37-
- `t27c parse|icarus-lowerable|icarus-simulate|icarus-cocotb|seal --save` W765: PASS.
36+
- `cargo test -p t27c --test icarus_lowerable`: 226/0.
37+
- `t27c parse|icarus-lowerable|icarus-simulate|icarus-cocotb|seal --save` W766: PASS.
38+
39+
---
40+
41+
## Wave Loop 767 — next odd outer-dimension `[353][2]^6 Pt` (Issue #1738)
42+
43+
- Branch: `wave-loop-767` (to create after W766 merge)
44+
- Issue: #1738
45+
- Plan: `.claude/plans/wave-loop-767.md`
46+
47+
### Candidate variants
48+
- Variant A (recommended): continue the odd outer-dimension ladder with `[353][2]^6 Pt`.
49+
- Variant B: keep width at ~0.686 MiBit but move the packed var to bench/function scope.
50+
- Variant C: add `if`-guarded indexed signed field writes at the current width.
3851

3952
---
4053

0 commit comments

Comments
 (0)