Skip to content
Merged
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
8 changes: 7 additions & 1 deletion docs/NOW.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# NOW — fix(gen-zig): unused params + test bindings (2026-08-08)
# NOW — deeper net gated (2,5,3,1) + a without-Vivado open-flow refinement (2026-08-08)

Last updated: 2026-08-08

## test+docs: CI now gates a deeper [2,5,3,1] net learns; met-timing is a partial without-Vivado refinement (Refs #1764)

- V2 (stack): added a deeper [2,5,3,1] (3-layer, 158-step) learning assertion to the generator self-test / CI learning gate -- held-out 59/60 (98%), deterministic. Extends the proven "the method scales beyond XOR" claim to a deeper+wider net
- Answered "can we do it without Vivado?": measured a partial open-flow refinement -- constrain the INTERNAL clk net to a met period (create_clock -period 50 [get_nets clk], ~20 MHz < fmax 21) and build WITHOUT --timing-allow-fail so P&R closes timing deterministically. Result: several seeds come up bit-exact at ep0 (vs glitching from the start), and seed-search still finds a fully-stable build (a met-timing seed trained XOR 4/4 all 60 epochs, saved as ax7203_MET_seed8_STABLE.bit). It does NOT kill the lottery (some seeds diverge over epochs) and more settle stays non-monotonic -- so met-timing + seed-search is the best OPEN recipe; deterministic no-seed-search still needs commercial P&R
- Free Vivado (ML Standard) supports xc7a200t but is x86 Linux/Windows only (not this macOS arm64 host). Board on generated capstone (XOR 4/4). Refs #1764

## fix(gen-zig): discard unused params + declare test/bench bindings (Closes #1910)

- Zig gen emitted unused fn parameters (zig errors on them) and test-block bindings without declarations (the Zig twin of #1894) -- 66/68 of tri-net's legacy spec gens failed zig ast-check
Expand Down
12 changes: 12 additions & 0 deletions docs/SILICON_TRAINING_METHODOLOGY.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,18 @@ buildable on this flow (item: MMCM places), or **commercial P&R** timing closure
prototypes: cores in `scratchpad/retime/`, pipelined trainer in `scratchpad/board/bppipe/`,
write/control-hardened in `scratchpad/board/bpctrl/`.

**Without Vivado — a partial open-flow refinement (measured).** Constraining the *internal*
clock net to a period nextpnr actually *meets* (`create_clock -period 50 [get_nets clk]`,
~20 MHz < the ~21 MHz fmax) and building **without** `--timing-allow-fail` makes P&R close
timing deterministically. This measurably improves the forward pass — several seeds come up
**bit-exact at ep0** (0/0.551/0.936/0.234) rather than glitching from the start — and
seed-search still finds a **fully-stable** build (a met-timing seed trained XOR 4/4 through
all 60 epochs; `scratchpad/board/bpmet/`). It does **not** eliminate the lottery (some seeds
still diverge over epochs) and more `settle` on top stays non-monotonic (item 2 holds even
here). So on the open flow, **met-timing + seed-search** is the best recipe;
deterministic no-seed-search closure still needs commercial P&R. *Free* Vivado (ML Standard,
ex-WebPACK) supports the xc7a200t but is x86 Linux/Windows only — not the macOS arm64 host.

## Reproducibility

The verification runs in CI on every pull request. The silicon build is one script
Expand Down
21 changes: 21 additions & 0 deletions tools/gft_backprop_microcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,27 @@ def _predd(a, b):
te = sum(1 for a, b, t in ted if _predd(a, b) == t)
assert te >= int(0.9 * len(ted)), f"deep [2,4,3,1] held-out too low: {te}/{len(ted)}"
print(f"self-test: deep [2,4,3,1] (3-layer, 2 hidden) learns nonlinear task, held-out {te}/{len(ted)} (>=90%) -- OK")
# deeper+wider: [2,5,3,1] (3-layer) generalises too -- the method scales, only the open
# silicon flow's placement marginality does not (fixed by the Vivado closure kit).
SZ = [2, 5, 3, 1]
reg, steps = gen_deep(SZ); rf = [0] * len(reg)
random.seed(3)
for l in range(1, len(SZ)):
for j in range(SZ[l]):
for k in range(SZ[l - 1]): rf[reg[f"W{l}_{j}_{k}"]] = enc(round(random.uniform(-0.8, 0.8), 3))
rf[reg[f"b{l}_{j}"]] = enc(round(random.uniform(-0.5, 0.5), 3))
random.seed(7); trw, tew = _ds(160), _ds(60)
def _predw(a, b):
sav = rf[:]; rf[reg["x0"]] = enc(a); rf[reg["x1"]] = enc(b); rf[reg["t0"]] = 0
run(steps, rf); y = dec(rf[reg["y0"]])
for i in range(len(rf)): rf[i] = sav[i]
return int(y > 0.5)
for _ in range(60):
for a, b, t in trw:
rf[reg["x0"]] = enc(a); rf[reg["x1"]] = enc(b); rf[reg["t0"]] = enc(float(t)); run(steps, rf)
te = sum(1 for a, b, t in tew if _predw(a, b) == t)
assert te >= int(0.9 * len(tew)), f"deep [2,5,3,1] held-out too low: {te}/{len(tew)}"
print(f"self-test: deep [2,5,3,1] (158 steps) learns nonlinear task, held-out {te}/{len(tew)} (>=90%) -- OK")
vd = emit_verilog_deep([2, 4, 3, 1], "deep431")
assert "module deep431" in vd and "for(gi=0;gi<" in vd
print("emit_verilog_deep: [2,4,3,1] module generated -- OK")
Expand Down
Loading