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 — feat: emit_verilog custom init -> GENERATED trainer TRAINS XOR ON SILICON (2026-08-08)
# NOW — test: CI quantifies "size costs TIME (steps), not AREA" (2026-08-08)

Last updated: 2026-08-08

## test: the emit gate now reports microcode step count per topology (Refs #1764)

- Quantified the whitepaper's headline claim IN CI. The emit-bitexact gate now prints, per topology, the microcode STEP count next to the one-shared-multiplier datapath invariant: (2,2,1)=32 steps -> (2,4,2)=88 -> deep [3,4,4,2,1]=216 steps, while the synth area report shows cell counts stay ~constant (13945 -> 17468). So "network size costs TIME (microcode steps), not AREA (one shared multiply/add)" is now measured on every PR, not just asserted in prose
- Bonus: the step count also PREDICTS on-silicon timing-marginality -- more steps per frame = more chances for a glitch on the timing-relaxed shared-core path (why the generated trainer with trainable biases, 32+ steps, needed more seed-search than a leaner design). This ties the CI metric to the silicon reality found in cycles 86-89
- Also added [N steps / N regs] to each per-topology bit-exact OK line. Tool-only; Refs #1764

## feat: emit_verilog `init=` + closed the verified-generator -> hardware loop (Refs #1764)

- `emit_verilog` now takes an optional `init` dict (default None) that overrides the random weight init. With an XOR near-solution init, the CI-verified generator emits a microsequencer that trains XOR (29/30 epochs in the model)
Expand Down
11 changes: 10 additions & 1 deletion tools/verify_emit_bitexact.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ def check(g, arch, workdir):
if mism:
print(f"FAIL {arch}: {len(mism)}/{len(py)}; first step {mism[0][0]} py={mism[0][1]} rtl={mism[0][2]}")
return False
print(f"OK {arch}: RTL == model BIT-EXACT over {len(py)} training steps, all {n_out} output(s) (final yout={py[-1]})")
print(f"OK {arch}: RTL == model BIT-EXACT over {len(py)} training steps, all {n_out} output(s) "
f"[{len(steps)} microcode steps / {len(reg)} regs] (final yout={py[-1]})")
return True


Expand Down Expand Up @@ -198,6 +199,14 @@ def main():
print("--- datapath invariant (one shared smul + one shared sadd) ---")
ok = all(datapath_check(g, a) for a in ARCHS)
print("ALL ONE-MULTIPLIER" if ok else "DATAPATH FAIL")
if ok:
# quantify the core claim: bigger nets grow the microcode (TIME), not the
# one-shared-multiplier datapath (AREA). (Step count also predicts on-silicon
# timing-marginality: more steps per frame -> more chances for a glitch.)
print("--- size costs TIME (microcode steps), not AREA (1 shared multiplier) ---")
for a in ARCHS:
reg2, steps2 = (g.gen_deep(a) if isinstance(a, list) else g.gen(*a))
print(f" {str(a):<16} {len(steps2):>4} steps {len(reg2):>3} regs -- same 1-smul+1-sadd datapath")
if ok and shutil.which("yosys"):
print("--- synthesizability + area (yosys synth_xilinx) ---")
results = [synth_check(g, a, wd) for a in SYNTH_ARCHS]
Expand Down
Loading