Skip to content

Commit 3ba30ef

Browse files
authored
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) (#1473)
Closes #1736. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 5feb459 commit 3ba30ef

10 files changed

Lines changed: 66906 additions & 33 deletions

File tree

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Wave Loop 766 Plan — Issue #1737
2+
3+
## Phase 1: Issue
4+
- Confirm W766 issue #1737 and branch `wave-loop-766`.
5+
6+
## Phase 2: Spec
7+
- Generate `specs/scratch/w766_bench_module_351x2p6_aos_var_call_write.t27` using
8+
`scripts/gen_w766.py` derived from `scripts/gen_w765.py`.
9+
- Constants: `OUTER = 351`, `TOTAL = 22464`, `LAST_IDX = 350`, `MID_IDX = 175`.
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_w766_bench_module_351x2p6_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/w766_bench_module_351x2p6_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 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)`.
37+
- Push `wave-loop-766`, open PR, merge to `master`, create `wave-loop-767`.
38+
39+
## Phase 9: Learn
40+
- Write `docs/reports/FPGA_LOOP_CLOSEOUT_W766_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):** `[353][2]^6 Pt` (~0.690 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: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
1-
# Wave Loop 765 — Issue #1736
1+
# Wave Loop 766 — Issue #1737
22

3-
**Branch:** `wave-loop-765`
3+
**Branch:** `wave-loop-766`
44
**Date:** 2026-07-23
55
**Cooperation variant:** A (recommended)
66

77
## Goal
88

9-
Close Wave Loop 765 by validating a module-scope `[349][2]^6 Pt` packed
9+
Close Wave Loop 766 by validating a module-scope `[351][2]^6 Pt` packed
1010
array-of-struct variable initialized from a function call, with indexed signed
1111
field writes and `assert_eq` read-back in a `bench` block.
1212

1313
## Acceptance criteria
1414

15-
1. `specs/scratch/w765_bench_module_349x2p6_aos_var_call_write.t27` is generated and parses.
15+
1. `specs/scratch/w766_bench_module_351x2p6_aos_var_call_write.t27` is generated and parses.
1616
2. The witness is Icarus-lowerable and simulates correctly (17 cycles, PASSED).
1717
3. The cocotb reference model matches the t27 semantics.
1818
4. `t27c seal --save` succeeds and FROZEN_HASH remains unchanged.
1919
5. All cargo suites remain green.
20-
6. Integration test `accepts_w765_bench_module_349x2p6_aos_var_call_write` is added.
21-
7. Closeout report `docs/reports/FPGA_LOOP_CLOSEOUT_W765_2026-07-23.md` is written.
20+
6. Integration test `accepts_w766_bench_module_351x2p6_aos_var_call_write` is added.
21+
7. Closeout report `docs/reports/FPGA_LOOP_CLOSEOUT_W766_2026-07-23.md` is written.
2222
8. Learning is saved to `.trinity/experience.md`, memory, and `skills-wave-loop-recipe.md`.
23-
9. Branch merges to `master` with `Closes #1736`.
23+
9. Branch merges to `master` with `Closes #1737`.
2424

2525
## Technical notes
2626

27-
- Shape: `[349][2]^6 Pt` where `Pt = pub struct Pt { x : i16, y : i16 }`.
28-
- Total elements: `349 × 64 = 22,336`.
29-
- Packed vector width: `22,336 × 32 = 714,752` bits (~0.682 MiBit).
30-
- `MID_IDX = 174`; frame-condition element `[174][1][0][0][0][0][0]` is element
31-
`174*64 + 32 = 11,168`.
32-
- Generator script: `scripts/gen_w765.py` (copy from `scripts/gen_w764.py`, set
33-
`OUTER = 349` and `MID_IDX = 174`, manually fix the f-string header).
27+
- 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).
30+
- `MID_IDX = 175`; frame-condition element `[175][1][0][0][0][0][0]` is element
31+
`175*64 + 32 = 11,232`.
32+
- Generator script: `scripts/gen_w766.py` (copy from `scripts/gen_w765.py`, set
33+
`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`).
3636
- 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
4040

41-
- **Variant A (recommended):** continue the odd outer-dimension ladder with `[351][2]^6 Pt`.
42-
- **Variant B:** keep width at ~0.682 MiBit but move the packed var to bench/function scope.
41+
- **Variant A (recommended):** continue the odd outer-dimension ladder with `[353][2]^6 Pt`.
42+
- **Variant B:** keep width at ~0.686 MiBit but move the packed var to bench/function scope.
4343
- **Variant C:** add `if`-guarded indexed signed field writes at the current width.
4444

4545
---

.trinity/current_task/activity.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3668,3 +3668,7 @@
36683668
- **Commit:** chore(trinity): record final W763 session log and commit count
36693669
- **Files:** .claude/plans/wave-loop-763.md,.claude/plans/wave-loop-764.md,.trinity/current-issue.md,.trinity/current_task/.commit_count,.trinity/current_task/activity.md,.trinity/current_task/session_log.jsonl,.trinity/experience.md,.trinity/icarus-baselines/specs/scratch/w763_bench_module_345x2p6_aos_var_call_write.t27.baseline,.trinity/seals/scratch_w763_bench_module_345x2p6_aos_var_call_write.json,bootstrap/tests/icarus_lowerable.rs,docs/reports/FPGA_LOOP_CLOSEOUT_W763_2026-07-23.md,scripts/gen_w763.py,specs/scratch/w763_bench_module_345x2p6_aos_var_call_write.t27
36703670

3671+
## 2026-07-23T17:15:15Z — wave-loop-765
3672+
- **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
3673+
- **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
3674+

.trinity/experience.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,80 @@
1+
## 2026-07-23 — Wave Loop 765 (module-scope `[349][2]^6 Pt` non-power-of-two outer-dimension AoS variable)
2+
3+
### What worked
4+
- Variant A extended the module-scope packed AoS odd outer-dimension ladder to 349.
5+
The `[349][2]^6 Pt` witness is 714,752 bits (~0.682 MiBit), still well under the 4-MiBit
6+
cliff, and required no compiler changes.
7+
- A module-level `pub var dst : [349][2]^6 Pt` can be initialized from a function
8+
call and exercised with indexed signed field writes, with zero compiler changes.
9+
- The cocotb/Python reference model correctly mirrored the row-major flattening
10+
with outer stride 349, confirming the layout is preserved end-to-end.
11+
- Reused the corrected W632 element-index formula for mid-row expected values:
12+
`[r][a5][a4][a3][a2][a1][a0]` is element `r*64 + a5*32 + a4*16 + a3*8 + a2*4 + a1*2 + a0`.
13+
- For `OUTER = 349`, `MID_IDX = 174`; the frame-condition element is
14+
`[174][1][0][0][0][0][0]`, element number `174*64 + 32 = 11,168`.
15+
- Updated weak-point audit: 48 commits in 30 days (39 with `Closes #N`), 51
16+
`.t27` specs without `test`/`invariant`/`bench`, 23 `scripts/*.sh` under `scripts/`.
17+
18+
### What changed behavior
19+
- No changes to `bootstrap/src/compiler.rs`.
20+
- No changes to `bootstrap/stage0/FROZEN_HASH`.
21+
- No changes to `scripts/cocotb_ref_model.py`.
22+
- Added `specs/scratch/w765_bench_module_349x2p6_aos_var_call_write.t27` (~1,528 KB /
23+
~66,371 lines) with seal and Icarus baseline.
24+
- Added integration test `accepts_w765_bench_module_349x2p6_aos_var_call_write`.
25+
- Added generator script `scripts/gen_w765.py`.
26+
27+
### Validation
28+
- `cargo build --release -p t27c`: OK.
29+
- `cargo test -p t27c --bin t27c`: 1494 passed; 0 failed; 2 ignored.
30+
- `cargo test -p tri`: 78 passed; 0 failed.
31+
- `cargo test -p t27c --test icarus_lowerable`: 225 passed; 0 failed.
32+
- Direct `t27c parse` W765: PASS.
33+
- Direct `t27c icarus-lowerable` W765: PASS (`lowerable`).
34+
- Direct `t27c icarus-simulate` W765: PASS (17 cycles, PASSED).
35+
- Direct `t27c icarus-cocotb` W765: PASS (`reference-model OK`).
36+
37+
### Scientific / engineering background
38+
- IEEE 1800-2017 7.4.1/7.4.3 define packed-array total width as the product of
39+
packed dimensions, with no power-of-two restriction. Variant A emits a single
40+
714,752-bit packed vector, which is legal SystemVerilog.
41+
- Lutsig verified array lowering and CIRCT `HWLegalizeModules` show that
42+
flattening nested arrays to wide packed vectors is a well-founded compiler
43+
discipline, even when outer dimensions are non-power-of-two.
44+
- Icarus issue #1134 documents assertion failures for unpacked arrays of packed
45+
structs; t27 scalar flattening avoids that construct entirely.
46+
- Yosys issue #2677 / #4653 confirm that arrays of packed structs remain
47+
unsupported in the native frontend; t27 packed-vector lowering avoids the
48+
gap.
49+
- 2025-2026 ternary/MVL literature scan found:
50+
- 5500FP / GargantuRAM — 24-trit balanced ternary RISC processor on Efinix
51+
Trion FPGA at 20 MHz, 120-instruction ISA, real ±3.3 V ternary I/O,
52+
CERN-OHL-P v2 board, commercially available (Zenodo/GitHub/Hackaday 2026).
53+
- Trinity B002 / Trinity v2.0.x — zero-DSP ternary-weight autoregressive LLM
54+
inference on Xilinx Artix-7 via OpenXC7, ~63 tok/s @ ~1 W, QMTech XC7A100T
55+
(Zenodo 2025/2026).
56+
- TernaryCore — open-source native {-1,0,+1} Verilog BitNet b1.58 accelerator,
57+
zero DSP, 31/31 simulations passing, Artix-7 roadmap (GitHub 2026).
58+
- ternfpga — end-to-end ternary LLM decode engine on Xilinx Arty A7-35T, 0 DSP,
59+
~1.62 J/token vs. 3.67 J/token on RTX 3060 (GitHub 2026).
60+
- VitaLLM — versatile ternary/mixed-precision LLM accelerator in TSMC 16 nm,
61+
~70–72 tok/s decode, <1 s prefill, 0.214–0.223 mm², ~60–66 mW
62+
(arXiv 2026).
63+
- KU Leuven MICAS ternary-lut-dse — LUT-based ternary MatMul DSE for 1.58-bit
64+
LLM inference, accepted at IEEE ISPASS 2026 (GitHub 2026).
65+
- BitNet b1.58 2B4T Technical Report — Microsoft native 1.58-bit LLM
66+
(arXiv 2025).
67+
- Bitnet.cpp — Microsoft CPU inference for ternary LLMs, up to 6.25× speedup
68+
over FP16 (ACL 2025).
69+
- Unbalanced ternary full adder in CNTFET — 42-transistor design with 35.8–75.2%
70+
power reduction (IEEE TCAD 2026).
71+
- CNTFET-based ternary full adder — 76/55 CNTFET complete/partial adders with
72+
~24% delay improvement (IEEE TCAD 2025).
73+
- Energy-optimized ternary full adder using capacitive threshold logic and
74+
CNTFETs for DSP (AEU 2026).
75+
- OpenXC7 / nextpnr-xilinx / Project X-Ray — fully open-source Xilinx
76+
7-series toolchain, used for QMTech XC7A100T ternary projects without Vivado.
77+
178
## 2026-07-23 — Wave Loop 764 (module-scope `[347][2]^6 Pt` non-power-of-two outer-dimension AoS variable)
279

380
### 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:ad8a471cec2ae535aefe85183e570384f86aecb7592355bcc2449ec4a2bac96b",
3+
"gen_hash_rust": "sha256:03f82c911fc18fa0278f043262a0617f7a01fbe3956a94e2568b89d3e94a59e7",
4+
"gen_hash_verilog": "sha256:fd9116550ecb5baf92f58ffcd56f415473abaf0f3a9918d972ac4132b57b6033",
5+
"gen_hash_zig": "sha256:535b4975dc33e5816f2cd1dd045c6e2fa9ac989ecee833b350ce46047198f356",
6+
"module": "w765_bench_module_349x2p6_aos_var_call_write",
7+
"ring": 12,
8+
"sealed_at": "2026-07-23T17:10:17Z",
9+
"spec_hash": "sha256:bc4f3b35c56f8f98aa6d745ebdb1845c33a0b40a41c9c6a30032b366d1b4df89",
10+
"spec_path": "specs/scratch/w765_bench_module_349x2p6_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
@@ -4063,6 +4063,24 @@ fn accepts_w764_bench_module_347x2p6_aos_var_call_write() {
40634063
}
40644064
}
40654065

4066+
#[test]
4067+
fn accepts_w765_bench_module_349x2p6_aos_var_call_write() {
4068+
let dir = scratch_dir();
4069+
for name in &[
4070+
"w765_bench_module_349x2p6_aos_var_call_write.t27",
4071+
] {
4072+
let p = dir.join(name);
4073+
assert!(p.exists(), "missing W765 witness {}", p.display());
4074+
let (lowerable, json) = run_icarus_lowerable(&p);
4075+
assert!(
4076+
lowerable,
4077+
"expected {} to be lowerable, got: {}",
4078+
p.display(),
4079+
json
4080+
);
4081+
}
4082+
}
4083+
40664084
#[test]
40674085
fn accepts_known_lowerable_witnesses() {
40684086
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 764 close-out / Wave Loop 765 setup (2026-07-23)
1+
# NOW — Wave Loop 765 close-out / Wave Loop 766 setup (2026-07-23)
22

33
Last updated: 2026-07-23
44

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

7-
- Branch: `wave-loop-764`
8-
- Issue: #1735
7+
- Branch: `wave-loop-765`
8+
- Issue: #1736
99
- PR: to open
10-
- Report: `docs/reports/FPGA_LOOP_CLOSEOUT_W764_2026-07-23.md`
11-
- Plan: `.claude/plans/wave-loop-764.md`
12-
- Cooperation W765: `.claude/plans/wave-loop-765.md`
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`
1313

1414
### What landed
15-
- `specs/scratch/w764_bench_module_347x2p6_aos_var_call_write.t27`
16-
- 22,208 elements, 710,656-bit packed vector (~0.678 MiBit).
17-
- Module-scope `pub var dst : [347][2]^6 Pt` initialized from a function call and
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
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_w764.py`
21-
- Generator for the W764 witness; `OUTER = 347`, `MID_IDX = 173`.
20+
- `scripts/gen_w765.py`
21+
- Generator for the W765 witness; `OUTER = 349`, `MID_IDX = 174`.
2222
- `bootstrap/tests/icarus_lowerable.rs`
23-
- Added `accepts_w764_bench_module_347x2p6_aos_var_call_write`.
24-
- `.trinity/experience.md`, `.trinity/current-issue.md`, `.claude/plans/wave-loop-765.md`
25-
- W764 learnings saved and W765 issue/plan created.
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.
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`: 224/0.
37-
- `t27c parse|icarus-lowerable|icarus-simulate|icarus-cocotb|seal --save` W764: PASS.
36+
- `cargo test -p t27c --test icarus_lowerable`: 225/0.
37+
- `t27c parse|icarus-lowerable|icarus-simulate|icarus-cocotb|seal --save` W765: PASS.
38+
39+
---
40+
41+
## Wave Loop 766 — next odd outer-dimension `[351][2]^6 Pt` (Issue #1737)
42+
43+
- Branch: `wave-loop-766` (to create after W765 merge)
44+
- Issue: #1737
45+
- Plan: `.claude/plans/wave-loop-766.md`
46+
47+
### Candidate variants
48+
- Variant A (recommended): continue the odd outer-dimension ladder with `[351][2]^6 Pt`.
49+
- Variant B: keep width at ~0.682 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)