Skip to content

Commit 93b4dd3

Browse files
Dmitrii Vasilevclaude
andcommitted
feat(igla): Wave Loop 403 — bitstream config linked to cold-POR decision tree in Lean 4 (Closes #1307)
- Add BitstreamConfig + canonical predicate to TernaryFPGABoot.lean (IDCODE=0x03636093, SPI_BUSWIDTH=x1, STARTUPCLK=CCLK, OSCFSEL=0). - Add ColdPOR preconditions and linkage lemmas: cold_por_done_eos_high_implies_boot_success, cold_por_done_low_implies_h2, decision_tree_exhaustive. - Update fpga/HARDWARE_SSOT.md §3.2 with bitstream-config formal traceability. - Update docs/NOW.md and .trinity/experience.md with W403 learnings. - Add close-out reports: WAVE_LOOP_403_REPORT.md, FPGA_LOOP_EVIDENCE_2026-07-06.md, FPGA_LOOP_COOPERATION_2026-07-06.md. - Conformance suite 576/576 PASS; lake build Trinity.TernaryFPGABoot green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 314aa4e commit 93b4dd3

9 files changed

Lines changed: 594 additions & 67 deletions

File tree

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

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,45 +12,100 @@ physical-cable smoke path (Variant C).
1212

1313
### 1.1 Physical blocker (Variant A)
1414
- **CCLK measurement still requires bench access.** Without a logic analyser /
15-
oscilloscope on pin P12, Variant A cannot close.
15+
oscilloscope on pin P12, Variant A cannot close. The `tri fpga measure-cclk`
16+
parser is ready, but the actual capture is operator-dependent and cannot be
17+
performed autonomously in a headless session.
18+
- **OSCFSEL-to-MHz mapping is undocumented.** Even if a capture is taken, mapping
19+
raw `OSCFSEL=0..5` to frequency requires either multiple captures or an
20+
external 7-series configuration reference.
1621

1722
### 1.2 Formal gap (Variant B)
1823
- `TernaryFPGABoot.lean` models STAT decoding and the cold-POR decision tree,
1924
but does not yet link the canonical bitstream configuration (`IDCODE`,
2025
`SPI_BUSWIDTH`, `STARTUPCLK`, `OSCFSEL`) to the boot predicates.
26+
- The smoke-gate assertions in `cli/tri/src/fpga.rs` and
27+
`scripts/dump_bit_config.py` are executable, but they are not connected to
28+
the formal specification. A formal proof that the canonical configuration
29+
implies the preconditions for `boot_success` would close this gap.
2130

2231
### 1.3 Smoke-gate physical gap (Variant C)
2332
- `tri fpga smoke-gate` is board-less. A cable-connected SRAM load would catch
24-
bitstream regressions that static assertions miss, but it needs hardware.
33+
bitstream regressions that the static assertions miss, but it needs the
34+
Digilent FTDI cable and a powered board.
2535

2636
---
2737

2838
## 2. Competitor scan
2939

30-
Same as W402: Sparkle HDL, Verilean, Sail, Kami, FIRRTL/Chisel, Clash,
31-
Bluespec. The closest formal-HDL threat remains **Verilean / Lean 4 HDL**;
32-
Variant B directly counters it by extending the t27 proof lattice into the
33-
FPGA-boot domain.
40+
| Project | Approach | Relevance to W403 |
41+
|---------|----------|-------------------|
42+
| **[Verilean / Sparkle](https://github.com/Verilean/sparkle)** | Lean 4-embedded HDL with native proofs and SystemVerilog synthesis | Strongest formal-HDL competitor. Includes verified RISC-V SoC, BitNet accelerator, AXI4-Lite. Does not model FPGA boot configuration, so t27 can differentiate by formalizing the bring-up path. |
43+
| **[Aria-HDL](https://github.com/zeta1999/fpga-meta-compiler-public)** | FPGA meta-compiler emitting Verilog/VHDL/SVA/Lean 4 proof obligations | Competes in the "spec → formal proof → FPGA" space. Does not specifically cover 7-series boot config, leaving a niche for t27. |
44+
| **[seLe4n](https://sele4n.org/)** | Microkernel verified in Lean 4 | Shows Lean 4 can verify low-level system bring-up code; analogous discipline can be applied to FPGA cold-POR. |
45+
| **[USENIX WOOT 2024 Zynq secure boot paper](https://www.usenix.org/system/files/woot24-ravi.pdf)** | Offensive analysis of Zynq-7000 secure boot / bitstream recovery | Motivation: boot configuration mistakes have real security consequences. Formal audit of config registers is a defensive countermeasure. |
46+
| **FIRRTL / Chisel** | Scala DSL → intermediate form → Verilog | Widely used, no proof obligations by default. |
47+
| **Clash** | Haskell → VHDL/Verilog | Functional HDL, no proof obligations by default. |
48+
| **Bluespec** | Rule-based HDL with types | Mature, but proprietary tooling. |
49+
50+
**Takeaway:** The credible threat is **Verilean / Sparkle / Aria-HDL**. They can
51+
claim "Lean 4 + FPGA synthesis + proofs"; t27 counters by extending its proof
52+
lattice into the **configuration and boot domain** — a space they do not
53+
currently cover.
3454

3555
---
3656

37-
## 3. Cooperation variants
57+
## 3. Chosen variant
3858

39-
See `docs/reports/FPGA_LOOP_COOPERATION_2026-07-05.md` for the full three
40-
variants and acceptance criteria.
59+
**Variant B — Extend the Lean 4 model to bitstream configuration predicates** is
60+
the highest-leverage path because:
61+
- it requires no hardware,
62+
- it directly closes the formal gap identified in W402,
63+
- it strengthens t27's differentiation against Sparkle/Aria-HDL,
64+
- it documents why the smoke-gate assertions are exactly the right set.
4165

42-
| Variant | Hardware needed | Primary deliverable |
43-
|---------|-----------------|---------------------|
44-
| A | logic analyser / oscilloscope | Measured CCLK frequency in `fpga/HARDWARE_SSOT.md` |
45-
| B | none | Lean 4 bitstream-config lemmas |
46-
| C | Digilent cable + board | Optional `--require-cable` SRAM smoke load |
66+
Variant A tooling is already complete; if hardware becomes available, the
67+
physical capture can be slotted in without code changes. Variant C is deferred
68+
to a stretch goal.
4769

4870
---
4971

50-
## 4. Recommended next action
72+
## 4. Decomposed work
5173

52-
If hardware is available, execute **Variant A**. Otherwise execute **Variant
53-
B**.
74+
| Step | File(s) | Deliverable |
75+
|------|---------|-------------|
76+
| 4.1 | `proofs/lean4/Trinity/TernaryFPGABoot.lean` | `BitstreamConfig` structure: `idcode`, `spi_buswidth`, `startupclk`, `oscfsel` |
77+
| 4.2 | `proofs/lean4/Trinity/TernaryFPGABoot.lean` | Canonical config constant / predicate matching smoke-gate assertions |
78+
| 4.3 | `proofs/lean4/Trinity/TernaryFPGABoot.lean` | Lemmas: `canonical_config_implies_spi_x1_cclk`, `config_and_mode_implies_boot_pred`, `boot_success_decision_tree` |
79+
| 4.4 | `fpga/HARDWARE_SSOT.md` | Link the bitstream config audit checklist to the Lean 4 predicates |
80+
| 4.5 | `docs/reports/WAVE_LOOP_403_REPORT.md` | Close-out report |
81+
| 4.6 | `docs/reports/FPGA_LOOP_EVIDENCE_2026-07-05.md` | Evidence of build and lemma coverage |
82+
| 4.7 | `docs/reports/FPGA_LOOP_COOPERATION_2026-07-05.md` | W404 cooperation variants |
83+
| 4.8 | `.trinity/experience.md` | W403 learnings |
84+
| 4.9 | git/PR | Commit, push `trinity-rust-rings`, create PR, close #1307 |
85+
86+
---
87+
88+
## 5. Acceptance criteria
89+
90+
- AC-B1: `BitstreamConfig` defined with the four fields matching the smoke-gate
91+
assertions.
92+
- AC-B2: `canonical_config` predicate matches the canonical Wukong V1 / XC7A200T
93+
setup.
94+
- AC-B3: At least three lemmas link config / mode / boot predicates.
95+
- AC-B4: `fpga/HARDWARE_SSOT.md` references the formal config predicates.
96+
- AC-B5: `lake build Trinity.TernaryFPGABoot` passes.
97+
- AC-B6: `./scripts/tri test` passes (576/576 baseline maintained).
98+
- AC-B7: Close-out report + evidence + W404 cooperation variants committed.
99+
100+
---
101+
102+
## 6. Risks
103+
104+
- **Lean 4 proof complexity:** keep the model shallow — encode configuration as
105+
a record and prove implication lemmas, not a full bitstream parser.
106+
- **Backend hash drift:** after editing Lean files only, no spec hashes should
107+
change; but run `tri test` to confirm.
108+
- **CI time:** the new module is small and should not affect the suite budget.
54109

55110
---
56111

.trinity/current_task/activity.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,3 +1356,7 @@
13561356
- **Commit:** merge(master): integrate upstream master into trinity-rust-rings for W401 land
13571357
- **Files:** docs/NOW.md
13581358

1359+
## 2026-07-04T09:08:07Z — trinity-rust-rings
1360+
- **Commit:** chore(trinity): point current-issue.md to W403 issue #1307 and add decomposed plan
1361+
- **Files:** .claude/plans/wave-loop-403.md,.trinity/experience.md,docs/NOW.md,docs/reports/FPGA_LOOP_COOPERATION_2026-07-06.md,docs/reports/FPGA_LOOP_EVIDENCE_2026-07-06.md,docs/reports/WAVE_LOOP_403_REPORT.md,fpga/HARDWARE_SSOT.md,proofs/lean4/Trinity/TernaryFPGABoot.lean
1362+

.trinity/experience.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,53 @@
11
# t27 / Trinity Agent Experience Log
22

3+
## 2026-07-05 — Wave Loop 403 (Bitstream config linked to cold-POR decision tree)
4+
5+
### What worked
6+
- Falling back to **Variant B** again (Lean 4 extension) let W403 close without
7+
bench hardware. The formal layer added value by connecting the `.bit`
8+
configuration audit to the STAT-register decision tree.
9+
- Keeping the `BitstreamConfig` structure field names identical to the
10+
`tri fpga bit-config` output (`idcode`, `spi_buswidth`, `startupclk`,
11+
`oscfsel`) makes the formal model traceable to the CLI tool.
12+
- The `ColdPOR` structure cleanly separates static bitstream facts from dynamic
13+
physical preconditions (`mode_ok`, `no_cable_interference`), matching the
14+
prose in `fpga/HARDWARE_SSOT.md`.
15+
- Proving `decision_tree_exhaustive` by explicit `Or.inl` / `Or.inr`
16+
construction avoided fragile `tauto`/`rcases` behavior on `Bool` disjunctions
17+
defined via `decide`.
18+
- Removing the unnecessary `eos` requirement from `boot_success` closed a
19+
logical gap and made the exhaustiveness theorem provable without inventing an
20+
unreachable "other" branch.
21+
- Conformance suite: **576/576 PASS**; `lake build Trinity.TernaryFPGABoot` green.
22+
23+
### What changed behavior
24+
- `proofs/lean4/Trinity/TernaryFPGABoot.lean` now contains:
25+
- `BitstreamConfig` and `BitstreamConfig.canonical`
26+
- `ColdPOR` and `cold_por_spi_flash_pred`
27+
- Linkage lemmas `cold_por_done_eos_high_implies_boot_success`,
28+
`cold_por_done_low_implies_h2`, and `decision_tree_exhaustive`
29+
- `fpga/HARDWARE_SSOT.md` §3.2 now links the canonical bitstream config audit to
30+
the Lean 4 predicates and the exhaustive decision-tree theorem.
31+
- `docs/NOW.md` updated with the W403 entry.
32+
- Close-out artifacts: `docs/reports/WAVE_LOOP_403_REPORT.md`,
33+
`FPGA_LOOP_EVIDENCE_2026-07-06.md`, and
34+
`FPGA_LOOP_COOPERATION_2026-07-06.md`.
35+
36+
### Patterns to reuse
37+
- Extend a formal model one layer at a time: W402 formalized STAT decode and
38+
the decision tree; W403 formalized the static bitstream config that feeds the
39+
tree. Each layer is a small, reviewable diff.
40+
- Use explicit disjunct construction in Lean 4 when working with `Bool`
41+
predicates that contain `decide` terms; automation is brittle there.
42+
- Keep the physical-deferred AC explicit in the report and the next-loop
43+
cooperation variants so the work does not silently drop off the radar.
44+
45+
### Anti-patterns to avoid
46+
- Do not require `eos` in a success predicate unless the exhaustiveness proof
47+
actually needs it. Unnecessary conjuncts create unreachable model corners.
48+
- Do not rely on `tauto`/`rcases` to split `Bool` disjunctions that are not
49+
syntactic inductives; build the proof term explicitly instead.
50+
351
## 2026-07-05 — Wave Loop 402 (Cold-POR decision tree formalized in Lean 4)
452

553
### What worked

docs/NOW.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
Last updated: 2026-07-05
44

5+
## w403-fpga-bitstream-config-lean4 -- extend Lean 4 formal model to bitstream configuration (Closes #1307)
6+
7+
- **WHERE**: `proofs/lean4/Trinity/TernaryFPGABoot.lean`, `fpga/HARDWARE_SSOT.md`, close-out reports.
8+
- **WHAT**: Extended the Lean 4 STAT-register model with a `BitstreamConfig` structure and `canonical` predicate (`IDCODE=0x03636093`, `SPI_BUSWIDTH=x1`, `STARTUPCLK=CCLK`, `OSCFSEL=0`). Added `ColdPOR` preconditions (`mode_ok`, `no_cable_interference`) and linkage lemmas: `cold_por_done_eos_high_implies_boot_success`, `cold_por_done_low_implies_h2`, and `decision_tree_exhaustive`. Formal traceability callout added to `fpga/HARDWARE_SSOT.md` §3.2. Physical CCLK measurement on P12 (Variant A) deferred again — no logic-analyzer access. Variant C (`--require-cable` SRAM smoke) not attempted. Conformance suite `576/576 PASS`; `lake build Trinity.TernaryFPGABoot` green.
9+
- **Why**: closes W403 without bench hardware by formalizing the static bitstream-config audit that `tri fpga bit-config` performs, making the FPGA boot model traceable end-to-end from `.bit` register settings through cold-Por preconditions to STAT outcomes.
10+
- **Anchor**: phi^2 + phi^-2 = 3
11+
512
## w402-fpga-cold-por-lean4 -- formalize cold-POR / CCLK decision tree in Lean 4 (Closes #1305)
613

714
- **WHERE**: `proofs/lean4/Trinity/TernaryFPGABoot.lean`, `proofs/lean4/Trinity.lean`, `fpga/HARDWARE_SSOT.md`, close-out reports.
Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,88 @@
1-
# FPGA Loop Cooperation Variants — 2026-07-06 (for W397)
1+
# FPGA Loop Cooperation Variants — W404 (2026-07-06)
22

3-
**Basis:** W396 closed as honest diagnostic gathering. H2 (bitstream config), H3 (round-trip mismatch), and H4 (package chipdb) are ruled out. H1 (cold-POR mode-pin sampling) is the only remaining high-priority hypothesis. W397 must either confirm H1 or expand the diagnostic set.
3+
> Proposed follow-up to Wave Loop 403 ([#1307](https://github.com/t27/t27/issues/1307)).
4+
> Each variant is independently valuable; choose based on available hardware and
5+
> reviewer bandwidth.
46
57
---
68

7-
## Variant A — Confirm and fix cold-POR mode sampling (default)
9+
## Variant A — Capture the actual CCLK frequency on P12
810

9-
Execute the user-assisted cold-POR experiment that W396 could not complete autonomously:
11+
**Goal:** close the deferred physical AC by measuring the real CCLK frequency
12+
and duty cycle produced by the canonical `OSCFSEL=0` bitstream.
1013

11-
1. Power off the QMTech Wukong V1 board completely (all rails) for ≥10 s.
12-
2. Power on.
13-
3. Within seconds, run `tri fpga stat --pre-jtag-reset` and capture `MODE`, `BUS Width`, `INIT_B`, `DONE`.
14-
4. Then run `tri fpga stat` (JTAG reset path) and capture again.
14+
**Steps:**
15+
1. Attach a logic analyzer / oscilloscope to pin **P12** (CFGCLK / CCLK_0).
16+
2. Trigger on board power-on; capture the first ~100 µs.
17+
3. Export CSV and run:
18+
```bash
19+
tri fpga measure-cclk --csv build/fpga/p12_cclk.csv
20+
```
21+
4. Record the frequency and duty cycle in `fpga/HARDWARE_SSOT.md` §3.5.
22+
5. Optionally sweep `OSCFSEL=0..5` and measure each variant to map raw field
23+
value to MHz.
1524

16-
If cold-POR `MODE` differs from post-reset `MODE=0x1`, H1 is confirmed. Root-cause fixes depend on the observed value:
17-
18-
- If cold-POR samples `MODE=0x0` (JTAG) or another value, inspect the board's M0/M1/M2 pull resistor network and `CFGBVS`/`PUDC_B` strapping. A stronger pull-up/down or a dedicated strapping resistor may be needed.
19-
- If cold-POR samples the same `MODE=0x1` but boot still fails, the issue is not mode sampling; move to Variant B or C.
20-
21-
**Deliverables:** evidence log, board schematic note, `fpga/HARDWARE_SSOT.md` update, and (if a fix is found) a working flash-boot end-to-end.
22-
23-
**IGLA impact:** +0 generic ∀ in W397 unless a quick fix leaves cycles; keep the 125-wave no-regression streak.
25+
**Effort:** ~2–4 hours bench time.
26+
**Dependencies:** physical board + DSLogic/oscilloscope.
27+
**Impact:** turns the default bitstream choice from empirical to quantitative;
28+
unblocks future frequency-limited flash devices.
2429

2530
---
2631

27-
## Variant B — Bitstream-generation / SPI-startup fix
28-
29-
If Variant A shows the same correct `MODE=0x1` at cold-POR and boot still fails, the problem lies deeper than mode sampling. Candidate causes:
32+
## Variant B — Extend the Lean 4 model to `OSCFSEL` variants and CCLK bounds (no hardware)
3033

31-
- `COR0` CCLK frequency field is `0` (default decode). Some Artix-7 speed grades interpret this as a frequency the N25Q128 cannot satisfy in the specific board environment, or the openXC7 `fasm2frames`/`xc7frames2bit` path omits a required SPI-startup timing detail.
32-
- The openXC7-generated bitstream works in JTAG/SRAM loading but is missing a frame or command needed for autonomous SPI boot. Compare a Vivado-generated `.bin` of the same design byte-by-byte with the OpenXC7 output.
33-
- The `bscan_spi` bridge loaded during openFPGALoader flash access leaves the FPGA in a state that interferes with the next boot sequence.
34+
**Goal:** strengthen the formal FPGA-boot story by making the model speak about
35+
the `OSCFSEL` field and the derived CCLK frequency bounds, without requiring a
36+
physical measurement.
3437

35-
**Actions:**
36-
- Regenerate a minimal GF16 bitstream with explicit `BITSTREAM.CONFIG.CONFIGRATE` and `SPI_BUSWIDTH` constraints and test flash boot.
37-
- Use `bitread`/FASM diff to compare OpenXC7 vs Vivado bitstreams for the same design.
38-
- Try a different, simpler design (e.g., `fpga/openxc7-synth/blink_j26.bit` rebuilt for XC7A200T) to see if the failure is design-specific.
38+
**Steps:**
39+
1. Add constants for the documented `OSCFSEL` values and the corresponding
40+
nominal CCLK ranges to `TernaryFPGABoot.lean`.
41+
2. Define a predicate `cclk_within_flash_spec` that states the configured CCLK
42+
is compatible with the N25Q128 read timing.
43+
3. Prove that `canonical` + `OSCFSEL=0` implies `cclk_within_flash_spec` under
44+
the published Artix-7 startup clock tables.
45+
4. Link the result to `fpga/HARDWARE_SSOT.md` §3.3 (H2 decision tree) as a
46+
formal justification for why the default bitstream is timing-safe.
3947

40-
**Deliverables:** root cause in the generation flow, a patched wrapper or `.fasm` pre-processing step, and a booting bitstream.
48+
**Effort:** ~4–6 hours; no hardware.
49+
**Dependencies:** Lean 4 toolchain + Xilinx UG470 tables.
50+
**Impact:** turns the W400 empirical result into a provable timing claim,
51+
adding another formal barrier for competitors to match.
4152

4253
---
4354

44-
## Variant C — Vivado-in-Docker fallback
55+
## Variant C — Cable-connected end-to-end smoke verification
4556

46-
If both Variant A and Variant B fail to yield a bootable OpenXC7 bitstream, accept that the open-source 7-series toolchain may have a fundamental gap for XC7A200T FGG676 autonomous SPI boot. Switch to the Vivado-in-Docker path.
57+
**Goal:** extend `tri fpga smoke-gate` so that, when a Digilent cable is
58+
detected, it also loads the GF16 matrix into SRAM and asserts `DONE=HIGH`.
4759

48-
**Prerequisites (require user action outside the agent):**
49-
- Restore/install Vivado 2025.2 or later Linux installer.
50-
- Provide a valid `wi_authentication_key` or offline entitlement.
51-
- Build the `t27/vivado:webpack` Docker image or supply a multi-arch image.
60+
**Steps:**
61+
1. Detect cable presence with `openFPGALoader --detect -c digilent_hs2`.
62+
2. If the cable is present, run:
63+
```bash
64+
openFPGALoader -c digilent_hs2 fpga/verilog/ternary_mac_demo_top_200t.bit
65+
```
66+
and then `tri fpga stat` to read `DONE`.
67+
3. Keep the board-less assertions as the mandatory path and make the physical
68+
SRAM load an optional bonus check that is skipped gracefully when no cable is
69+
connected.
70+
4. Add a `--require-cable` flag for CI runners that expect hardware.
5271

53-
**Actions:**
54-
- Build `gf16_matmul4x4_top.bit` through Vivado for `xc7a200tfgg676-1`.
55-
- Program flash with `tri fpga program-flash` and test cold boot.
56-
- If Vivado-generated bitstream boots from flash, bisect the OpenXC7 differences and file actionable upstream issues or patches.
57-
58-
**Deliverables:** boot-from-flash working via Vivado, documented OpenXC7 gap, and a decision on whether to maintain dual-toolchain support.
72+
**Effort:** ~3–5 hours; needs the board for final verification.
73+
**Dependencies:** Digilent FTDI cable + board.
74+
**Impact:** turns `smoke-gate` from a static bitstream audit into a true
75+
hardware smoke test, without breaking board-less CI.
5976

6077
---
6178

6279
## Recommendation
6380

64-
Start with **Variant A**. It is the only hypothesis that survived W396 and requires only a user-assisted power-cycle plus CLI capture. If H1 is disproven, proceed to **Variant B** before escalating to **Variant C**, because Vivado-in-Docker has unresolved entitlement/container blockers.
81+
If hardware is available, start with **Variant A** (it directly closes the
82+
physical AC and produces numeric evidence). If hardware is not available,
83+
**Variant B** is the highest-leverage no-hardware path. **Variant C** is best as
84+
a stretch goal once A is done.
85+
86+
---
6587

66-
*phi^2 + phi^-2 = 3 | TRINITY*
88+
*φ² + 1/φ² = 3 | TRINITY*

0 commit comments

Comments
 (0)