Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .claude/plans/wave-loop-800.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Wave Loop 800 Plan — Variant A (recommended)

**Date:** 2026-07-24
**Anchor:** φ² + φ⁻² = 3 | TRINITY
**Branch:** `wave-loop-800` (to be created from `wave-loop-799` HEAD because earlier wave PRs remain open)
**Issue:** TBD (next available GitHub issue after W799 PR is opened)
**Cooperation variant:** A

## Goal

Continue the module-scope packed array-of-struct ladder with the recommended Variant A shape: module-scope `[419][2]^6 Pt` initialized from a function call and exercised with indexed signed field writes, then read back with `assert_eq` in a `bench` block.

## Acceptance criteria

1. `specs/scratch/w800_bench_module_419x2p6_aos_var_call_write.t27` is generated and parses.
2. The witness is Icarus-lowerable and simulates correctly (17 cycles, PASSED).
3. The cocotb reference model matches the t27 semantics.
4. `t27c seal --save` succeeds and `FROZEN_HASH` stays unchanged.
5. All cargo suites remain green.
6. Integration test `accepts_w800_bench_module_419x2p6_aos_var_call_write` is added to `bootstrap/tests/icarus_lowerable.rs`.
7. Closeout report `docs/reports/FPGA_LOOP_CLOSEOUT_W800_2026-07-24.md` is written with weak-point audit, literature scan, and validation matrix.
8. Next-wave plan `.claude/plans/wave-loop-801.md` with three cooperation variants is created.
9. Learning is saved to `.trinity/experience.md`, `.claude/skills/t27-wave-loop.md`, persistent memory, and `.trinity/current-issue.md`.

## Technical notes

- Shape: `[419][2]^6 Pt` where `Pt = pub struct Pt { x : i16, y : i16 }`.
- Total elements: `419 x 64 = 26,816`.
- Packed vector width: `26,816 x 32 = 858,112` bits (~0.818 MiBit).
- `MID_IDX = 209`; frame-condition element `[209][1][0][0][0][0][0]` is element number `209*64 + 32 = 13,408`.
- Generator script `scripts/gen_w800.py` should be copied from `scripts/gen_w799.py`, update `OUTER = 419` and `MID_IDX = 209`, and fix the destination path and hardcoded module prefix in the f-string header.
- Use `assert_eq` on changed elements (`assert_ne` is not emitted by the Icarus simulation path).
- Include `make_grid(32768)` period-identity check because `32768 == 0 (mod 32768)`.
- Zero compiler / reference-model / FROZEN_HASH changes expected for the witness.

## Decomposition

### Phase A — Branch setup (5 min)
1. Create `wave-loop-800` from `wave-loop-799` HEAD because earlier wave PRs remain open.
2. Open next GitHub issue when ready.

### Phase B — Spec + generator (15 min)
3. Copy `scripts/gen_w799.py` to `scripts/gen_w800.py`.
4. Update `OUTER = 419`, `MID_IDX = 209`, fix destination path and module prefix.
5. Run generator to produce `specs/scratch/w800_bench_module_419x2p6_aos_var_call_write.t27`.
6. Verify module name and destination path have no stale `w799` / `417` references.

### Phase C — Test + validation (45 min)
7. Add integration test `accepts_w800_bench_module_419x2p6_aos_var_call_write` to `bootstrap/tests/icarus_lowerable.rs`.
8. `cargo build --release -p t27c`.
9. `t27c parse`, `icarus-lowerable`, `icarus-simulate` (expected 17 cycles), `icarus-cocotb` on the W800 witness.
10. `t27c seal --save` the witness; confirm `FROZEN_HASH` unchanged.
11. `cargo test -p t27c --bin t27c`, `cargo test -p tri`, `cargo test -p t27c --test icarus_lowerable`, `cargo test -p t27c --test verilog_const_array`.
12. `cargo clippy -p t27c`.

### Phase D — Closeout + cooperation variants (30 min)
13. Write `docs/reports/FPGA_LOOP_CLOSEOUT_W800_2026-07-24.md` with audit, literature, validation, and three W801 cooperation variants.
14. Update `docs/NOW.md` and `.trinity/current-issue.md`.

### Phase E — Save skills + memory (15 min)
15. Append W800 worked example to `.claude/skills/t27-wave-loop.md`.
16. Update `.trinity/experience.md`.
17. Save memory file `wave-loop-800.md` and pointer in `MEMORY.md`.

## Cooperation variants for Wave Loop 801

- **Variant A (recommended):** continue odd outer-dimension ladder with `[421][2]^6 Pt` (~0.822 MiBit, 26,944 elements, 862,208-bit packed vector). Zero compiler changes expected.
- **Variant B:** keep `[419][2]^6 Pt` width but move the packed var to bench/function scope to exercise function-local non-power-of-two packed arrays.
- **Variant C:** keep `[419][2]^6 Pt` width and add `if`-guarded indexed signed field writes to exercise control-flow + packed-vector writes.

## Exit criteria

- W800 witness parses, lowers, simulates, cocotb-matches, and seals.
- All cargo suites green.
- Closeout report written.
- `.trinity/experience.md` updated.
- Skills and memory saved.
- Commit with `Closes #N`, push `wave-loop-800`, open PR.

*φ² + φ⁻² = 3 | TRINITY*
41 changes: 41 additions & 0 deletions .claude/skills/t27-wave-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,47 @@ grepping for stale wave numbers and outer dimensions after each copy, keep the
`make_grid(32768)` period-identity check, and use `assert_eq` on changed elements
because `assert_ne` is not emitted by the Icarus simulation path.

## Worked example — Wave Loop 799

Wave Loop 799 continued the module-scope packed-array-of-struct ladder with no
compiler changes, branching from `wave-loop-798` HEAD because earlier wave PRs
remained open awaiting review:

- Generated `scripts/gen_w799.py` from `scripts/gen_w798.py` with `OUTER = 417`
and `MID_IDX = 208`.
- Fixed both the generator destination path and the module header f-string from
stale `w798` / `415` references to `w799_bench_module_417x2p6_aos_var_call_write`
before regenerating.
- Produced `specs/scratch/w799_bench_module_417x2p6_aos_var_call_write.t27`
(26,688 elements, 854,016-bit packed vector, ~0.814 MiBit).
- Added integration test `accepts_w799_bench_module_417x2p6_aos_var_call_write`
after the existing W798 tests in `bootstrap/tests/icarus_lowerable.rs`.
- Ran `t27c parse`, `icarus-lowerable`, `icarus-simulate` (17 cycles, PASSED),
`icarus-cocotb` (reference-model OK), and `t27c seal --save`.
- No changes to `bootstrap/src/compiler.rs`, `bootstrap/stage0/FROZEN_HASH`, or
`scripts/cocotb_ref_model.py` for the witness itself.
- Validation: `cargo build --release -p t27c` green,
`cargo clippy -p t27c` green (780 warnings, 0 errors),
`cargo test -p t27c --bin t27c` 1494/0/2, `cargo test -p tri` 78/0,
`cargo test -p flash-spi` 2/0,
`cargo test -p t27c --test bitnet_pipeline` 20/0,
`cargo test -p t27c --test bitnet_top` 17/0,
`cargo test -p t27c --test icarus_lowerable` 259/0,
`cargo test -p t27c --test verilog_const_array` 2/0.
- Refreshed weak-point audit and 2025–2026 ternary/MVL literature scan.
- Wrote `docs/reports/FPGA_LOOP_CLOSEOUT_W799_2026-07-24.md` and
`.claude/plans/wave-loop-800.md` with three cooperation variants.

Key learning: the mechanical ladder is now 27 waves deep (W774–W799) with zero
compiler changes, confirming the packed-vector AoS lowering is robust up to at
least `[417][2]^6 Pt` (26,688 elements, ~0.814 MiBit). The generator copy hazard
continues to be the only manual failure mode, and it now spans two distinct text
locations (destination path + module header f-string). A single parameterized
wave-prefix variable in the generator template would eliminate both. Continue
grepping for stale wave numbers and outer dimensions after each copy, keep the
`make_grid(32768)` period-identity check, and use `assert_eq` on changed elements
because `assert_ne` is not emitted by the Icarus simulation path.

---

*φ² + φ⁻² = 3 | TRINITY*
22 changes: 11 additions & 11 deletions .trinity/current-issue.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
# Current Issue — Wave Loop 799 setup
# Current Issue — Wave Loop 800 setup

**Date:** 2026-07-24
**Anchor:** φ² + φ⁻² = 3 | TRINITY

## Active wave

- **Wave:** 799
- **Issue:** TBD (open after W798 PR is created)
- **Branch:** `wave-loop-799` (to create from `wave-loop-798` HEAD because earlier PRs remain open)
- **Plan:** `.claude/plans/wave-loop-799.md`
- **Recommended variant:** A — module-scope `[417][2]^6 Pt` packed array-of-struct variable from call with indexed signed writes.
- **Wave:** 800
- **Issue:** TBD (open after W799 PR is created)
- **Branch:** `wave-loop-800` (to create from `wave-loop-799` HEAD because earlier PRs remain open)
- **Plan:** `.claude/plans/wave-loop-800.md`
- **Recommended variant:** A — module-scope `[419][2]^6 Pt` packed array-of-struct variable from call with indexed signed writes.

## Goal

Continue the odd outer-dimension module-scope packed array-of-struct ladder with `[417][2]^6 Pt`.
Expected 26,688 elements, 854,016-bit packed vector (~0.814 MiBit), still under the 4-MiBit cliff,
Continue the odd outer-dimension module-scope packed array-of-struct ladder with `[419][2]^6 Pt`.
Expected 26,816 elements, 858,112-bit packed vector (~0.818 MiBit), still under the 4-MiBit cliff,
with zero compiler / reference-model / FROZEN_HASH changes.

## Acceptance criteria

1. `specs/scratch/w799_bench_module_417x2p6_aos_var_call_write.t27` is generated and parses.
1. `specs/scratch/w800_bench_module_419x2p6_aos_var_call_write.t27` is generated and parses.
2. Icarus-lowerable, simulates (17 cycles, PASSED), and cocotb reference-model matches.
3. `t27c seal --save` succeeds and `FROZEN_HASH` stays unchanged.
4. All cargo suites green.
5. Integration test added to `bootstrap/tests/icarus_lowerable.rs`.
6. Closeout report written with weak-point audit, literature scan, and three W800 cooperation variants.
6. Closeout report written with weak-point audit, literature scan, and three W801 cooperation variants.
7. Skills and experience saved.

## Notes

- Copy `scripts/gen_w798.py` to `scripts/gen_w799.py`, update `OUTER = 417` and `MID_IDX = 208`, and fix the destination path/module header copy hazard before generating.
- Copy `scripts/gen_w799.py` to `scripts/gen_w800.py`, update `OUTER = 419` and `MID_IDX = 209`, and fix the destination path/module header copy hazard before generating.
- Use `assert_eq` on changed elements; `assert_ne` is not emitted by the Icarus simulation path.
- Keep the `make_grid(32768)` period-identity check because `32768 ≡ 0 (mod 32768)`.

Expand Down
8 changes: 8 additions & 0 deletions .trinity/current_task/activity.md
Original file line number Diff line number Diff line change
Expand Up @@ -3860,3 +3860,11 @@
- **Commit:** feat(igla): Wave Loop 798 — module-scope [415][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes
- **Files:** docs/NOW.md,docs/reports/FPGA_LOOP_CLOSEOUT_W798_2026-07-24.md

## 2026-07-25T10:57:14Z — wave-loop-799
- **Commit:** docs(trinity): Wave Loop 798 closeout — record session state and commit count
- **Files:** .claude/plans/wave-loop-800.md,.claude/skills/t27-wave-loop.md,.trinity/current-issue.md,.trinity/experience.md,.trinity/seals/scratch_w799_bench_module_417x2p6_aos_var_call_write.json,bootstrap/tests/icarus_lowerable.rs,docs/NOW.md,docs/reports/FPGA_LOOP_CLOSEOUT_W799_2026-07-24.md,scripts/gen_w799.py,specs/scratch/w799_bench_module_417x2p6_aos_var_call_write.t27

## 2026-07-25T10:58:58Z — wave-loop-799
- **Commit:** feat(igla): Wave Loop 799 — module-scope [417][2]^6 Pt non-power-of-two outer-dimension array-of-struct variable from call with indexed signed writes
- **Files:** docs/NOW.md,docs/reports/FPGA_LOOP_CLOSEOUT_W799_2026-07-24.md

104 changes: 104 additions & 0 deletions .trinity/experience.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,107 @@
## 2026-07-24 — Wave Loop 799 (module-scope `[417][2]^6 Pt` non-power-of-two outer-dimension AoS variable, issue #1527)

### What worked
- Variant A extended the module-scope packed AoS odd outer-dimension ladder to 417.
The `[417][2]^6 Pt` witness is 854,016 bits (~0.814 MiBit), still well under the 4-MiBit
cliff, and required no compiler changes.
- A module-level `pub var dst : [417][2]^6 Pt` can be initialized from a function
call and exercised with indexed signed field writes, with zero compiler changes.
- The cocotb/Python reference model correctly mirrored the row-major flattening
with outer stride 417, confirming the layout is preserved end-to-end.
- Reused the corrected W632 element-index formula for mid-row expected values:
`[r][a5][a4][a3][a2][a1][a0]` is element `r*64 + a5*32 + a4*16 + a3*8 + a2*4 + a1*2 + a0`.
- For `OUTER = 417`, `MID_IDX = 208`; the frame-condition element is
`[208][1][0][0][0][0][0]`, element number `208*64 + 32 = 13,344`.
- The generator copy hazard struck again: both the destination path and the module
header f-string in `scripts/gen_w799.py` carried stale `w798` / `415` references
after copying from W798. Fixing both before regenerating resolved it. This is the same
hazard documented in W782–W798 learnings and remains the only manual step in the
otherwise mechanical flow.
- Fresh weak-point audit (2026-07-24) found no new actionable items. The W783 fix
for `bootstrap/tests/verilog_const_array.rs:166` remains green; the pre-existing
`verilog_array_literal_expr` regression is still out of scope for the witness ladder.
- 30-day subject-line traceability remained low; the closeout commit carries
`Closes #1527` in the subject, but the overall rate needs improvement.
Continue putting issue references in commit subjects.

### What changed behavior
- No changes to `bootstrap/src/compiler.rs`.
- No changes to `bootstrap/stage0/FROZEN_HASH` (`68a0b933c00ba5efd7facb5997f00880c3eecae55e6ac5e8cea2aee399b92adc`).
- No changes to `scripts/cocotb_ref_model.py`.
- Added `specs/scratch/w799_bench_module_417x2p6_aos_var_call_write.t27` (~1,829 KB /
~79,291 lines) with seal and Icarus baseline.
- Added integration test `accepts_w799_bench_module_417x2p6_aos_var_call_write`
in `bootstrap/tests/icarus_lowerable.rs`.
- Added generator script `scripts/gen_w799.py`.
- Wrote `docs/reports/FPGA_LOOP_CLOSEOUT_W799_2026-07-24.md` and
`.claude/plans/wave-loop-800.md` with three cooperation variants.

### Validation
- `cargo build --release -p t27c`: OK.
- `cargo clippy -p t27c`: OK (780 warnings, 0 errors).
- `cargo test -p t27c --bin t27c`: 1494 passed; 0 failed; 2 ignored.
- `cargo test -p tri`: 78 passed; 0 failed.
- `cargo test -p flash-spi`: 2 passed; 0 failed.
- `cargo test -p t27c --test bitnet_pipeline`: 20 passed; 0 failed.
- `cargo test -p t27c --test bitnet_top`: 17 passed; 0 failed.
- `cargo test -p t27c --test icarus_lowerable`: 259 passed; 0 failed.
- `cargo test -p t27c --test verilog_const_array`: 2 passed; 0 failed.
- Direct `t27c parse` W799: PASS.
- Direct `t27c icarus-lowerable` W799: PASS (`lowerable`).
- Direct `t27c icarus-simulate` W799: PASS (17 cycles, PASSED).
- Direct `t27c icarus-cocotb` W799: PASS (`reference-model OK`).
- Direct `t27c seal --save` W799: PASS.

### Scientific / engineering background
- IEEE 1800-2017 §7.4.1/7.4.3 define packed-array width as the product of packed
dimensions, with no power-of-two restriction. Variant A emits a single
854,016-bit packed vector, which is legal SystemVerilog.
- Lutsig's verified array lowering and CIRCT's `HWLegalizeModules` show that
flattening nested arrays to wide packed vectors is a well-founded compiler
discipline, even when outer dimensions are non-power-of-two.
- Icarus issue #1134 documents assertion failures for unpacked arrays of packed
structs; t27's scalar flattening avoids that construct entirely.
- Yosys issue #2677 / #4653 confirm that arrays of packed structs remain
unsupported in the native frontend; t27's packed-vector lowering avoids the
gap.
- Recent 2025–2026 ternary/MVL literature reinforces that flattening ternary
aggregate data to wide binary packed vectors is a pragmatic, toolchain-compatible
path while native MVL fabrics mature:
- IEEE Access 2025: An RTL-Based General Synthesis Methodology for
Device-Independent Ternary Logic Circuits.
- Chinese Journal of Electronics 2026: Tlsys, an RTL-to-CNFET ternary synthesis
framework for 500k+ gate designs.
- IEEE Access 2025: A Generalized Multiple-Valued FPGA Architecture Based on
Improved T-Gate Circuit.
- 2026 IEEE ISMVL: Ternary VHDL, a balanced ternary extension to IEEE 1076-2008.
- arXiv 2025: TerEffic, highly efficient ternary LLM inference on FPGA.
- Zenodo 2026: Trinity B002, zero-DSP FPGA architecture for ternary inference.
- GitHub 2026: Vericert v2.0.0, a formally verified HLS tool based on CompCert,
whose scheduler uses a validated three-valued logic checker.

### Patterns to reuse
- Use a non-power-of-two outer dimension under the 4-MiBit cliff to test layout
correctness while keeping simulation fast.
- Keep signed-i16 leaf values inside range with `(2*e + offset) % 32768` for
any element count ≤ 163,840.
- Reuse the W589 wholesale module-scope initializer path for any scalar-struct
array shape; no new compiler work is needed until the wall-clock limit is hit.
- Prefer `assert_eq` over `assert_ne` in Icarus-lowerable simulation blocks;
`assert_ne` is accepted by the classifier but not lowered by the simulation
emitter.
- When computing expected values for deep packed-array indices, convert the full
row-major LSB-first element index explicitly rather than guessing inner-dimension
offsets.
- Parameterizing the wave prefix and destination path inside the generator template
would eliminate the recurring copy hazard; until then, grep for both the old wave
number and the old outer dimension after copying a generator and before the first
generation.

### Anti-patterns to avoid
- Do not use single-line literals for >1,000 element initializers; the scanner
becomes the bottleneck.
- Do not rely on `assert_ne` being emitted for Icarus simulation.

## 2026-07-24 — Wave Loop 798 (module-scope `[415][2]^6 Pt` non-power-of-two outer-dimension AoS variable, issue #1525)

### What worked
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"gen_hash_c": "sha256:b6e616c90f0627e61f22522ed7676ef0a56b2c74dc6f3a205612d0c165ac3528",
"gen_hash_rust": "sha256:62db96e9c378828f6e70cc937802669dd52fa4666a19a199fc8601b5da653666",
"gen_hash_verilog": "sha256:e5e341f899c76df7567f8dc3a434fbc8a61d4e676331c6a156c6bae08f5da073",
"gen_hash_zig": "sha256:3be6caed0960f9458f23b5a02218c106551cea26f929565dab0e8bf4d50f9f22",
"module": "w799_bench_module_417x2p6_aos_var_call_write",
"ring": 12,
"sealed_at": "2026-07-25T10:52:18Z",
"spec_hash": "sha256:6e1334ac2213b43e24c3379f5cd781e781e581b8a609065ec7e2fc2b56e24819",
"spec_path": "/Users/playra/t27/specs/scratch/w799_bench_module_417x2p6_aos_var_call_write.t27"
}
18 changes: 18 additions & 0 deletions bootstrap/tests/icarus_lowerable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4675,6 +4675,24 @@ fn accepts_w798_bench_module_415x2p6_aos_var_call_write() {
}
}

#[test]
fn accepts_w799_bench_module_417x2p6_aos_var_call_write() {
let dir = scratch_dir();
for name in &[
"w799_bench_module_417x2p6_aos_var_call_write.t27",
] {
let p = dir.join(name);
assert!(p.exists(), "missing W799 witness {}", p.display());
let (lowerable, json) = run_icarus_lowerable(&p);
assert!(
lowerable,
"expected {} to be lowerable, got: {}",
p.display(),
json
);
}
}

#[test]
fn accepts_known_lowerable_witnesses() {
let dir = scratch_dir();
Expand Down
Loading
Loading