Commit Graph
26 Commits
Author SHA1 Message Date
micheleandClaude Sonnet 5 44be4a7d81 docs: reflect flash #1 removal and the N=4 8/8 timing recovery
Datasheet and pinouts.md updated to the current, real state after
today's session: flash #1 was implemented then removed (user's own
MHz-over-persistence priority call), the clock-closure table now
shows the post-revert, post-DEC-0042 numbers (N_SLOTS=4 @ 64MHz 8/8,
worst 64.55MHz/best 72.37MHz; N_SLOTS=8 deferred by explicit user
request), and the FPGA_DATA_READY any_pending formula is updated to
the real counter-based implementation (credited to the user's own
diagnosis) that fixed the last failing N=4 seed.

Compiled clean (45 pages, 0 errors).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 19:20:57 +02:00
micheleandClaude Sonnet 5 abaaf21f56 docs: datasheet addendum for two-flash programming architecture + FPGA_DATA_READY
Adds a real, dated section to ch.10 (Hardware and board) covering the
two-independent-flash architecture (neural-network data vs. boot
bitstream), the ESP32<->ECP5 JTAG-only link, and the real CABGA381
ball assignments (JTAG/PROGRAMN/INITN/DONE/CFG[2:0]/MSPI dedicated
pins), matching decisions.log DEC-0041.

Also closes ch.7's (Host interface) own long-standing "still needed"
list: the physical transport (spi_host_bridge.v) and the completion-
notification path (FPGA_DATA_READY) it used to flag as missing are
both now real -- described with the same system-idle-detector formula
implemented in the RTL.

Compiled clean (44 pages, 0 errors).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 13:11:12 +02:00
micheleandClaude Sonnet 5 7d6311bce3 feat: two-flash programming architecture, FPGA_DATA_READY, real JTAG/config pinout
Establishes the real ESP32<->ECP5 programming architecture: flash #1
(neural-network data, existing V1 subsystem, ball reserved not yet
wired into V2) stays separate from flash #2 (boot bitstream, MSPI
auto-boot, CFG[2:0]=[0,1,0]); ESP32 talks JTAG only (bit-banged, no
hardware JTAG-master peripheral on S3/C6), updating flash #2 through
the ECP5's own internal sysCONFIG-to-SPI bridge, never driving the
flash pins directly -- zero bus contention, confirmed against the real
Lattice hardware checklist and sysCONFIG user guide.

Adds real, verified ball assignments (official Lattice CABGA381 CSV +
Project Trellis iodb.json) for JTAG, PROGRAMN/INITN/DONE, CFG[2:0],
and the MSPI dedicated pins -- all written to docs/pinouts.md.

Implements FPGA_DATA_READY as real RTL: a system-idle detector
(dependency_manager's any_pending OR neural_director's !queue_empty OR
any active slot), sticky on the busy->idle edge, self-clearing on new
work -- not a per-neuron completion pulse, which was confirmed too
fine-grained. Bit-exact regression re-verified at N_SLOTS=4 and 8
(zero cycle-count change), new explicit data_ready assertion check
added to the D-Stress testbench (PASS both configs), and a fresh
Yosys+nextpnr-ecp5 placement check (0 errors, data_ready placed at G3).

Also fixes a real, independently-found bug while editing an adjacent
file: nms_neural_multiprocessor_sdram_unified.v's own sdram_a port was
still [11:0] (12 bits), stale from before the 64MB/13-bit memory
upgrade. Not exercised by the real board-level top (which wires SDRAM
directly, bypassing this wrapper) but WAS silently truncating A12 in
every D-Stress simulation this session, including today's earlier
ERR-0029 verification runs. Assessed impact: all D-Stress test
addresses used this session decode to rows under 4096 (bit 12 never
actually needed), so no false-positive PASS is believed to have
resulted -- but the full 64MB space was never actually exercised
through this wrapper. Fixed; re-verified bit-exact with identical
cycle counts.

See decisions.log DEC-0041 for full detail.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 12:46:00 +02:00
micheleandClaude Sonnet 5 81a9619214 chore: remove root-level V1 duplicates, superseded by hardware/v1/ freeze
hardware/v1/ was created (dc0b331) as a frozen snapshot of the V1
project that then lived at the repo root (rtl/, sim/, synth/, tools/,
docs/). Root received zero further commits to those files after the
freeze -- confirmed byte-identical to the hardware/v1/ copy for every
file removed here. Root was the "before", hardware/v1/ is the
curated, canonical "after".

Removed (all verified exact-hash duplicates of hardware/v1/ content):
  - rtl/ (20 files, 100% covered by hardware/v1/rtl/)
  - tools/{netasm,pinout,run_regression.py,flash_catalog,validation,
    fpga_benchmark.py} (19 files, 100% covered by hardware/v1/tools/;
    tools/neural_sim/ kept -- unique, post-freeze, no counterpart)
  - sim/*.v (47 testbenches, 100% covered by hardware/v1/sim/; the
    ~38 remaining sim/ entries are compiled binaries and .vcd
    waveform dumps, left as a separate cleanup decision)
  - synth/ecp5/{p2,p4,p8,post_fix_verify} (25 files, exact duplicates
    of hardware/v1/synthesis/; the other ~84 synth/ecp5/* experiment
    build directories are historical artifacts never carried into the
    freeze, left as a separate decision)
  - WORKLOG.md (duplicate of hardware/v1/docs/WORKLOG.md)
  - docs/{FPGA-Neural-Datapatch-Benchmark,FPGA-Neural-Hardware-Design,
    FPGA-NeuralNetwork-Engine}.md, docs/validation/*.md (18 files),
    docs/FPGA-Neural-Datasheet-{EN,IT}.pdf -- all exact duplicates of
    hardware/v1/docs/ content
  - hardware/v1/docs/DatasheetLatex/ (24 files) -- exact duplicate of
    hardware/v2/docs/datasheet/files/docs/datasheet/en/ (discovered
    during this audit; not the same DatasheetLatex already removed
    from hardware/v2/docs/ in an earlier commit)

Moved (genuine, unique, post-freeze V2 content -- not duplicated
anywhere, just living in the wrong/legacy root docs/ location):
  - docs/architecture/*.md -> hardware/v2/docs/architecture/
  - docs/pinouts.md, docs/FPGA_NEURAL_V2_DATASHEET.md,
    docs/FPGA_NEURAL_V2_SCHEMATIC.md,
    docs/FPGA-Neural-V2-Datasheet-EN.pdf -> hardware/v2/docs/

Left untouched (separate decisions, not part of this cleanup):
  - docs/FPGA-Neural-Flash-Subsystem-Verification.md, docs/
    v2-description.md -- orphaned root-only content, no duplicate
    found anywhere, but also not part of the reviewed plan
  - synth/ecp5/* experiment dirs and sim/*_sim + sim/*.vcd build
    artifacts -- not literal duplicates, flagged as candidates for a
    future, separate cleanup pass

Verified no functional breakage: grepped all remaining scripts/docs
for references to every removed path -- only prose/comment mentions
found, no executable imports or build-script paths broken.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 05:30:17 +02:00
micheleandClaude Sonnet 5 e1cefd13db docs: remove hardware/v2/docs/DatasheetLatex, superseded by datasheet/
Replaced by the just-versioned hardware/v2/docs/datasheet/ (the
project's real, maintained IT+EN LaTeX datasheet, now including the
2026-09-07 SDRAM upgrade addendum). DatasheetLatex/ was a separate,
differently-structured, stale LaTeX document living in the same
location -- removed to avoid two competing datasheets under
hardware/v2/docs. hardware/v1/docs/DatasheetLatex/ is untouched (V1
scope, not part of this request).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 05:10:58 +02:00
micheleandClaude Sonnet 5 ff49d3c75d docs: bring datasheet/ into the main repo under hardware/v2/docs
Was a separate, untracked directory (DataSheet/) outside the repo.
Renamed to lowercase and moved in as hardware/v2/docs/datasheet/, with
its own .gitignore for LaTeX build byproducts (compiled PDFs stay
tracked, .aux/.log/.toc/etc do not). Now versioned and shares this
repo's own remote instead of living untracked on disk.

Content: IT+EN LaTeX chapter sources, reference manufacturer PDFs, and
compiled datasheet PDFs including the 2026-09-07 SDRAM upgrade
addendum (AS4C32M16SB-7BIN part/pinout/timing) in the v2-en chapters.

Note: hardware/v2/docs/DatasheetLatex/ (and the v1 sibling) is a
separate, already-tracked, differently-structured LaTeX document that
predates this move -- left untouched, not merged, since its chapter
set and content differ and merging was not requested.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 05:09:14 +02:00
micheleandClaude Sonnet 5 f14224d0cd fix: ERR-0029 sdram_unified_backend weight-cache hit-index critical path
Replace the serial "last-match-wins" priority-scan hit-index encoder
with a flat one-hot compare + single-level priority encode, breaking
the serially-dependent PFUMX/OFX cascade real P&R showed dominating
the N_SLOTS=8 @ 64MHz critical path (55.84MHz worst, 4/8 seeds PASS).

Real nextpnr-ecp5 re-verification (32-run matrix, 4 configs x 8 seeds):
N_SLOTS=8 @ 64MHz improves to 5/8 PASS (worst 60.12MHz, up from
55.84MHz). N_SLOTS=4 @ 64MHz stays 8/8 PASS but with reduced worst-case
margin (WNS +0.605ns, down from +2.143ns) as the critical path
relocates to a different, previously-second-worst path in the same
module -- a real, disclosed trade-off, not hidden. 80MHz remains NO-GO
at both processor counts (re-confirmed on the fixed RTL).

Bit-exact, zero functional regression: isolated
tb_sdram_unified_backend.v (40/40) and full D-Stress N=4/N=8 (both
256/256 neurons bit-exact vs golden model).

See errors.log ERR-0029 and decisions.log DEC-0040 for full root-cause
writeup and MEMORY_UPGRADE_64MB_N8.md section 10 for the complete
measured data set and AS4C32M16SB-7BIN pinout tables.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 03:10:50 +02:00
micheleandClaude Sonnet 5 a20f1ecd73 docs: memory upgrade writeup (MEMORY_UPGRADE_64MB_N8.md) + supersede stale SDRAM docs
Adds the consolidated, authoritative record for the 64MB memory
upgrade and N_SLOTS=8 investigation (real datasheet family comparison,
RTL changes, both timing fixes with real P&R data, honest N=8 clock-
closure status, real DigiKey availability for the frozen part).

Marks HARDWARE_FREEZE.md/MEMORY_ARCHITECTURE.md/PRE_PCB_VERIFICATION.md/
PRE_PCB_CLOSURE_4POINT.md's own SDRAM-specific sections as superseded
(they describe the previous 8MB AS4C4M16SA-6TIN part) with pointers to
the new document, rather than rewriting each individually.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 00:21:05 +02:00
micheleandClaude Sonnet 5 c4763aab10 test: directed SDRAM boundary verification + SPI frequency sweep
PRE-PCB CLOSURE Point 1: adds tb_sdram_boundary.v, a directed (not
randomized) regression covering address 0/1/last/last-1, an explicit
row-boundary crossing, all 3 inter-bank boundary crossings, the real
V2 memory-map region boundaries (weights/activations/results), and
every DQM byte-mask combination with explicit read-after-write.
21/21 PASS at both 64MHz and 166MHz, zero bugs found.

PRE-PCB CLOSURE Point 2: adds tb_spi_freq_sweep.v, a reproducible SPI
bit-rate sweep against the real fpga_neural_v2_top (osc_clk driven at
the real 64MHz clk_sys rate via the SIM PLL bypass). Found and fixed a
race in the new test harness itself (a fixed-time wait before reading
a WRITE_MEM/READ_MEM response, too short whenever a periodic AUTO
REFRESH delayed the backend) -- not a spi_host_bridge.v defect,
confirmed against tb_spi_host_bridge.v's own isolated regression.
Determined the real, deterministic CDC margin: the synchronizer
requires >=5 system-clock cycles per SPI bit (exactly 64MHz/5 =
12.8MHz); recommends SPI_MAX_VERIFIED=12MHz with real margin below
that hard edge.

Full writeup: hardware/v2/docs/PRE_PCB_CLOSURE_4POINT.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-06 19:42:37 +02:00
micheleandClaude Sonnet 5 eb0b0f9170 docs: PRE-PCB VERIFICATION FREEZE report + config flash freeze
Adds hardware/v2/docs/PRE_PCB_VERIFICATION.md as the single
authoritative pre-schematic verification record: RTL/ERR-0025/
regression re-verification, clock/reset, synthesis/P&R re-audit,
setup/hold timing status, the real SDRAM datasheet-parameter audit
table (Alliance Memory AS4C4M16SA-6TIN Table 17), SPI host bridge
protocol documentation, FPGA power/pinout tables, first-board bring-up
and benchmark status, and cross-domain consistency audit.

Freezes the FPGA configuration flash: Winbond W25Q32JVSSIQ (32Mbit,
SOIC-8, 2.7-3.6V, standard SPI, ECP5 Master-SPI-boot compatible) --
this was the one section-11 item the governing mandate required not
be left OPEN.

Marks CHIP_READINESS.md/OPEN_ITEMS.md/PINOUT.md/CLOCK_ARCHITECTURE.md/
POWER_ARCHITECTURE.md/SCHEMATIC_READINESS.md as superseded (they
predate the SPI host bridge, PLL, and this session's SDRAM datasheet
audit) with pointers to the new consolidated document, rather than
rewriting each individually.

Updates the V2 LaTeX datasheet's status/roadmap chapter to reflect the
SDRAM datasheet audit and configuration-flash decisions, rebuilds the
PDF (clean compile, 16 pages).

Classification: PRE-PCB VERIFIED. Schematic and PCB implementation
remain user-owned and not started.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-06 18:32:40 +02:00
micheleandClaude Sonnet 5 d6376e8f2a V2 final synthesis/P&R sign-off + LaTeX datasheet port (NOT SILICON READY)
Real synthesis and place-and-route of the actual final board-level
top (fpga_neural_v2_top.v -- SPI bridge, real EHXPLLL, reset_sync,
compute+memory core), against a real, fully ball-assigned LPF. Also
ports the V2 datasheet to LaTeX using V1's own preamble/macros/
typography, and records a real (non-ESP32, honestly labeled) software
reference comparison.

Synthesis (Yosys, real run): 0 CHECK-pass problems, 38 unique warnings
(43 total), all matching this project's own previously-reviewed benign
set (neural_processor.v's known genvar multi-driver artifact, small-
array-to-register unrolling, the real SDRAM DQ tristate bus) -- no new
warnings from the SPI bridge, PLL, or reset synchronizer.
TRELLIS_FF=6322, TRELLIS_COMB=7084, MULT18X18D=32, EHXPLLL=1 (real PLL
confirmed present), DP16KD=0 (all small SRAMs -> distributed RAM).

Place-and-route (nextpnr-ecp5, real runs, 8 seeds, new
v2_board_top.lpf with all 44 top-level signals ball-assigned from the
official Lattice pinout CSV -- no placeholders): 8/8 PASS at 64MHz.
Worst 68.51MHz (seed 4), best 74.17MHz (seed 7), mean 71.16MHz. Zero
unrouted nets, zero placement/routing errors, TRELLIS_IO=44/245 (17%).
Critical path alternates between dependency_manager's own priority
encoder and sdram_unified_backend's own weight-cache hit-index logic,
matching this project's own prior documented timing investigations --
not a new defect.

New: hardware/v2/constraints/v2_board_top.lpf (final LPF, supersedes
v2_unified.lpf for the board-level top), hardware/v2/reports/
step_final_{synthesis,pnr_worst_seed4,timing}.* (raw evidence),
hardware/v2/docs/DatasheetLatex/ (V2 datasheet, real LaTeX build,
16 pages, visually inspected, ported from hardware/v1/docs/
DatasheetLatex/'s own preamble and macros).

Real, honestly-labeled software baseline: the D-Stress arithmetic
(256 neurons x 128 INT8 MACs) compiled and run on THIS development
machine (Apple M4, arm64, NOT an embedded target, NOT ESP32) --
1.28us/inference, included in the datasheet with an explicit
disclosure that no physical ESP32 hardware was available for a real
embedded-target comparison.

Remaining, disclosed, NOT-yet-closed items (this commit does NOT
claim silicon readiness): real KiCad schematic + ERC, PCB layout,
sourced BOM, real power current-budget estimate, SDRAM-datasheet-
parameter cross-check, configuration-flash selection, and (necessarily)
physical fabrication/bring-up. See hardware/v2/docs/DatasheetLatex/
chapters/08-status-roadmap.tex for the complete, itemized checklist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-06 17:50:53 +02:00
micheleandClaude Sonnet 5 68f3c5e403 fix(v2): resolve ERR-0025 Part B - SRAM read timing bug in weight/activation memory
Root-causes and fixes the real, disclosed defect left open at the end
of the previous STEP20 commit: the board-level SPI host interface
produced wrong compute results when jobs were dispatched with
realistic (widely time-separated) pacing, even though job registration
itself was already confirmed correct at the dependency_manager
handshake.

Root cause: nms_weight_packed.v and nms_activation_replicated.v both
used a REGISTERED SRAM read (rd_data_reg <= mem[addr], one full clock
of latency), but nms_memory_manager_stream_wide.v's own read-ahead
pipeline (its `rd_pending` bit) is designed around a COMBINATIONAL
read -- a request issued this cycle produces data already valid to
capture the very next cycle. A busy, multi-tile job (e.g. the STEP19
D-Stress regression, 16 tiles/neuron) never exposes the mismatch,
since its own weight/activation prefetch always runs far enough ahead
that any given tile has been sitting stable in the SRAM for many
cycles by the time it's actually consumed. An uncontested single-tile
job has zero such margin: its one tile's read fires on the exact edge
the data nominally becomes ready, landing squarely on the missing
cycle and permanently latching stale/zero data.

Fixed by making both SRAMs' reads combinational, with an explicit
same-cycle fill/read address-match bypass for the one hazard a plain
combinational read alone would still miss. No FSM, arbiter, or SDRAM
controller logic was touched.

Verified (Verilator, per this project's own standing DEC-0004
protocol):
- tb_fpga_neural_v2_top_smoke.v: 11/11 PASS -- single job, back-to-back
  jobs, a realistic ~85us-gap job pair, and a parametric sweep of
  inter-job gaps (100ns/5000ns/50000ns).
- STEP19 D-Stress N=2: 49788 cycles, 256/256 bit-exact -- identical
  cycle count to before this fix (zero regression).
- STEP19 D-Stress N=4: 49771 cycles, 256/256 bit-exact -- identical
  cycle count to before this fix (zero regression).
- tb_sdram_unified_backend.v (40/40) and tb_spi_host_bridge.v (18/18)
  reconfirmed unaffected.

The physical SPI host interface is now verified correct end-to-end.
Real synthesis/P&R of the board-level top (fpga_neural_v2_top.v) is
the deliberate next step, not yet performed this round.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-06 17:33:45 +02:00
micheleandClaude Sonnet 5 43abf28b5b V2.1.0-dev: SPI host bridge + clock/reset architecture (NOT release-ready)
STEP20 work toward the V2 hardware release gate. Adds real new RTL
implementing the three pieces the previous freeze (V2.0.0) explicitly
left open, plus real, disclosed verification findings. Does NOT
declare hardware release complete -- see below.

New RTL:
- spi_host_bridge.v: real SPI slave protocol engine (WRITE_JOB/
  WRITE_MEM/READ_MEM/STATUS/RESET opcodes), replacing the 110-pin
  reg_* testbench bus as the intended physical host interface.
  Isolated regression 18/18 PASS (tb_spi_host_bridge.v); two real
  MISO-timing bugs found and fixed during its own development (see
  the module's header for the root-cause writeup).
- ecp5_pll_sys_clk.v: real, tool-generated (Project Trellis ecppll)
  EHXPLLL wrapper, 16MHz oscillator -> 64MHz system clock, with a
  declared (not fabricated) simulation-only PLL bypass.
- reset_sync.v: standard async-assert/sync-deassert reset bridge
  gating on external POR and PLL lock.
- fpga_neural_v2_top.v: board-level top wiring the above around the
  STEP19 compute+memory design's own already-frozen submodules
  (zero modification to neural_processor.v, dependency_manager.v,
  sdram_unified_backend.v, or any other previously-frozen file).

Real findings from this step's own re-verification (both logged in
full in hardware/v2/logs/errors.log):
- ERR-0024: the current Icarus Verilog v13.0 install (updated since
  the last freeze) gives WRONG bit-exact results for the
  already-committed STEP19 regression. Cross-checked against
  Verilator per this project's own standing protocol (DEC-0004) --
  the STEP19 baseline (single SDRAM, N=2/N=4, raw reg_* interface) IS
  bit-exact correct, reconfirmed today, matching the historical cycle
  counts exactly. Two provably-zero-behavior-change declaration-order
  fixes were required just to get the current toolchain to elaborate
  the already-shipped STEP19 files at all.
- ERR-0025: a real SPI-bridge protocol race (fixed) plus a SEPARATE,
  real, UNRESOLVED defect -- two jobs dispatched through the real SPI
  path with realistic pacing produce wrong compute results, even
  though job registration itself is confirmed correct at the
  handshake. Root cause not yet isolated. Committed as a known-failing
  regression (tb_fpga_neural_v2_top_smoke.v) documenting the gap
  honestly rather than hiding it.

Given ERR-0025 Part B is real and unresolved, synthesis/P&R of the new
board-level top was deliberately not attempted this round, and V2
hardware release is NOT declared complete. See decisions.log DEC-0036
and hardware/v2/docs/{CHIP_READINESS,OPEN_ITEMS}.md for the full,
itemized status.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-06 14:35:14 +02:00
micheleandClaude Sonnet 5 8e014d8d49 V2.0.0 hardware freeze - single SDRAM
FASE #1 hardware freeze for FPGA-Neural V2, N4/P8, single external
SDRAM (Alliance Memory AS4C4M16SA-6TIN) serving weights, activations,
and results through one physical sdram_controller.v instance. Removes
the PSRAM dependency (hardware/v1/rtl/psram_controller.v +
memory_interface.v) from the V2 physical path entirely -- V1 itself
remains fully unmodified, the golden reference.

New RTL: sdram_unified_backend.v (2-way W/AR arbitration over one
SDRAM controller, real per-byte DQM write masking added to
sdram_controller.v for correct single-byte result writes with no
read-modify-write), nms_neural_multiprocessor_sdram_unified.v (the
frozen top-level). Two real bugs found and fixed via full-system
testing before being accepted (ERR-0023): a deadlock and an off-by-one
data-shift bug in the new arbitration logic.

Real results: N=4 and N=2 D-Stress bit-exact (256/256 neurons), 40
real AUTO REFRESH events interleaved with zero corruption, real
Yosys+nextpnr-ecp5 synthesis/P&R for LFE5U-45F-8CABGA381 (149/245
TRELLIS_IO, a real 45-pin reduction from the prior dual-memory
design). Timing is MARGINAL (1/8 P&R seeds >=80MHz), reported honestly
rather than masked by the best seed.

Real, sourced ball-level pinout for the SDRAM bus + clk/rst (39/149
signals, P&R-verified) using the official Lattice ECP5U-45 pinout CSV
found on disk during this step's own pre-commit review -- corrects an
earlier draft that wrongly assumed no real pinout data was available.

Chip readiness: NO. Real, disclosed blockers remain (no physical host
interface exists yet -- the RTL's own reg_* ports are a 110-pin raw
test-harness bus; clock source/PLL decision; power/configuration
component selection) -- see hardware/v2/docs/{HARDWARE_FREEZE,
CHIP_READINESS,OPEN_ITEMS}.md for the complete, itemized status.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-06 13:39:55 +02:00
micheleandClaude Sonnet 5 63cac6a7e5 perf(v2): shared activation cache - further 1.66-2.00x real speedup (DEC-0016)
Implements optimization #2 from the final benchmark campaign's own
recommendation, on top of DEC-0015's word-level burst rewrite: a new
shared activation_cache.v module fetches a given activation (X)
vector from PSRAM once instead of once per neuron sharing it - the
exact redundant traffic pattern the dense-layer workloads in this
project's benchmark suite exhibit.

Each memory_manager's own prefetch_engine now fetches WEIGHTS only;
the activation half is requested from the shared cache instead
(single-tag, tile-granular, N_SLOTS request ports, its own real
word-level PSRAM backend via a new dedicated arbiter port).
dataflow_core.v/slot_mem_arbiter.v/neural_multiprocessor.v widened to
N_SLOTS+1 ports to arbitrate the cache's traffic alongside each
slot's weight traffic.

Two real bugs found and fixed during implementation (ERR-0010): a
target-bank/pending-bank race in memory_manager.v's activation-cache
wiring (the same bug class ERR-0006 already fixed once for
pf_target_bank - a later handoff's queued request can overwrite which
bank an earlier, still-in-flight request's ack applies to), and a
repeat of ERR-0009's N_SLOTS=1 zero-width replication bug in
activation_cache.v itself.

Real, measured results: the full final-benchmark campaign (24/24
workload/config combinations) re-verified bit-exact. D-Stress cycles
fall a further 1.66-2.00x on top of DEC-0015 (~4x combined vs the
original byte-level baseline). But the cache's real Fmax cost is much
steeper than DEC-0015's own: N_SLOTS=2 (the recommended default,
DEC-0014) drops from 133.58 to 87.72 MHz (-34%, margin over 80MHz
shrinks from +67% to +9.7%), and N_SLOTS=4 drops to 65.01 MHz - now
FAILING the 80MHz target it previously passed. Combined real
wall-clock speedup vs the original baseline: N=1 3.86x, N=2 2.45x
(both real net wins); N=4 is a real regression once its own now-failing
Fmax is honestly used, though N=4 was never the recommended
configuration.

N_SLOTS=2 remains the recommended default (DEC-0014 unaffected) with
a thinner but still real Fmax margin. Cache hit-detection pipelining
is flagged as concrete follow-up work if N_SLOTS>2 is ever needed with
the cache active - not attempted this round.

Logged: simulation/synthesis/timing/benchmark/decisions (DEC-0016)/
experiments (EXP-0016)/errors (ERR-0010)/development.log, ROADMAP.md
updated.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 20:59:14 +02:00
micheleandClaude Sonnet 5 3cdaeaee35 test(v2): final benchmark campaign - real end-to-end characterization (EXP-0014)
Post-M10, user-requested final benchmark campaign: 6 realistic
workloads (16-256 independent neurons in a shared-input dense-layer
shape, a random-seeded 2-layer network with real cross-node PSRAM
forwarding, and a 6-node 2-hop dependency diamond) x 4 concurrency
levels (N_SLOTS=1/2/4/8) through the real, full neural_multiprocessor
system (real V1 PSRAM chain, real slot_mem_arbiter). 24/24 runs PASS
bit-exact against a software golden model (11,520 individual neuron/
node checks, zero mismatches).

Three real bugs found and fixed during the campaign itself (ERR-0009):
1. neural_director.v (M5) had a real RTL bug at N_SLOTS=1
   ($clog2(1)=0 makes a replication expression illegal) - never
   caught because M5-M10 only ever tested N_SLOTS=2/4/8. Fixed with
   a width-agnostic '0 literal; M5's own testbench re-verified
   unaffected.
2/3. Two testbench sizing bugs in tb_benchmark_suite.v itself
   (psram_model DEPTH too small for the Large workload's address
   range; N_NODES too small for the Stress workload's node-id range,
   causing a real deadlock via node-id wraparound colliding with an
   already-DISPATCHED node - a real, honest consequence of DEC-0008's
   own "no node-slot reclamation" design choice).

Headline finding: real parallel scaling is essentially flat beyond
N_SLOTS=2 - the single shared PSRAM port saturates at ~91%
utilization regardless of slot count, so memory-bound workloads gain
only 1.05-1.06x real speedup from N=1 to N=8. Once real POST-P&R Fmax
degradation is also factored in, N_SLOTS=4 is measurably 21% SLOWER
in real wall-clock time than N_SLOTS=1 for the largest workload
tested. N_SLOTS=2 is recommended as the default (DEC-0014,
superseding DEC-0012's resource-only "N_SLOTS=8 ceiling" framing for
general use).

Full 21-section report (every number classified THEORETICAL/
SIMULATED/POST-P&R MEASURED/DERIVED, per the user's own
methodology requirements): hardware/v2/docs/benchmarks/
final-benchmark.md

Logged: simulation/synthesis/timing/benchmark/decisions (DEC-0014)/
experiments (EXP-0014)/errors (ERR-0009)/development.log,
ROADMAP.md updated.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 19:58:30 +02:00
micheleandClaude Sonnet 5 91bbbe2fe5 feat(v2): M10 Optimization - data-driven findings, completes the V2 roadmap
Final milestone of docs/v2-description.md's §33 roadmap, scoped
exactly to its own mandate: optimize only on data already gathered in
M1-M9, across the pipeline/P_IN/processor-count/scheduling/memory
axes - no speculative new features.

Three concrete, data-driven results:

1. N_SLOTS=8 (numero processor axis): real synthesis + nextpnr-ecp5
   P&R for dataflow_core at N_SLOTS=8, extending M7's N_SLOTS=2/4
   sweep to the real DSP ceiling DEC-0005 predicted. 92.63 MHz
   POST-P&R, PASS at 80MHz, DSP 64/72 (88.9%). DEC-0012 recommends
   N_SLOTS=8 as the practical ceiling for P_IN=8 on the
   LFE5U-45F-8BG381.

2. ACC_WIDTH 24 vs 32 (pipeline axis): a real 6-seed nextpnr-ecp5
   placement sweep (reusing already-synthesized netlists, no new
   synthesis needed) resolves EXP-0002's single-seed
   inconclusiveness. ACC_WIDTH=24 wins on both mean Fmax (+6.2%,
   180.71 vs 170.12 MHz) and seed-to-seed variance (~3.4x tighter),
   on top of its already-known resource advantage. DEC-0013
   recommends ACC_WIDTH=24 as the new default.

3. Stall %/utilization (scheduling/memory axes): testbench-only cycle
   counters added to tb_neural_multiprocessor.v (no RTL touched)
   close DEC-0011's deferred measurement gap with real data - shared
   PSRAM port 81.7% utilized, slot 0 95.2%, slot 1 65.2%, no
   conclusive evidence of harmful fixed-priority starvation at this
   scale.

The 10-milestone V2 roadmap (docs/v2-description.md §33) is now
complete end-to-end: real Verilator simulation, real Yosys synthesis,
real nextpnr-ecp5 place & route for every milestone, fully logged
(EXP-0001..EXP-0013, DEC-0001..DEC-0013, ERR-0001..ERR-0008) with no
invented results (§30) and V1 kept frozen and untouched throughout
(§1/§34).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 18:58:10 +02:00
micheleandClaude Sonnet 5 84794a3d25 docs(v2): M9 full benchmark - V1 vs V2 comparison table (§32)
Consolidates real, already-measured data from hardware/v1/ (frozen,
pre-certified) and V2's own M1-M8 logs into the §32-mandated
comparison table, on an apples-to-apples basis: both full systems
(V1's spi_neuron_top post_fix_verify vs V2's neural_multiprocessor
N_SLOTS=2), both PARALLEL=8/P_IN=8, both using the real unmodified V1
PSRAM backend.

Headline, all real measurements: V2 full-system Fmax 142.45 MHz
POST-P&R (PASS at 80MHz) vs V1's 68.65 MHz (FAIL at 80MHz); 166 vs 209
real simulated cycles for one neuron's 8-input dot product through the
same real PSRAM chain (2.6x wall-clock speedup); peak MAC/cycle 16
(N_SLOTS=2 concurrent slots, real contention already demonstrated in
EXP-0009) vs V1's 8 (single sequential core); lower LUT/FF despite V2
already including full dependency-graph scheduling that V1 has none
of.

9 of the table's 12 rows carry real sourced numbers; stall %/memory
utilization/processor utilization are reported as NOT MEASURED rather
than approximated (DEC-0011) - a real number needs dedicated
cycle-accounting instrumentation neither system has had built for it
yet, and approximating from partial data would violate §30's "no
invented results" rule. Deferred to M10, which needs exactly this
data to decide what to optimize.

No new RTL this milestone - pure data consolidation, logged as
EXP-0010.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 15:17:14 +02:00
micheleandClaude Sonnet 5 6cff2c8a7c feat(v2): M8 PSRAM integration - real V1 backend shared across concurrent slots
neural_multiprocessor.v wraps dataflow_core.v (M7, unmodified) around
the real, unmodified V1 PSRAM backend chain (int8_memory_access ->
memory_interface -> psram_controller), funneling N_SLOTS independent
Memory Backend Interface ports through a new generic N-port arbiter
(slot_mem_arbiter.v) inspired by (not copied from) V1's own
mem_arbiter.v.

Real concurrent-slot simulation immediately surfaced a genuine bug
(ERR-0008): memory_manager/prefetch_engine's byte-level backend
protocol is fire-and-forget (a single-cycle mem_req pulse with no
accept handshake) - correct for M4's direct 1:1 connection, but a
naive arbiter silently drops a pulse arriving while the shared bus is
owned by another slot, hanging that slot forever. Fixed with a
per-port pending-request latch, the same "queue, don't drop" idiom
already used by memory_manager's own pf_pending register (ERR-0006).

Verified (Verilator): 4/4 PASS with 2 slots genuinely contending for
one real PSRAM port (444 cycles). No regression on M4's own
testbench. Real synthesis + nextpnr-ecp5 P&R (no harness needed - real
PSRAM pins keep the top-level at 157 pins): 0 problems, Fmax 142.45
MHz, PASS at 80MHz.

Arbitration policy is fixed lowest-index priority, not fairness-
balanced (DEC-0010) - consistent with every other "simplest correct
policy first" scheduling choice in this roadmap, revisited only if
M9's real measurement shows starvation matters.

Logged: simulation/synthesis/timing/benchmark/decisions (DEC-0010)/
experiments (EXP-0009)/errors (ERR-0008)/development.log, ROADMAP.md
updated.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 15:13:11 +02:00
micheleandClaude Sonnet 5 77baa8fc16 feat(v2): M7 Dataflow Core - full M1-M6 integration, wake-up loop closed end-to-end
dataflow_core.v integrates dependency_manager (M6) -> neural_director
(M5) -> N_SLOTS x (memory_manager (M4) + neural_processor (M1)) for
the first time. A slot's completion (via neural_director's new
slot_node_id tracking, an additive port) feeds back as a
producer_done event to dependency_manager, waking up any node that
depended on it - closing the dataflow loop without external glue.

Verified end-to-end (Verilator) on a 3-node DAG: two independent
nodes plus a third depending on both, confirmed to dispatch only
after both genuinely complete via real neural_processor computation.
4/4 PASS.

Real synthesis + nextpnr-ecp5 P&R via a synthesis-only timing harness
(bare per-slot backend ports exceed the LFE5U-45F's TRELLIS_IO
budget, same pattern as ERR-0005): N_SLOTS=2 -> 165.15 MHz,
N_SLOTS=4 -> 133.19 MHz, both PASS at 80MHz, 0 synthesis problems.

Scope explicitly deferred to M8 (DEC-0009): M3's BRAM buffers not
wired in yet, per-slot Memory Backend Interface ports not arbitrated
to one shared PSRAM master yet - both need real measured data before
committing to a design, not guessed at here.

Logged: simulation/synthesis/timing/benchmark/decisions (DEC-0009)/
experiments (EXP-0008)/errors (ERR-0007, a Yosys chparam-ordering
build quirk, not an RTL bug)/development.log, ROADMAP.md updated.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 15:05:28 +02:00
micheleandClaude Sonnet 5 8af16d3a12 feat(v2): M6 Dependency Manager, multi-dependency wake-up
Implements M6: dependency_manager.v tracks a table of node
descriptors (node_id/state/required_dependencies/resolved_
dependencies/producer_ids -- §10's exact field list), incrementing a
waiting node's resolved count whenever one of its listed producers
completes, transitioning it to READY once resolved==required, and
dispatching ready nodes to the Neural Director (M5) one at a time via
a backpressure-safe valid/ready interface.

Verified with Verilator on a small hand-built DAG: node0/node1 have no
dependencies (dispatch immediately); node2 depends on BOTH node0 AND
node1 ("dipendenze multiple") and stays WAITING until both complete,
confirmed via an explicit negative check after only one resolves;
node3 depends on node0 ALONE, demonstrating a single producer
("node0") satisfying two different consumers' dependencies
("risultati condivisi... piu' consumer") -- node3 fully, node2
partially. 4/4 tests pass.

Scope for this milestone (decisions.log DEC-0008): dependency
COUNTING/readiness only, no direct producer-to-consumer value
forwarding (§11 frames that as a "quando possibile" optimization, not
a correctness requirement -- deferred until real bandwidth
measurements justify it) and no node-slot reclamation after dispatch
(not exercised by any scenario built so far).

Real synthesis: 0 CHECK problems, 763 LUT4/474 FF/0 DSP/0 CCU2C. Real
place&route (module fits the TRELLIS_IO budget as a bare top-level
this time, no harness needed): Fmax 155.30 MHz, PASS at 80MHz.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 14:51:02 +02:00
micheleandClaude Sonnet 5 2e4cedc761 feat(v2): M5 Neural Director, first-free job scheduling
Implements M5: neural_director.v dispatches job descriptors to
whichever of N_SLOTS (memory_manager, neural_processor) pairs is
currently free (first-free scheduling per §9's initial policy), with
a parametric-depth ready-queue FIFO for jobs arriving faster than
slots can absorb them.

Scope for this milestone (see decisions.log DEC-0007): a reduced
4-state FSM (DIR_IDLE/SCAN_READY/ALLOCATE/ERROR) rather than §9's full
8-state baseline -- dependency tracking, the waiting queue, and
wake-up are §10's explicit responsibility (Dependency Manager, M6, not
yet built), and slot-completion detection runs as an always-active
per-slot tracker rather than a dedicated FSM state, for the same
reason DEC-0002 already gave for the Neural Processor's own FSM
(gating concurrent per-unit progress behind one shared state kills
throughput).

Verified with Verilator (N_SLOTS=2, each slot backed by its own
independent behavioral memory rather than sharing V1's real PSRAM --
M4 already proved that path for one slot; this milestone's own concern
is scheduling across multiple slots): 4/4 tests pass -- 3 jobs
submitted to 2 slots (first two dispatch immediately, third correctly
queues until a slot frees), and a deliberate burst that forces the
ready queue to genuinely fill and recover.

Real synthesis: 0 CHECK problems, 382 LUT4/366 FF/4 CCU2C/0 DSP. Real
place&route (via a synthesis-only timing harness, same TRELLIS_IO
pin-budget reason as M2/M4): Fmax 250.50 MHz, PASS at 80MHz.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 14:46:32 +02:00
micheleandClaude Sonnet 5 175f697ae1 feat(v2): M4 Memory Manager + Prefetch Engine, real V1 PSRAM backend
Implements M4: memory_manager.v (arbitration/buffering/forwarding/
latency hiding/double buffering, §12) + prefetch_engine.v
(double-buffered tile fetch, §13), sitting on the REAL, UNMODIFIED V1
PSRAM backend chain (int8_memory_access.v -> memory_interface.v ->
psram_controller.v, per §15's explicit mandate not to touch the
controller).

Verified fully end-to-end with Verilator: real neural_processor (M1)
fed entirely by memory_manager, computing against PSRAM-resident X/W
tiles (double-buffered prefetch across up to 5 tiles) and writing its
result back to PSRAM -- checked via an independent PSRAM read-back,
with poison bytes around the operand regions to catch addressing
errors. 3/3 jobs pass (1/3/5-tile configurations).

Three real RTL bugs found and fixed during integration (full
diagnostic trail in errors.log ERR-0006): prefetch_engine had no
single-in-flight-request discipline, letting a queued request corrupt
the bank bookkeeping of a fetch already running; the fix's own
!pf_busy guard had a one-cycle blind spot (pf_busy lags pf_start by a
clock) that needed an explicit !pf_start term; and a state-based mux
for the shared backend port was off by one cycle, silently dropping
the PSRAM result write entirely.

Real synthesis: 0 CHECK problems, 851 LUT4/789 FF/108 CCU2C/0 DSP
(expected, no multiplication in this module). Real place&route (via a
synthesis-only timing harness, needed for the same TRELLIS_IO pin-
budget reason as M2's array): Fmax 165.86 MHz, PASS at 80MHz.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 14:39:29 +02:00
micheleandClaude Sonnet 5 5f0d7f101c feat(v2): M3 activation/weight/result buffers, real BRAM mapping
Implements M3: three parametric dual-port buffers for the §12
data-plane (Input/Weight/Result), reusing the proven BRAM-inference
idiom from the frozen hardware/v1/rtl/act_buffer.v (synchronous write,
synchronous REGISTERED read, no reset on the read register -- keeps
Yosys off the LUT-RAM path).

Verified with Verilator: 10/10 tests pass (write-then-read
correctness, extreme INT8 round-tripping, weight_buffer's full 64-bit
tile width round-tripping, undisturbed re-reads).

Real synthesis at two depths per module (6 configs total): 0 CHECK
problems, every configuration correctly infers DP16KD (never
LUT-RAM). Non-obvious real finding: weight_buffer's BRAM cost is
driven by its P_IN*DATA_WIDTH tile width, not its DEPTH -- an 8x depth
reduction (512->64) left DP16KD usage unchanged at 2, while
activation_buffer/result_buffer (byte-wide) scale as naively expected
(2->1). All default-depth configs PASS at 80MHz with large margin
(287-367 MHz) via real nextpnr-ecp5 place&route.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 14:19:11 +02:00
micheleandClaude Sonnet 5 3026dcd997 feat(v2): M2 Neural Processor Array, N_PROCESSORS resource sweep
Implements M2 of the V2 roadmap: neural_processor_array.v instantiates
N_PROCESSORS independent neural_processor (M1) units, each with its
own dedicated point-to-point job/operand/result interface -- no shared
bus or mux at this level (arbitration is explicitly the Neural
Director's job, M5).

Verified with Verilator (tb_neural_processor_array.v, N_PROCESSORS=4):
7/7 tests pass, including a same-cycle 4-way concurrent launch with
different tile counts and a staggered-start test where a
later-launched, shorter job completes before an earlier-launched,
longer one -- confirming genuine independent concurrent execution
(§18/§34: a blocked/busy processor must not block the others).

Real resource/timing sweep for N_PROCESSORS in {1,2,4,8} (Yosys +
nextpnr-ecp5, real place&route): Fmax stays above the 80MHz target
throughout (159.11 -> 134.70 MHz), but MULT18X18D usage scales
linearly and reaches 88% of the LFE5U-45F's 72 DSPs at N=8 while
LUT/FF stay under 6% -- DSP, not LUT/FF/routing, is the first hard
ceiling on N_PROCESSORS at P_IN=8 (decisions.log DEC-0005). Measured
via a dedicated synthesis-only timing harness after the array's wide
per-processor buses were found to exhaust the device's TRELLIS_IO pin
budget as a bare top-level module beyond N=1 (errors.log ERR-0005) --
not a logic limit, an artifact of testing the array in isolation
before the Memory Manager/Director (M4/M5) exist to consume those
ports on-chip.

Full log trail (development/experiments/errors/decisions/simulation/
synthesis/timing/benchmark.log) in hardware/v2/logs/ per the project's
logging mandate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-05 14:15:11 +02:00
micheleandClaude Sonnet 5 dc0b331d3e 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
2026-09-05 14:06:53 +02:00