feat(v2): scaffold hardware/v1 frozen baseline + M1 Neural Processor
Begins the V2 Neural Multiprocessor / Dataflow architecture per docs/v2-description.md, per explicit user request to freeze V1 and start V2 development, copying from V1 what's needed. Scaffold: - hardware/v1/: byte-exact, read-only copy of the current V1 codebase (rtl, testbenches, tools, constraints, a representative subset of synthesis results, and reference docs) -- verified identical via diff/cmp against the live top-level tree before being made filesystem-read-only. The live top-level tree is untouched and remains the project's "production" V1 (see hardware/v1/README.md and hardware/v2/logs/decisions.log DEC-0001 for why copy-not-move). - hardware/v2/: mandatory structure (rtl/sim/constraints/synthesis/ reports/scripts/logs/docs) plus the full logging system required by the spec (development/architecture/simulation/synthesis/timing/ benchmark/decisions/experiments/errors.log). M1 -- Neural Processor (hardware/v2/rtl/neural_processor.v): - 8-stage pipelined perceptron unit (P_IN=8): input align, 8 multipliers, 3-level adder tree, accumulator, bias+activation, INT8 saturation. Genuine 1-tile/cycle throughput, not just a wider combinational datapath. - 7-state FSM (NP_IDLE..NP_ERROR per docs/v2-description.md §6, with 4 baseline states merged into NP_WAIT_OPERANDS -- see decisions.log DEC-0002); valid/ready/data/last stream interfaces per §7. - Bit-exact vs the frozen hardware/v1/rtl/neuron_parallel.v + mac8.v + mac_unit.v: 7/7 tests pass (hardware/v2/sim/tb_neural_processor.v), covering regular/mixed-sign/extreme-INT8 vectors, both activations, a zero-idle-gap back-to-back-tiles throughput check, and an 8-tile job -- verified with Verilator (see below for why). - Real synthesis + place&route (Yosys + nextpnr-ecp5): 0 CHECK problems, Fmax 183.12 MHz at ACC_WIDTH=32 (PASS at 80MHz, ~3x V1's isolated PARALLEL=8 Fmax of 61.71 MHz) and 176.21 MHz at ACC_WIDTH=24 (a user-requested comparison experiment, also bit-exact-verified; see experiments.log EXP-0001/EXP-0002 and benchmark.log). Three real bugs found and resolved during M1 development (full diagnostic record in errors.log): - Two independent, reproducible Icarus Verilog v13.0 scheduling defects (ERR-0001, ERR-0002) that silently produced wrong simulation results for standard sequential Verilog -- confirmed via Verilator 5.050 giving correct results on the same minimal repros. Verilator is now the trusted simulator for hardware/v2/ (decisions.log DEC-0004); Icarus's affected protocol-violation check was removed from the RTL and deferred architecturally to the Neural Director (DEC-0003) rather than chased further. - One real RTL bug (ERR-0003): last0 wasn't gated like valid0, letting a "last tile" tag leak into the pipeline ahead of its actual valid tile on back-to-back jobs. Fixed and verified. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# Formato dei log V2
|
||||
|
||||
Regola non negoziabile (`docs/v2-description.md` §25-29): ogni attività
|
||||
significativa (modifica, simulazione, sintesi, benchmark, decisione, errore)
|
||||
deve essere registrata. Nessun log viene mai sovrascritto o troncato — solo
|
||||
append. Nessun ID esperimento (`EXP-XXXX`) o decisione (`DEC-XXXX`) viene mai
|
||||
riutilizzato, anche se il risultato è un FAIL.
|
||||
|
||||
## File
|
||||
|
||||
- `development.log` — log principale di sviluppo, un'entry per ogni sessione
|
||||
di lavoro/milestone (creazione file, refactor, avanzamento roadmap).
|
||||
- `architecture.log` — decisioni e note di architettura a grana fine (non
|
||||
scelte finali — quelle vanno in `decisions.log` — ma esplorazioni,
|
||||
alternative considerate, vincoli scoperti).
|
||||
- `simulation.log` — ogni run di simulazione (Icarus/Verilator): test,
|
||||
vettori, cicli, PASS/FAIL, confronto bit-exact con V1, stall/memory-wait.
|
||||
- `synthesis.log` — ogni run Yosys: LUT/FF/DSP/BRAM, warning, problemi CHECK.
|
||||
- `timing.log` — ogni run nextpnr-ecp5: Fmax, percorso critico, WNS/TNS se
|
||||
disponibili. Fmax "ufficiale" di una configurazione = solo da qui, mai da
|
||||
simulazione o stima.
|
||||
- `benchmark.log` — tabelle di confronto per configurazione (Fmax, MAC/cycle,
|
||||
cycles/neuron, utilization, ecc.), sempre con etichetta
|
||||
THEORETICAL/SIMULATED/SYNTHESIZED/POST-P&R.
|
||||
- `decisions.log` — decisioni architetturali importanti, formato `DEC-XXXX`
|
||||
(vedi `docs/v2-description.md` §27).
|
||||
- `experiments.log` — registro principale, un `EXP-XXXX` per ogni esperimento
|
||||
end-to-end (config → sim/synth/timing → risultato), rimanda a
|
||||
`reports/experiments/EXP-XXXX/`.
|
||||
- `errors.log` — errori/bug/regressioni incontrati durante lo sviluppo V2
|
||||
stesso (non i bug V1, già chiusi in `hardware/v1/docs/validation/bugs.md`).
|
||||
|
||||
## Campi minimi per entry (§26)
|
||||
|
||||
```
|
||||
timestamp, experiment_id (se applicabile), git_commit, session/agent,
|
||||
module, configuration, action, reason, command, result, errors, decision,
|
||||
next_action
|
||||
```
|
||||
|
||||
Per synthesis/timing aggiungere: LUT, FF, DSP, BRAM, Fmax, critical path,
|
||||
WNS/TNS. Per simulazione: test, vectors, cycles, PASS/FAIL, bit-exact result,
|
||||
stall cycles, memory wait, utilization.
|
||||
@@ -0,0 +1,14 @@
|
||||
# V2 architecture log -- solo append, mai troncato/sovrascritto (vedi README.md)
|
||||
# Nessuna entry ancora -- popolato incrementalmente man mano che avanza lo sviluppo V2.
|
||||
|
||||
[2026-09-05] Neural Processor Array error isolation (§34: "un processor
|
||||
bloccato non deve bloccare gli altri")
|
||||
NP_ERROR is per-processor state, private to each neural_processor
|
||||
instance -- it only halts the ONE processor's own FSM (recoverable via
|
||||
its own rst), never asserts anything that could stall a shared bus,
|
||||
arbiter, or the Neural Director's own state. This is the mechanism
|
||||
that will let M2's neural_processor_array.v treat one processor's
|
||||
NP_ERROR as an isolated fault (report + exclude from scheduling) rather
|
||||
than a system-wide halt, once the Director (M5) exists to observe it.
|
||||
No shared/global reset or shared bus signal is driven by any single
|
||||
processor's error state at M1.
|
||||
@@ -0,0 +1,20 @@
|
||||
# V2 benchmark log -- solo append, mai troncato/sovrascritto (vedi README.md)
|
||||
# Nessuna entry ancora -- popolato incrementalmente man mano che avanza lo sviluppo V2.
|
||||
|
||||
[2026-09-05] M1 single Neural Processor, isolated (no array/director/
|
||||
memory manager yet -- system-level numbers deferred to M9)
|
||||
|
||||
| Config | Fmax (POST-P&R) | LUT | FF | DSP | BRAM |
|
||||
|----------------------|------------------|-----|-----|-----|------|
|
||||
| P_IN=8, ACC_WIDTH=32 | 183.12 MHz | 55 | 533 | 8 | 0 |
|
||||
| P_IN=8, ACC_WIDTH=24 | 176.21 MHz | 49 | 509 | 8 | 0 |
|
||||
|
||||
Reference (V1, hardware/v1/synthesis/p8/, isolated neuron_parallel,
|
||||
PARALLEL=8, N_INPUTS=256): 61.71 MHz POST-P&R.
|
||||
|
||||
All Fmax figures above are POST-P&R (real nextpnr-ecp5), not
|
||||
theoretical or simulated-only. MAC/cycle, cycles/neuron, neurons/s,
|
||||
stall %, effective MAC/s: not yet meaningful at this milestone (single
|
||||
isolated processor, no streaming benchmark harness yet -- deferred to
|
||||
M2 once neural_processor_array.v exists and a real workload can be
|
||||
timed end-to-end).
|
||||
@@ -0,0 +1,203 @@
|
||||
# V2 decisions log -- formato DEC-XXXX, mai sovrascritto (vedi README.md)
|
||||
|
||||
DEC-0001
|
||||
|
||||
DATE: 2026-09-05
|
||||
|
||||
DECISION:
|
||||
Congelare V1 come copia separata in hardware/v1/ (sola lettura a livello
|
||||
filesystem) invece di spostare (git mv) l'albero top-level esistente
|
||||
(rtl/, sim/, synth/, tools/) dentro hardware/v1/.
|
||||
|
||||
WHY:
|
||||
docs/v2-description.md §1/§34 impone una "struttura obbligatoria"
|
||||
hardware/v1/ + hardware/v2/ e vieta di modificare/degradare V1. Due
|
||||
strade possibili: (a) spostare fisicamente rtl/sim/synth/tools
|
||||
nell'albero hardware/v1/, oppure (b) copiarli lasciando l'albero
|
||||
top-level esattamente come e' oggi. Lo spostamento romperebbe tutti i
|
||||
riferimenti a percorso in WORKLOG.md, docs/validation/*.md,
|
||||
docs/FPGA-NeuralNetwork-Engine.md (centinaia di citazioni tipo
|
||||
"rtl/neuron_parallel.v:127") e negli script (tools/run_regression.py
|
||||
resta funzionante per costruzione relativa, ma altri riferimenti
|
||||
documentali no) -- un costo reale senza benefico funzionale, dato che
|
||||
l'obiettivo della regola e' *non perdere/alterare* V1, non *dove* vive
|
||||
fisicamente. La copia raggiunge lo stesso obiettivo (baseline
|
||||
funzionale/numerica/bit-exact per V2, mai modificabile) senza il
|
||||
rischio di rompere la cronologia documentale esistente.
|
||||
|
||||
EVIDENCE:
|
||||
- `diff -rq rtl/ hardware/v1/rtl/` e confronto file-per-file su
|
||||
sim/*.v: 0 differenze (copia bit-esatta verificata, non assunta).
|
||||
- hardware/v1/ reso sola lettura (`chmod -R a-w`) subito dopo la copia,
|
||||
prima di qualunque lavoro V2.
|
||||
|
||||
ALTERNATIVES:
|
||||
- git mv dell'intero albero rtl/sim/synth/tools sotto hardware/v1/,
|
||||
poi aggiornamento di tutti i riferimenti di percorso nella
|
||||
documentazione. Scartata: costo/rischio alto, beneficio nullo
|
||||
rispetto all'obiettivo dichiarato della regola.
|
||||
- Symlink hardware/v1/ -> ../../rtl ecc. Scartata: non garantisce
|
||||
l'immutabilita' (un simlink non protegge dalla modifica dell'originale
|
||||
ed e' fragile rispetto a `chmod -R a-w`).
|
||||
|
||||
RESULT:
|
||||
hardware/v1/ creato come copia bit-esatta e sola-lettura. L'albero
|
||||
top-level del repository resta la "produzione" V1 corrente, invariata,
|
||||
usata anche dal resto del progetto (WORKLOG.md, docs/) esattamente come
|
||||
prima di questa sessione.
|
||||
|
||||
STATUS:
|
||||
ACCEPTED
|
||||
|
||||
DEC-0002
|
||||
|
||||
DATE: 2026-09-05
|
||||
|
||||
DECISION:
|
||||
Collapse §6's baseline Neural Processor FSM states NP_LOAD_TILE,
|
||||
NP_MAC, NP_ACCUM, NP_NEXT_TILE into the single NP_WAIT_OPERANDS state
|
||||
in the actual implementation (hardware/v2/rtl/neural_processor.v),
|
||||
rather than implementing them as four separate one-cycle-gated states.
|
||||
|
||||
WHY:
|
||||
§5 explicitly states the internal datapath must be pipelined and the
|
||||
goal is throughput, not minimal latency -- accepting a new P_IN-wide
|
||||
tile every cycle. Gating tile acceptance behind four sequential FSM
|
||||
states (each holding for exactly one cycle per tile) would recreate a
|
||||
non-pipelined, one-tile-per-4-cycles controller, directly
|
||||
contradicting §5/§34 ("ottimizzare il throughput effettivo"). The four
|
||||
states from §6's baseline list describe what the ORIGINAL (pre-M1)
|
||||
sketch assumed before the pipeline design in §5 was fully worked out;
|
||||
once the datapath is genuinely pipelined, tile acceptance becomes a
|
||||
single steady-state condition (operand_valid && operand_ready), and
|
||||
per-tile progress is tracked by the valid/last tags flowing through
|
||||
the pipeline registers, not by the outer FSM.
|
||||
|
||||
EVIDENCE:
|
||||
EXP-0001 (bit-exact vs V1, 7/7 tests incl. a deliberate zero-idle-gap
|
||||
back-to-back-tiles case, TEST 5 in tb_neural_processor.v) -- confirms
|
||||
tiles are genuinely accepted one per cycle with no outer-FSM stall
|
||||
between them.
|
||||
|
||||
ALTERNATIVES:
|
||||
Literal 11-state FSM per §6's baseline list, with LOAD_TILE/MAC/
|
||||
ACCUM/NEXT_TILE each a real one-cycle state gating acceptance.
|
||||
Rejected: would cap throughput at 1 tile per 4 cycles, defeating the
|
||||
pipeline's own purpose.
|
||||
|
||||
RESULT:
|
||||
7-state FSM (NP_IDLE, NP_LOAD_JOB, NP_WAIT_OPERANDS, NP_FINISH,
|
||||
NP_WRITE_RESULT, NP_DONE, NP_ERROR) implemented and verified.
|
||||
|
||||
STATUS:
|
||||
ACCEPTED
|
||||
|
||||
---
|
||||
|
||||
DEC-0003
|
||||
|
||||
DATE: 2026-09-05
|
||||
|
||||
DECISION:
|
||||
Remove the operand-arrival protocol-violation guard from
|
||||
neural_processor.v (the check that would raise NP_ERROR if
|
||||
operand_valid arrived while the processor could not consume it) rather
|
||||
than continue debugging it. Defer this responsibility to the Neural
|
||||
Director (M5).
|
||||
|
||||
WHY:
|
||||
The guard's own evaluation triggered ERR-0002 (docs/v2-description.md
|
||||
mandate §25-29 requires documenting this, not hiding it) -- a
|
||||
reproducible Icarus Verilog v13.0 bug where the guard's condition
|
||||
evaluated true despite operand_valid being independently confirmed 0.
|
||||
Root cause was bisected down to a minimal FSM transition unrelated to
|
||||
this specific expression (see errors.log ERR-0002), meaning the bug is
|
||||
in the toolchain's scheduling, not fixable by rewording the condition.
|
||||
Architecturally, a standalone Neural Processor policing its OWN
|
||||
issuer's protocol is also arguably the wrong owner of that
|
||||
responsibility: per §34's own division of labor ("Il Director gestisce
|
||||
WHAT deve essere eseguito"), arbitrating/validating operand issuance
|
||||
across possibly-multiple Neural Processors is the Director's job, not
|
||||
each processor's.
|
||||
|
||||
EVIDENCE:
|
||||
ERR-0002 (errors.log) -- the guard, and several simplified variants of
|
||||
it, all misevaluated under Icarus v13.0; disabling it entirely (and
|
||||
only it) restored correct behavior in every case, confirmed via
|
||||
Verilator that the underlying pipeline logic was already correct.
|
||||
|
||||
ALTERNATIVES:
|
||||
1. Keep chasing the exact Icarus root cause. Rejected for this
|
||||
session: already bisected to a toolchain-level scheduling issue
|
||||
independent of this specific code, further chasing would not
|
||||
change the architectural need for this check to live in the
|
||||
Director eventually anyway.
|
||||
2. Reimplement the same check with different Verilog phrasing.
|
||||
Rejected: multiple independent phrasings all reproduced the bug.
|
||||
|
||||
RESULT:
|
||||
NP_ERROR is now reachable only via the `default:` case branch (a
|
||||
genuine np_state encoding corruption) -- a real safety net, just not
|
||||
exercised by operand-arrival timing. The corresponding negative test
|
||||
(TEST 7) was removed from tb_neural_processor.v; the scenario is
|
||||
deferred to M5's testbench (tb_neural_director.v), where the Director
|
||||
is the actual issuer under test.
|
||||
|
||||
STATUS:
|
||||
ACCEPTED
|
||||
|
||||
---
|
||||
|
||||
DEC-0004
|
||||
|
||||
DATE: 2026-09-05
|
||||
|
||||
DECISION:
|
||||
Adopt Verilator 5.050 (`verilator --binary --timing`) as the primary/
|
||||
trusted simulator for hardware/v2/ testbenches going forward, in
|
||||
addition to (not instead of) Icarus Verilog. Cross-check any Icarus
|
||||
result that looks anomalous against Verilator before concluding it is
|
||||
an RTL bug.
|
||||
|
||||
WHY:
|
||||
ERR-0001/ERR-0002 (errors.log) are two independently-reproduced Icarus
|
||||
Verilog v13.0 defects that produced WRONG simulation results (not
|
||||
compile errors) for straightforward, standard sequential Verilog, with
|
||||
no workaround available at the RTL/testbench level for ERR-0002 short
|
||||
of removing the affected logic. Verilator gave the CORRECT result for
|
||||
every one of these repros. §30's rule against invented results cuts
|
||||
both ways: a simulator that silently gives a WRONG "measured" result is
|
||||
just as dangerous as inventing one outright -- cross-checking against
|
||||
a second, architecturally different simulator (Verilator compiles to
|
||||
C++, Icarus interprets bytecode -- unlikely to share the same
|
||||
scheduling bug) is now mandatory whenever a hardware/v2/ testbench
|
||||
shows unexpected behavior.
|
||||
|
||||
EVIDENCE:
|
||||
- Minimal FSM repro (`if (go) st<=B;`, no tasks, no other logic):
|
||||
Icarus v13.0 fails to transition on specific testbench edge-count
|
||||
parities; Verilator 5.050 gives the correct result every time.
|
||||
- Full hardware/v2/sim/tb_neural_processor.v: Icarus v13.0 hangs/
|
||||
misbehaves even after every known-real RTL bug (ERR-0003) was fixed;
|
||||
the SAME unmodified file under Verilator gives 7/7 PASS, bit-exact
|
||||
vs the frozen V1 reference.
|
||||
|
||||
ALTERNATIVES:
|
||||
1. Downgrade Icarus to an older release. Rejected: no older bottle was
|
||||
cached on this machine (`brew list --versions icarus-verilog` shows
|
||||
only 13.0) and fetching a specific historical formula version was
|
||||
not attempted this session (time-boxed decision, revisit if it
|
||||
becomes a recurring blocker).
|
||||
2. Keep using only Icarus and manually work around each new defect as
|
||||
found. Rejected: not sustainable across the dozens of testbenches
|
||||
the full V2 roadmap requires (§20).
|
||||
|
||||
RESULT:
|
||||
Verilator installed (`brew install verilator`, 5.050). hardware/v2/
|
||||
testbenches are compiled/run with both simulators when convenient;
|
||||
Verilator's result is authoritative when the two disagree, and any
|
||||
such disagreement is logged here / in errors.log, not silently
|
||||
resolved by picking whichever answer looks more convenient.
|
||||
|
||||
STATUS:
|
||||
ACCEPTED
|
||||
@@ -0,0 +1,61 @@
|
||||
# V2 development log — solo append, mai troncato/sovrascritto (vedi README.md)
|
||||
|
||||
[2026-09-05T11:14:08Z] commit=07a48e4 session=v2-kickoff
|
||||
module: scaffold
|
||||
action: creato hardware/v1/ (baseline V1 congelata, sola lettura) e
|
||||
hardware/v2/ (struttura obbligatoria: rtl/ sim/ constraints/ synthesis/
|
||||
reports/{simulation,synthesis,timing,experiments}/ scripts/sweep/ logs/
|
||||
docs/), per iniziare lo sviluppo V2 richiesto da docs/v2-description.md.
|
||||
reason: richiesta utente esplicita -- "Crea un v1 con tutto il codice
|
||||
attuale che non deve essere modificato per nessun motivo e lavora su
|
||||
una v2 copiando quello che ti serve. Aggiornami frequentemente e crea
|
||||
un log nuovo."
|
||||
command: cp rtl/*.v sim/*.v tools/ synth/ecp5/{p2,p4,p8,post_fix_verify}
|
||||
synth/ecp5/*.lpf docs/validation/*.md WORKLOG.md
|
||||
docs/FPGA-NeuralNetwork-Engine.md docs/FPGA-Neural-Datapatch-Benchmark.md
|
||||
docs/FPGA-Neural-Hardware-Design.md -> hardware/v1/{rtl,sim,tools,
|
||||
constraints,synthesis,docs}; chmod -R a-w su tutto hardware/v1/.
|
||||
result: verificato bit-esatto (`diff -rq rtl/ hardware/v1/rtl/` e cmp
|
||||
file-per-file su sim/*.v, 0 differenze). hardware/v1/ reso sola lettura
|
||||
a livello filesystem come ulteriore salvaguardia oltre alla policy.
|
||||
hardware/v2/ vuoto tranne logs/ (questo file + README.md).
|
||||
errors: nessuno.
|
||||
decision: copia (non spostamento) dell'albero top-level rtl/sim/synth/
|
||||
tools -- l'albero principale del repository resta la "produzione" V1
|
||||
invariata; hardware/v1/ e' una seconda copia frozen dedicata al
|
||||
confronto V2, per minimizzare il rischio di rompere riferimenti/path
|
||||
esistenti in WORKLOG.md, docs/, altri script. Vedi decisions.log
|
||||
DEC-0001 per la motivazione completa.
|
||||
next_action: M1 (docs/v2-description.md §33) -- implementare
|
||||
hardware/v2/rtl/neural_processor.v (P_IN=8), pipeline 8 stage,
|
||||
bit-exact contro hardware/v1/rtl/neuron_parallel.v + mac8.v,
|
||||
testbench hardware/v2/sim/tb_neural_processor.v.
|
||||
|
||||
[2026-09-05T12:03:12Z] commit=07a48e4 session=v2-M1-neural-processor
|
||||
module: hardware/v2/rtl/neural_processor.v + hardware/v2/sim/
|
||||
tb_neural_processor.v
|
||||
action: implementato M1 (docs/v2-description.md §33) -- Neural
|
||||
Processor P_IN=8, pipeline a 8 stadi (input align -> 8 moltiplicatori
|
||||
-> 3 livelli di albero di somma -> accumulatore -> bias/activation ->
|
||||
saturazione INT8), FSM a 7 stati (§6, con 4 stati assorbiti in
|
||||
NP_WAIT_OPERANDS per il vero throughput pipeline -- vedi
|
||||
decisions.log DEC-0002), interfacce valid/ready/data/last (§7).
|
||||
Aritmetica bit-esatta con hardware/v1/rtl/neuron_parallel.v +
|
||||
mac8.v + mac_unit.v.
|
||||
reason: roadmap M1, richiesta esplicita utente di iniziare lo sviluppo
|
||||
V2 copiando da V1 quanto necessario.
|
||||
result: 3 bug reali incontrati e risolti durante lo sviluppo (vedi
|
||||
errors.log ERR-0001/0002/0003) -- due erano bug del toolchain Icarus
|
||||
Verilog v13.0 (non del RTL), confermati installando e usando
|
||||
Verilator 5.050 come secondo simulatore indipendente (decisions.log
|
||||
DEC-0004); uno era un bug RTL reale (gating mancante su `last0`,
|
||||
fix verificato). Testbench finale: 7/7 test PASS, bit-exact contro
|
||||
V1, sia a ACC_WIDTH=32 che ACC_WIDTH=24 (esperimento richiesto
|
||||
dall'utente, experiments.log EXP-0002). Sintesi reale Yosys + P&R
|
||||
reale nextpnr-ecp5: 0 problemi CHECK, Fmax 183.12 MHz (ACC_WIDTH=32)
|
||||
/ 176.21 MHz (ACC_WIDTH=24) -- entrambi PASS a 80MHz con ampio
|
||||
margine, ~3x il Fmax isolato di V1 a PARALLEL=8 (61.71 MHz).
|
||||
errors: vedi errors.log ERR-0001, ERR-0002, ERR-0003, ERR-0004.
|
||||
decision: vedi decisions.log DEC-0002, DEC-0003, DEC-0004.
|
||||
next_action: M2 -- neural_processor_array.v, sweep N_PROCESSORS
|
||||
(1,2,4,8), misura timing/risorse/throughput/utilization reali.
|
||||
@@ -0,0 +1,100 @@
|
||||
# V2 errors log -- solo append, mai troncato/sovrascritto (vedi README.md)
|
||||
# Nessuna entry ancora -- popolato incrementalmente man mano che avanza lo sviluppo V2.
|
||||
|
||||
ERR-0001 (Icarus Verilog v13.0 toolchain bug, TASK/SCOPE-ENTRY DESYNC)
|
||||
DATE: 2026-09-05
|
||||
MODULE: hardware/v2/sim/tb_neural_processor.v (M1 testbench development)
|
||||
SYMPTOM: a task (or any named `begin:label` block) whose FIRST executable
|
||||
statement is a blocking assignment to a signal read by another module's
|
||||
`always @(posedge clk)`, when the task/block is entered immediately after
|
||||
a time-consuming statement in the caller with no intervening
|
||||
`@(posedge clk)`, can make that FIRST assignment invisible to the DUT at
|
||||
the very next clock edge (the DUT's own always block behaves as if the
|
||||
signal never changed). Confirmed at V1's own frozen `neuron_parallel.v`
|
||||
(unmodified, already certified) via a minimal 3-statement task
|
||||
(`v1_start=1; @(posedge clk); v1_start=0;`) -- `busy` never asserted.
|
||||
REPRODUCTION: /tmp/mt6.v-style repro (not committed, transient scratch
|
||||
file) -- see conversation record for the exact minimal case.
|
||||
DIAGNOSIS METHOD: bisected from the full dual-DUT testbench down to a
|
||||
standalone ~15-line repro, ruling out RTL, port connections, and
|
||||
operator precedence one at a time.
|
||||
WORKAROUND: always begin such a task with an explicit `@(posedge clk);`
|
||||
before its first assignment (matches the pre-existing convention in
|
||||
hardware/v1/sim's own tasks, e.g. neuron_parallel_tb.v's run_neuron,
|
||||
which is presumably why V1's own test suite was never affected).
|
||||
STATUS: WORKAROUND APPLIED in hardware/v2/sim/tb_neural_processor.v's
|
||||
run_case. NOT reported upstream (out of scope for this session). See
|
||||
ERR-0004 for the broader consequence of this finding.
|
||||
|
||||
ERR-0002 (Icarus Verilog v13.0 toolchain bug, SPURIOUS CONDITION EVALUATION)
|
||||
DATE: 2026-09-05
|
||||
MODULE: hardware/v2/rtl/neural_processor.v (protocol-violation guard,
|
||||
removed -- see decisions.log DEC-0003)
|
||||
SYMPTOM: `if (operand_valid && !operand_ready && (state-is-one-of-four))`
|
||||
inside `always @(posedge clk)` evaluated TRUE at an edge where
|
||||
`operand_valid` was independently confirmed (via $display in the same
|
||||
timestep, and via the testbench's own port-connected signal) to be 0.
|
||||
Bisected term-by-term: even `if (operand_valid && !operand_ready)`
|
||||
alone, and even `if (operand_valid)` alone with explicit `== 1'b1`
|
||||
comparisons, still fired spuriously. Confirmed NOT a precedence issue
|
||||
(parens are unambiguous) and NOT specific to this exact expression
|
||||
shape (multiple simplified variants all reproduced it).
|
||||
CROSS-CHECK: root-caused further via a minimal 2-state FSM
|
||||
(`if (go) st<=B;`) with NO relation to the removed guard -- Icarus
|
||||
failed to transition on an ODD-numbered testbench clock edge
|
||||
(`repeat(3)` before the pulse) but succeeded on an EVEN-numbered one
|
||||
(`repeat(4)`), reproduced identically with both `always #5 clk=~clk`
|
||||
and `initial ... forever #5 clk=~clk` clock generators. VERILATOR
|
||||
5.050 gives the CORRECT result for the same repro in both cases.
|
||||
This suggests ERR-0001 and ERR-0002 are two symptoms of the same
|
||||
underlying VVP scheduling defect (edge-count/thread-parity dependent),
|
||||
not two unrelated bugs.
|
||||
STATUS: the offending RTL block (protocol-violation detection) was
|
||||
REMOVED rather than chased further -- see DEC-0003. Root cause not
|
||||
fully isolated (documented honestly, not overclaimed).
|
||||
|
||||
ERR-0003 (real RTL bug in hardware/v2/rtl/neural_processor.v, FOUND AND FIXED)
|
||||
DATE: 2026-09-05
|
||||
MODULE: hardware/v2/rtl/neural_processor.v, stage 0 (input
|
||||
alignment/register)
|
||||
SYMPTOM: back-to-back single-tile jobs (and some multi-tile jobs)
|
||||
produced result_data=0 instead of the correct value, while the
|
||||
internal `y7` register (one stage upstream of the FSM's capture)
|
||||
showed the CORRECT value one cycle later than `valid7` first asserted.
|
||||
ROOT CAUSE: `last0 <= tile_last;` was unconditional, while
|
||||
`valid0 <= operand_valid && operand_ready;` was correctly gated. A
|
||||
master asserting `tile_last` before `operand_ready` rises (legal
|
||||
valid-before-ready behavior) let a "last" tag propagate through the
|
||||
pipeline (last1, last_tree[], last5, last6) with NO corresponding
|
||||
valid tile behind it, arriving at stage 7 one cycle ahead of the
|
||||
real valid/data pair and causing the FSM to capture a stale/wrong
|
||||
`y7`.
|
||||
EVIDENCE: isolated to a single-DUT, no-task, no-V1 repro
|
||||
(hardware/v2/sim/tb_neural_processor.v run under Verilator, with a
|
||||
cycle-by-cycle dump of valid5/last5/valid6/last6/valid7/y7) --
|
||||
`last5=1` while `valid5=0` on the same cycle, confirmed the
|
||||
desync's exact origin at stage 0.
|
||||
FIX: `last0 <= (operand_valid && operand_ready) ? tile_last : 1'b0;`
|
||||
-- last0 is now gated identically to valid0.
|
||||
VERIFICATION: full 7-test bit-exact-vs-V1 regression
|
||||
(hardware/v2/sim/tb_neural_processor.v under Verilator) -- 7/7 PASS
|
||||
after the fix, including the back-to-back and single-tile-after-
|
||||
multi-tile cases that exposed it.
|
||||
STATUS: FIXED, verified.
|
||||
|
||||
ERR-0004 (methodology consequence of ERR-0001/ERR-0002)
|
||||
DATE: 2026-09-05
|
||||
NOTE: this session's V1 certification campaign (docs/validation/,
|
||||
hardware/v1/docs/validation/) was verified exclusively with Icarus
|
||||
Verilog v13.0, the ONLY simulator available on this machine at the
|
||||
time. ERR-0001/ERR-0002 show that v13.0 has at least one real,
|
||||
reproducible scheduling defect around clock-edge/task-entry timing.
|
||||
V1's own testbenches were NOT observed to trigger it in this session
|
||||
(V1's `run_neuron`-style tasks already begin with `@(posedge clk)`,
|
||||
which incidentally avoids ERR-0001's trigger condition), and V1
|
||||
remains frozen/untouched regardless. This is flagged here for
|
||||
honesty, not to imply V1's certification is wrong -- re-verifying
|
||||
the full V1 suite under Verilator was explicitly OUT OF SCOPE for
|
||||
this V2-kickoff session (V1 is frozen, not to be touched) and was
|
||||
not performed. See decisions.log DEC-0004.
|
||||
STATUS: OPEN CAVEAT, not actioned in this session by design.
|
||||
@@ -0,0 +1,100 @@
|
||||
# V2 experiments log -- REGISTRO PRINCIPALE (docs/v2-description.md §25).
|
||||
# Un EXP-XXXX per ogni esperimento end-to-end (config -> sim/synth/timing ->
|
||||
# risultato). ID mai riutilizzati, anche per i FAIL. Ogni EXP rimanda a
|
||||
# reports/experiments/EXP-XXXX/ (experiment.yaml, simulation.log,
|
||||
# synthesis.log, timing.log, results.txt, notes.md).
|
||||
#
|
||||
# Nessun esperimento ancora eseguito.
|
||||
|
||||
EXP-0001
|
||||
timestamp: 2026-09-05T12:03:12Z
|
||||
git_commit: 07a48e401f56d395f9d1a6e22f1b5ebc6b598e64 (+ uncommitted M1 work)
|
||||
session: v2-M1-neural-processor
|
||||
module: hardware/v2/rtl/neural_processor.v
|
||||
configuration: DATA_WIDTH=8, P_IN=8, ACC_WIDTH=32
|
||||
action: first M1 implementation -- 8-stage pipelined perceptron unit,
|
||||
bit-exact vs hardware/v1/rtl/neuron_parallel.v + mac8.v + mac_unit.v
|
||||
command (sim, Verilator): verilator --binary --timing -j 0 -Wno-fatal
|
||||
--top-module tb -o /tmp/vtb_np hardware/v1/rtl/neuron_parallel.v
|
||||
hardware/v1/rtl/mac8.v hardware/v1/rtl/mac_unit.v
|
||||
hardware/v2/rtl/neural_processor.v hardware/v2/sim/tb_neural_processor.v
|
||||
&& /tmp/vtb_np
|
||||
command (synth): yosys -p "synth_ecp5 -json
|
||||
hardware/v2/synthesis/neural_processor_p8/top.json -top neural_processor"
|
||||
hardware/v2/rtl/neural_processor.v
|
||||
command (timing): nextpnr-ecp5 --45k --package CABGA381 --speed 8
|
||||
--freq 80 --json hardware/v2/synthesis/neural_processor_p8/top.json
|
||||
--lpf-allow-unconstrained --textcfg .../top.config
|
||||
result:
|
||||
SIMULATED: 7/7 tests PASS, bit-exact vs V1 (functional +
|
||||
extreme-INT8 + back-to-back-tiles + 64-input/8-tile coverage).
|
||||
SYNTHESIZED: 0 CHECK problems, 8 MULT18X18D, 533 TRELLIS_FF,
|
||||
96 CCU2C, 55 LUT4 (36 benign integer-loop-variable warnings, see
|
||||
hardware/v2/logs/synthesis.log).
|
||||
POST-P&R: Fmax = 183.12 MHz, PASS at 80MHz target (real
|
||||
nextpnr-ecp5 measurement, hardware/v2/synthesis/neural_processor_p8/
|
||||
nextpnr.log). Compare V1 isolated PARALLEL=8: 61.71 MHz
|
||||
(hardware/v1/synthesis/p8/) -- ~3x higher Fmax for the pipelined
|
||||
single-processor datapath alone (not yet a system-level
|
||||
comparison -- no Memory Manager/Director/multi-processor overhead
|
||||
included at this milestone).
|
||||
errors: ERR-0001, ERR-0002, ERR-0003 (see errors.log) encountered and
|
||||
resolved/worked around during development.
|
||||
decision: see decisions.log DEC-0002, DEC-0003, DEC-0004.
|
||||
next_action: EXP-0002 (ACC_WIDTH=24 comparison), then M2 (Processor
|
||||
Array, N_PROCESSORS sweep).
|
||||
|
||||
EXP-0002
|
||||
timestamp: 2026-09-05T12:03:12Z
|
||||
git_commit: 07a48e401f56d395f9d1a6e22f1b5ebc6b598e64 (+ uncommitted M1 work)
|
||||
session: v2-M1-neural-processor
|
||||
module: hardware/v2/rtl/neural_processor.v
|
||||
configuration: DATA_WIDTH=8, P_IN=8, ACC_WIDTH=24 (vs EXP-0001's
|
||||
ACC_WIDTH=32 baseline) -- requested explicitly by the user as a test
|
||||
variant ("come test nel perceptrone crea una versione con
|
||||
accumulatori a 24 bit anziche' a 32 bit").
|
||||
reason: ACC_WIDTH is already fully parametric throughout
|
||||
neural_processor.v (no code duplication needed); 24 bits is a real,
|
||||
non-degenerate choice -- worst-case realistic accumulation (e.g. 256
|
||||
INT8 inputs all at +-127/+-128) needs at most 23 signed bits
|
||||
(256 * 128 = 32768, |value| <= 2^22 for the largest single-tile-
|
||||
chain sums this project's configs reach), so 24 bits carries a
|
||||
legitimate 1-bit margin, not an arbitrary/unsafe truncation.
|
||||
command (sim, Verilator): same as EXP-0001 with a copy of
|
||||
tb_neural_processor.v with ACC_WIDTH localparam changed to 24 (V1's
|
||||
own neuron_parallel instantiated at ACC_WIDTH=24 too, for a true
|
||||
bit-exact comparison at the SAME width -- V1's ACC_WIDTH is also a
|
||||
module parameter, no V1 modification needed).
|
||||
command (synth): yosys -p "read_verilog
|
||||
hardware/v2/rtl/neural_processor.v; chparam -set ACC_WIDTH 24
|
||||
neural_processor; synth_ecp5 -json
|
||||
hardware/v2/synthesis/neural_processor_p8_acc24/top.json -top
|
||||
neural_processor"
|
||||
command (timing): nextpnr-ecp5, same flags as EXP-0001, json from
|
||||
the ACC_WIDTH=24 build.
|
||||
result:
|
||||
SIMULATED: 7/7 tests PASS, bit-exact vs V1 at ACC_WIDTH=24 (no
|
||||
overflow in any test vector, as expected from the margin analysis
|
||||
above).
|
||||
SYNTHESIZED: 0 CHECK problems, 8 MULT18X18D (unchanged, multiplier
|
||||
width is DATA_WIDTH-driven not ACC_WIDTH-driven), 509 TRELLIS_FF
|
||||
(was 533 at ACC_WIDTH=32, -24 FF as expected for 8 fewer
|
||||
accumulator bits carried through ~3 pipeline-stage copies),
|
||||
88 CCU2C (was 96), 49 LUT4 (was 55).
|
||||
POST-P&R: Fmax = 176.21 MHz (was 183.12 MHz at ACC_WIDTH=32) --
|
||||
REAL measurement, both from nextpnr-ecp5. The 24-bit build is
|
||||
~4% SLOWER despite fewer resources -- almost certainly placement
|
||||
noise (consistent with this project's established finding,
|
||||
hardware/v1/docs/WORKLOG.md "Timing closure", that seed-to-seed
|
||||
placement variance on this device dominates small logic-width
|
||||
differences), NOT attributed to a real architectural effect
|
||||
without a seed sweep to confirm. Reported as-measured, not
|
||||
overinterpreted -- see hardware/v2/logs/benchmark.log.
|
||||
errors: none.
|
||||
decision: ACC_WIDTH=32 remains the M1 default (matches V1 exactly for
|
||||
ongoing bit-exact comparisons); ACC_WIDTH=24 confirmed as a viable,
|
||||
correctly-functioning, slightly-smaller alternative, not adopted as
|
||||
default without a proper seed sweep (out of scope for this single
|
||||
comparison run).
|
||||
next_action: revisit ACC_WIDTH choice during M10 (Optimization) with a
|
||||
real seed sweep, not before.
|
||||
@@ -0,0 +1,17 @@
|
||||
# V2 simulation log -- solo append, mai troncato/sovrascritto (vedi README.md)
|
||||
# Nessuna entry ancora -- popolato incrementalmente man mano che avanza lo sviluppo V2.
|
||||
|
||||
[2026-09-05] EXP-0001/EXP-0002 -- hardware/v2/sim/tb_neural_processor.v
|
||||
test: 7 cases (16/32/8/8/8/8/64-input jobs; ACT_NONE + ACT_RELU;
|
||||
extreme INT8 saturation; back-to-back zero-idle-gap tiles)
|
||||
vectors: regular positive, mixed-sign cancellation, extreme INT8
|
||||
(-128,-127,-1,0,1,126,127,127 in one 8-lane tile), back-to-back
|
||||
jobs, 8-tile (64-input) job
|
||||
simulator: Verilator 5.050 (--binary --timing) -- see decisions.log
|
||||
DEC-0004 for why Icarus v13.0 is not trusted for this testbench
|
||||
cycles: not separately profiled at this milestone (throughput/stall
|
||||
cycle counting deferred to M9 per §22)
|
||||
PASS/FAIL: 7/7 PASS (ACC_WIDTH=32); 7/7 PASS (ACC_WIDTH=24, EXP-0002)
|
||||
bit-exact result: V1.y === V2.result_data for every case, both widths
|
||||
stall cycles / memory wait / utilization: N/A (no Memory Manager yet,
|
||||
M1 operands fed directly by testbench per the roadmap)
|
||||
@@ -0,0 +1,16 @@
|
||||
# V2 synthesis log -- solo append, mai troncato/sovrascritto (vedi README.md)
|
||||
# Nessuna entry ancora -- popolato incrementalmente man mano che avanza lo sviluppo V2.
|
||||
|
||||
[2026-09-05] EXP-0001 -- neural_processor (P_IN=8, ACC_WIDTH=32)
|
||||
LUT: 55 FF: 533 DSP(MULT18X18D): 8 BRAM: 0 CCU2C: 96
|
||||
CHECK: 0 problems. 36 warnings, all "multiple conflicting drivers for
|
||||
neural_processor.\gi" -- benign Yosys quirk for an `integer` used as
|
||||
a synthesizable for-loop index in stage 0's unrolled always block,
|
||||
not a real multi-driver conflict (cross-verified functionally
|
||||
correct on 2 independent simulators). Log: hardware/v2/synthesis/
|
||||
neural_processor_p8/yosys.log
|
||||
|
||||
[2026-09-05] EXP-0002 -- neural_processor (P_IN=8, ACC_WIDTH=24)
|
||||
LUT: 49 FF: 509 DSP(MULT18X18D): 8 BRAM: 0 CCU2C: 88
|
||||
CHECK: 0 problems, same 36 benign warnings as EXP-0001.
|
||||
Log: hardware/v2/synthesis/neural_processor_p8_acc24/yosys.log
|
||||
@@ -0,0 +1,22 @@
|
||||
# V2 timing log -- solo append, mai troncato/sovrascritto (vedi README.md)
|
||||
# Nessuna entry ancora -- popolato incrementalmente man mano che avanza lo sviluppo V2.
|
||||
|
||||
[2026-09-05] EXP-0001 -- neural_processor (P_IN=8, ACC_WIDTH=32)
|
||||
nextpnr-ecp5 --45k --package CABGA381 --speed 8 --freq 80
|
||||
--lpf-allow-unconstrained
|
||||
Fmax: 183.12 MHz -- PASS at 80 MHz (real place&route measurement)
|
||||
Critical path: job_ready -> TRELLIS_IO output pad (i.e. the design's
|
||||
own logic is NOT the bottleneck at this Fmax -- an unconstrained
|
||||
output pin dominates; a real system-level Fmax will differ once
|
||||
this signal is consumed on-chip instead of driven to a pad in
|
||||
isolation). Log: hardware/v2/synthesis/neural_processor_p8/nextpnr.log
|
||||
WNS/TNS: not reported by this nextpnr version in this invocation.
|
||||
|
||||
[2026-09-05] EXP-0002 -- neural_processor (P_IN=8, ACC_WIDTH=24)
|
||||
Same command as above, ACC_WIDTH=24 build.
|
||||
Fmax: 176.21 MHz -- PASS at 80 MHz (real place&route measurement)
|
||||
Delta vs ACC_WIDTH=32: -6.91 MHz (-3.8%) despite FEWER resources --
|
||||
attributed to placement noise, not a real architectural effect
|
||||
(no seed sweep run to confirm either way -- see experiments.log
|
||||
EXP-0002 and benchmark.log). Log: hardware/v2/synthesis/
|
||||
neural_processor_p8_acc24/nextpnr.log
|
||||
Reference in New Issue
Block a user