Skip to content

Commit fe4c522

Browse files
author
Dmitrii Vasilev
committed
feat(igla): Wave Loop 770 — module-scope [359][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1741)
1 parent 425bcb1 commit fe4c522

10 files changed

Lines changed: 68780 additions & 39 deletions

File tree

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Wave Loop 771 Plan — Issue #1742
2+
3+
## Phase 1: Issue
4+
- Confirm W771 issue #1742 and branch `wave-loop-771`.
5+
6+
## Phase 2: Spec
7+
- Generate `specs/scratch/w771_bench_module_361x2p6_aos_var_call_write.t27` using
8+
`scripts/gen_w771.py` derived from `scripts/gen_w770.py`.
9+
- Constants: `OUTER = 361`, `TOTAL = 23104`, `LAST_IDX = 360`, `MID_IDX = 180`.
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_w771_bench_module_361x2p6_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/w771_bench_module_361x2p6_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 771 — module-scope [361][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1742)`.
37+
- Push `wave-loop-771`, open PR, merge to `master`, create `wave-loop-772`.
38+
39+
## Phase 9: Learn
40+
- Write `docs/reports/FPGA_LOOP_CLOSEOUT_W771_2026-07-24.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):** `[363][2]^6 Pt` (~0.709 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 769 — Issue #1740
1+
# Wave Loop 770 — Issue #1741
22

3-
**Branch:** `wave-loop-769`
3+
**Branch:** `wave-loop-770`
44
**Date:** 2026-07-24
55
**Cooperation variant:** A (recommended)
66

77
## Goal
88

9-
Close Wave Loop 769 by validating a module-scope `[357][2]^6 Pt` packed
9+
Close Wave Loop 770 by validating a module-scope `[359][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/w769_bench_module_357x2p6_aos_var_call_write.t27` is generated and parses.
15+
1. `specs/scratch/w770_bench_module_359x2p6_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_w769_bench_module_357x2p6_aos_var_call_write` is added.
21-
7. Closeout report `docs/reports/FPGA_LOOP_CLOSEOUT_W769_2026-07-24.md` is written.
20+
6. Integration test `accepts_w770_bench_module_359x2p6_aos_var_call_write` is added.
21+
7. Closeout report `docs/reports/FPGA_LOOP_CLOSEOUT_W770_2026-07-24.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 #1740`.
23+
9. Branch merges to `master` with `Closes #1741`.
2424

2525
## Technical notes
2626

27-
- Shape: `[357][2]^6 Pt` where `Pt = pub struct Pt { x : i16, y : i16 }`.
28-
- Total elements: `357 x 64 = 22,848`.
29-
- Packed vector width: `22,848 x 32 = 731,136` bits (~0.697 MiBit).
30-
- `MID_IDX = 178`; frame-condition element `[178][1][0][0][0][0][0]` is element
31-
`178*64 + 32 = 11,424`.
32-
- Generator script: `scripts/gen_w769.py` (copy from `scripts/gen_w768.py`, set
33-
`OUTER = 357` and `MID_IDX = 178`, manually fix the f-string header).
27+
- Shape: `[359][2]^6 Pt` where `Pt = pub struct Pt { x : i16, y : i16 }`.
28+
- Total elements: `359 x 64 = 22,976`.
29+
- Packed vector width: `22,976 x 32 = 735,232` bits (~0.701 MiBit).
30+
- `MID_IDX = 179`; frame-condition element `[179][1][0][0][0][0][0]` is element
31+
`179*64 + 32 = 11,488`.
32+
- Generator script: `scripts/gen_w770.py` (copy from `scripts/gen_w769.py`, set
33+
`OUTER = 359` and `MID_IDX = 179`, 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 `[359][2]^6 Pt`.
42-
- **Variant B:** keep width at ~0.697 MiBit but move the packed var to bench/function scope.
41+
- **Variant A (recommended):** continue the odd outer-dimension ladder with `[361][2]^6 Pt`.
42+
- **Variant B:** keep width at ~0.701 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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3688,3 +3688,11 @@
36883688
- **Commit:** feat(igla): Wave Loop 768 — module-scope [355][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1739)
36893689
- **Files:** .claude/plans/wave-loop-770.md,.trinity/current-issue.md,.trinity/experience.md,.trinity/seals/scratch_w769_bench_module_357x2p6_aos_var_call_write.json,bootstrap/tests/icarus_lowerable.rs,docs/NOW.md,docs/reports/FPGA_LOOP_CLOSEOUT_W769_2026-07-24.md,scripts/gen_w769.py,specs/scratch/w769_bench_module_357x2p6_aos_var_call_write.t27
36903690

3691+
## 2026-07-23T18:30:25Z — wave-loop-770
3692+
- **Commit:** feat(igla): Wave Loop 769 — module-scope [357][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1740)
3693+
- **Files:** .claude/plans/wave-loop-771.md,.trinity/current-issue.md,.trinity/experience.md,.trinity/seals/scratch_w770_bench_module_359x2p6_aos_var_call_write.json,bootstrap/tests/icarus_lowerable.rs,docs/reports/FPGA_LOOP_CLOSEOUT_W770_2026-07-24.md,scripts/gen_w770.py,specs/scratch/w770_bench_module_359x2p6_aos_var_call_write.t27
3694+
3695+
## 2026-07-23T18:31:56Z — wave-loop-770
3696+
- **Commit:** feat(igla): Wave Loop 770 — module-scope [359][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes (Closes #1741)
3697+
- **Files:** docs/NOW.md
3698+

.trinity/experience.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,80 @@
1+
## 2026-07-24 — Wave Loop 770 (module-scope `[359][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 359.
5+
The `[359][2]^6 Pt` witness is 735,232 bits (~0.701 MiBit), still well under the 4-MiBit
6+
cliff, and required no compiler changes.
7+
- A module-level `pub var dst : [359][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 359, 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 = 359`, `MID_IDX = 179`; the frame-condition element is
14+
`[179][1][0][0][0][0][0]`, element number `179*64 + 32 = 11,488`.
15+
- Updated weak-point audit: 44 of 53 30-day commits include `Closes #N` (≈83%).
16+
Clean non-worktree scan: 57 of 873 `.t27` specs lack `test`/`invariant`/`bench`
17+
(≈6.5%). 19 `scripts/*.sh` remain under `scripts/`.
18+
- Fresh 2025-2026 literature scan surfaced ternary FPGA LLM accelerators (TeLLMe,
19+
TerEffic), ternary HDL/ISA work (Ternary VHDL, Setnex, REBEL-6, xTern, T-SAR),
20+
and memristor/FeFET ternary logic-in-memory arrays.
21+
22+
### What changed behavior
23+
- No changes to `bootstrap/src/compiler.rs`.
24+
- No changes to `bootstrap/stage0/FROZEN_HASH`.
25+
- No changes to `scripts/cocotb_ref_model.py`.
26+
- Added `specs/scratch/w770_bench_module_359x2p6_aos_var_call_write.t27` (~1,572 KB /
27+
~68,271 lines) with seal and Icarus baseline.
28+
- Added integration test `accepts_w770_bench_module_359x2p6_aos_var_call_write`.
29+
- Added generator script `scripts/gen_w770.py`.
30+
31+
### Validation
32+
- `cargo build --release -p t27c`: OK.
33+
- `cargo test -p t27c --bin t27c`: 1494 passed; 0 failed; 2 ignored.
34+
- `cargo test -p tri`: 78 passed; 0 failed.
35+
- `cargo test -p t27c --test icarus_lowerable`: 230 passed; 0 failed.
36+
- Direct `t27c parse` W770: PASS.
37+
- Direct `t27c icarus-lowerable` W770: PASS (`lowerable`).
38+
- Direct `t27c icarus-simulate` W770: PASS (17 cycles, PASSED).
39+
- Direct `t27c icarus-cocotb` W770: PASS (`reference-model OK`).
40+
41+
### Scientific / engineering background
42+
- IEEE 1800-2017 7.4.1/7.4.3 define packed-array total width as the product of
43+
packed dimensions, with no power-of-two restriction. Variant A emits a single
44+
735,232-bit packed vector, which is legal SystemVerilog.
45+
- Lutsig verified array lowering and CIRCT `HWLegalizeModules` show that
46+
flattening nested arrays to wide packed vectors is a well-founded compiler
47+
discipline, even when outer dimensions are non-power-of-two.
48+
- Icarus issue #1134 documents assertion failures for unpacked arrays of packed
49+
structs; t27 scalar flattening avoids that construct entirely.
50+
- Yosys issue #2677 / #4653 confirm that arrays of packed structs remain
51+
unsupported in the native frontend; t27 packed-vector lowering avoids the
52+
gap.
53+
- 2025-2026 ternary/MVL literature scan found:
54+
- TeLLMe — energy-efficient ternary LLM accelerator on edge FPGAs with
55+
table-lookup MatMul and fused attention (arXiv 2025).
56+
- TerEffic — highly efficient ternary LLM inference on FPGA with 1.6-bit
57+
compression and LUT-based TMat Core (arXiv 2025).
58+
- Ternary VHDL — IEEE 1076-2008 extension for balanced ternary mixed-radix
59+
VLSI design and GHDL simulation (IEEE ISMVL 2026).
60+
- Setnex ISA v0.8 — clean-slate balanced-ternary ISA with 27-trit words and
61+
configurable three-valued logics (2026).
62+
- REBEL-6 — 32-trit balanced ternary ISA binary-compatible with RV32I
63+
(IEEE ISMVL 2025).
64+
- xTern — RISC-V ISA extension with packed-SIMD ternary MAC for edge NN
65+
inference (arXiv 2024).
66+
- T-SAR — CPU-only ternary LLM inference via in-place SIMD ALU
67+
reorganization, extensible to RISC-V Vector (arXiv 2025).
68+
- Memristor-based balanced ternary logic gates, decoders, full adders, and
69+
Łukasiewicz logic using tri-valued resistance states (EPJP 2026, Phil.
70+
Trans. R. Soc. A 2025, IJCTA 2026).
71+
- FeFET-based non-volatile comparator with built-in less-than operation
72+
(IEICE ELEX 2025).
73+
- OpenXC7 / nextpnr-xilinx / Project X-Ray — fully open-source Xilinx
74+
7-series toolchain, used for QMTech XC7A100T ternary projects without Vivado.
75+
76+
---
77+
178
## 2026-07-23 — Wave Loop 769 (module-scope `[357][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:44aff9f243b87b121d30cae112425b85691e10eca416a0a9289a72ab527eae15",
3+
"gen_hash_rust": "sha256:0d86b72e63446bb3be468c2acc8dfe1212f60ad25839fcc9df6e8917dd42ff2f",
4+
"gen_hash_verilog": "sha256:6aea36e0741286b4cde890fd14201b459bc387fce9570c8f6d1b7eb1051807c0",
5+
"gen_hash_zig": "sha256:02d9e927c6b83323a74dbe3fd09a6fc91d9888da7618466217ddce6af7b9656a",
6+
"module": "w770_bench_module_359x2p6_aos_var_call_write",
7+
"ring": 12,
8+
"sealed_at": "2026-07-23T18:27:12Z",
9+
"spec_hash": "sha256:1dc5281e1481d494baf2a837df74a6d35bbdc09595bb9df56e3df46dfa1fb087",
10+
"spec_path": "specs/scratch/w770_bench_module_359x2p6_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
@@ -4153,6 +4153,24 @@ fn accepts_w769_bench_module_357x2p6_aos_var_call_write() {
41534153
}
41544154
}
41554155

4156+
#[test]
4157+
fn accepts_w770_bench_module_359x2p6_aos_var_call_write() {
4158+
let dir = scratch_dir();
4159+
for name in &[
4160+
"w770_bench_module_359x2p6_aos_var_call_write.t27",
4161+
] {
4162+
let p = dir.join(name);
4163+
assert!(p.exists(), "missing W770 witness {}", p.display());
4164+
let (lowerable, json) = run_icarus_lowerable(&p);
4165+
assert!(
4166+
lowerable,
4167+
"expected {} to be lowerable, got: {}",
4168+
p.display(),
4169+
json
4170+
);
4171+
}
4172+
}
4173+
41564174
#[test]
41574175
fn accepts_known_lowerable_witnesses() {
41584176
let dir = scratch_dir();

docs/NOW.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
# NOW — Wave Loop 769 close-out / Wave Loop 770 setup (2026-07-24)
1+
# NOW — Wave Loop 770 close-out / Wave Loop 771 setup (2026-07-24)
22

33
Last updated: 2026-07-24
44

5-
## Wave Loop 769 — module-scope `[357][2]^6 Pt` packed array-of-struct from call with indexed signed writes (Closes #1740)
5+
## Wave Loop 770 — module-scope `[359][2]^6 Pt` packed array-of-struct from call with indexed signed writes (Closes #1741)
66

7-
- Branch: `wave-loop-769`
8-
- Issue: #1740
7+
- Branch: `wave-loop-770`
8+
- Issue: #1741
99
- PR: to open
10-
- Report: `docs/reports/FPGA_LOOP_CLOSEOUT_W769_2026-07-24.md`
11-
- Plan: `.claude/plans/wave-loop-769.md`
12-
- Cooperation W770: `.claude/plans/wave-loop-770.md`
10+
- Report: `docs/reports/FPGA_LOOP_CLOSEOUT_W770_2026-07-24.md`
11+
- Plan: `.claude/plans/wave-loop-770.md`
12+
- Cooperation W771: `.claude/plans/wave-loop-771.md`
1313

1414
### What landed
15-
- `specs/scratch/w769_bench_module_357x2p6_aos_var_call_write.t27`
16-
- 22,848 elements, 731,136-bit packed vector (~0.697 MiBit).
17-
- Module-scope `pub var dst : [357][2]^6 Pt` initialized from a function call and
15+
- `specs/scratch/w770_bench_module_359x2p6_aos_var_call_write.t27`
16+
- 22,976 elements, 735,232-bit packed vector (~0.701 MiBit).
17+
- Module-scope `pub var dst : [359][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_w769.py`
21-
- Generator for the W769 witness; `OUTER = 357`, `MID_IDX = 178`.
20+
- `scripts/gen_w770.py`
21+
- Generator for the W770 witness; `OUTER = 359`, `MID_IDX = 179`.
2222
- `bootstrap/tests/icarus_lowerable.rs`
23-
- Added `accepts_w769_bench_module_357x2p6_aos_var_call_write`.
24-
- `.trinity/experience.md`, `.trinity/current-issue.md`, `.claude/plans/wave-loop-770.md`
25-
- W769 learnings saved and W770 issue/plan created.
23+
- Added `accepts_w770_bench_module_359x2p6_aos_var_call_write`.
24+
- `.trinity/experience.md`, `.trinity/current-issue.md`, `.claude/plans/wave-loop-771.md`
25+
- W770 learnings saved and W771 issue/plan created.
2626

2727
### Not changed
2828
- `bootstrap/src/compiler.rs` — zero compiler changes.
@@ -33,20 +33,20 @@ Last updated: 2026-07-24
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`: 229/0.
37-
- `t27c parse|icarus-lowerable|icarus-simulate|icarus-cocotb|seal --save` W769: PASS.
36+
- `cargo test -p t27c --test icarus_lowerable`: 230/0.
37+
- `t27c parse|icarus-lowerable|icarus-simulate|icarus-cocotb|seal --save` W770: PASS.
3838

3939
---
4040

41-
## Wave Loop 770 — next odd outer-dimension `[359][2]^6 Pt` (Issue #1741)
41+
## Wave Loop 771 — next odd outer-dimension `[361][2]^6 Pt` (Issue #1742)
4242

43-
- Branch: `wave-loop-770` (to create after W769 merge)
44-
- Issue: #1741
45-
- Plan: `.claude/plans/wave-loop-770.md`
43+
- Branch: `wave-loop-771` (to create after W770 merge)
44+
- Issue: #1742
45+
- Plan: `.claude/plans/wave-loop-771.md`
4646

4747
### Candidate variants
48-
- Variant A (recommended): continue the odd outer-dimension ladder with `[359][2]^6 Pt`.
49-
- Variant B: keep width at ~0.697 MiBit but move the packed var to bench/function scope.
48+
- Variant A (recommended): continue the odd outer-dimension ladder with `[361][2]^6 Pt`.
49+
- Variant B: keep width at ~0.701 MiBit but move the packed var to bench/function scope.
5050
- Variant C: add `if`-guarded indexed signed field writes at the current width.
5151

5252
---

0 commit comments

Comments
 (0)