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
This commit is contained in:
@@ -74,3 +74,10 @@ dominated by psram_model.v's real ~70ns TAA access latency, not by
|
||||
memory_manager's own control overhead (its bank-swap turnaround is
|
||||
documented as a fixed +1 cycle/tile in decisions.log DEC-0006, a small
|
||||
fraction of the ~140-cycle PSRAM-dominated total).
|
||||
|
||||
[2026-09-05] M5 Neural Director (standalone resource count; Fmax via
|
||||
timing harness -- see errors.log ERR-0005)
|
||||
|
||||
| Module | Fmax (POST-P&R) | LUT | FF | DSP | CCU2C |
|
||||
|------------------|------------------|-----|-----|-----|-------|
|
||||
| neural_director (N_SLOTS=4) | 250.50 MHz | 382 | 366 | 0 | 4 |
|
||||
|
||||
@@ -319,3 +319,73 @@ rather than optimized blindly now.
|
||||
|
||||
STATUS:
|
||||
ACCEPTED
|
||||
|
||||
---
|
||||
|
||||
DEC-0007
|
||||
|
||||
DATE: 2026-09-05
|
||||
|
||||
DECISION:
|
||||
neural_director.v (M5) implements a reduced FSM (DIR_IDLE,
|
||||
DIR_SCAN_READY, DIR_ALLOCATE, DIR_ERROR) instead of §9's full 8-state
|
||||
baseline list (which also includes DIR_WAIT_DEPENDENCY, DIR_MONITOR,
|
||||
DIR_COMPLETE, DIR_WAKEUP). Dependency tracking/waiting/wake-up are
|
||||
entirely deferred to the Dependency Manager (M6, not yet built); slot
|
||||
completion detection (§9's "rilevamento dei completamenti",
|
||||
DIR_MONITOR's job) is handled by an always-active per-slot busy
|
||||
tracker running independently of whatever state the allocate/scan
|
||||
loop happens to be in, not a dedicated state the loop must visit.
|
||||
|
||||
WHY:
|
||||
§10 explicitly assigns dependency counters/ready-vs-waiting
|
||||
tracking/wake-up/producer-tracking to the Dependency Manager, not the
|
||||
Director -- building DIR_WAIT_DEPENDENCY/DIR_WAKEUP now, before M6
|
||||
exists, would mean inventing a dependency model here that M6 would
|
||||
then have to either reuse or replace, backwards from the roadmap's own
|
||||
milestone order. For DIR_MONITOR: gating "did any slot just finish"
|
||||
detection behind a specific FSM state would force the SAME state to be
|
||||
revisited every cycle for every one of N_SLOTS independently-running
|
||||
jobs, which is exactly the throughput-killing pattern DEC-0002 already
|
||||
rejected for the Neural Processor's own FSM -- the same reasoning
|
||||
applies one level up here.
|
||||
|
||||
EVIDENCE:
|
||||
hardware/v2/sim/tb_neural_director.v -- 4/4 tests pass with 2 slots
|
||||
running genuinely concurrent, independently-timed jobs (a 3rd job
|
||||
correctly queued until whichever slot freed first, and a
|
||||
deliberately-slow 2-job burst used to force real ready-queue
|
||||
backpressure) -- confirms slot-completion detection and first-free
|
||||
allocation both work without a dedicated FSM state gating either.
|
||||
|
||||
Separately: this milestone's testbench gives each (memory_manager,
|
||||
neural_processor) slot its OWN independent behavioral byte memory
|
||||
(sim_byte_mem, not the real V1 PSRAM chain) rather than sharing one
|
||||
PSRAM port across N_SLOTS. M4 (EXP-0005) already proved the real PSRAM
|
||||
path end-to-end for ONE slot; M5's own concern is scheduling/dispatch
|
||||
across MULTIPLE slots, which this isolates. Multiple slots genuinely
|
||||
sharing one physical PSRAM port is a backend-arbitration problem
|
||||
already explicitly deferred (DEC-0006), not solved here either.
|
||||
|
||||
ALTERNATIVES:
|
||||
1. Implement the literal 8-state FSM now, with DIR_WAIT_DEPENDENCY/
|
||||
DIR_WAKEUP as real states that simply never get exercised until
|
||||
M6 wires something into them. Rejected: dead states with no real
|
||||
behavior are not simpler or safer than documenting the deferral
|
||||
explicitly, and risk baking in an ad-hoc dependency model that
|
||||
conflicts with M6's actual design once built.
|
||||
2. Share one real PSRAM backend across N_SLOTS now, forcing the
|
||||
arbiter-design question into M5. Rejected: out of this milestone's
|
||||
scope (§9 is about scheduling, not memory arbitration) and would
|
||||
duplicate work once M6/M8 need a real answer to backend sharing
|
||||
anyway.
|
||||
|
||||
RESULT:
|
||||
neural_director.v as implemented: 4-state FSM, always-active slot-busy
|
||||
tracking, ready-queue backpressure via a plain parametric-depth
|
||||
circular FIFO. First-free scheduling only (§9's initial policy);
|
||||
round-robin/least-loaded/etc are explicitly deferred to a later,
|
||||
experimentally-driven milestone per §9's own text.
|
||||
|
||||
STATUS:
|
||||
ACCEPTED
|
||||
|
||||
@@ -137,3 +137,25 @@ errors: vedi errors.log ERR-0005 (ricorrenza), ERR-0006 (3 bug nuovi).
|
||||
decision: vedi decisions.log DEC-0006 (motore di prefetch singolo +
|
||||
registro pendente, nessun arbitro backend ancora necessario).
|
||||
next_action: M5 -- neural_director.v, scheduling first-free.
|
||||
|
||||
[2026-09-05T17:00:00Z] commit=175f697 session=v2-M5-neural-director
|
||||
module: hardware/v2/rtl/neural_director.v
|
||||
action: implementato M5 -- Neural Director, scheduling first-free
|
||||
(§9) su N_SLOTS coppie (memory_manager, neural_processor). FSM
|
||||
ridotta a 4 stati (DIR_IDLE/SCAN_READY/ALLOCATE/ERROR) -- dependency
|
||||
tracking/wake-up rimandati al Dependency Manager (M6, non ancora
|
||||
costruito), rilevamento completamenti gestito da un tracker
|
||||
sempre-attivo per-slot (non uno stato dedicato da rivisitare).
|
||||
reason: roadmap M5.
|
||||
result: 4/4 test PASS (N_SLOTS=2) -- dispatch first-free confermato,
|
||||
coda pronta con backpressure reale confermata (riempimento e
|
||||
recupero), 3 job su 2 slot con il terzo correttamente in coda fino
|
||||
a liberazione di uno slot. 2 bug di testbench trovati e risolti
|
||||
(non RTL): DEPTH di sim_byte_mem troppo piccolo per il range di
|
||||
indirizzi usato, e una condizione di attesa che si fermava al primo
|
||||
job completato invece che a tutti e tre. Sintesi reale: 0 problemi,
|
||||
382 LUT4/366 FF/4 CCU2C/0 DSP. Fmax reale (via harness): 250.50 MHz.
|
||||
errors: nessun bug RTL, solo 2 bug di testbench (vedi experiments.log
|
||||
EXP-0006).
|
||||
decision: vedi decisions.log DEC-0007.
|
||||
next_action: M6 -- dependency_manager.v.
|
||||
|
||||
@@ -274,3 +274,51 @@ decision: see decisions.log DEC-0006 (single prefetch engine + pending
|
||||
next_action: M5 -- neural_director.v (first-free scheduling), wiring
|
||||
job dispatch to potentially multiple (memory_manager, neural_
|
||||
processor) pairs instead of the single hardcoded pair tested here.
|
||||
|
||||
EXP-0006
|
||||
timestamp: 2026-09-05T17:00:00Z
|
||||
git_commit: 175f697 (+ uncommitted M5 work)
|
||||
session: v2-M5-neural-director
|
||||
module: hardware/v2/rtl/neural_director.v
|
||||
configuration: N_SLOTS=2 (sim), N_SLOTS=4 (synth default),
|
||||
QUEUE_DEPTH=4 (sim), ADDR_WIDTH=23
|
||||
action: M5 -- first-free job scheduler dispatching to N_SLOTS
|
||||
(memory_manager, neural_processor) pairs, with a parametric-depth
|
||||
ready queue.
|
||||
command (sim, Verilator): verilator --binary --timing -j 0 -Wno-fatal
|
||||
--top-module tb -o /tmp/vtb_dir hardware/v2/rtl/neural_processor.v
|
||||
hardware/v2/rtl/prefetch_engine.v hardware/v2/rtl/memory_manager.v
|
||||
hardware/v2/rtl/neural_director.v hardware/v2/sim/tb_neural_director.v
|
||||
&& /tmp/vtb_dir
|
||||
command (synth): yosys -p "synth_ecp5 -json .../top.json -top
|
||||
neural_director" hardware/v2/rtl/neural_director.v (standalone, real
|
||||
resource counts); harness_neural_director.v (see errors.log
|
||||
ERR-0005 pattern) for real P&R Fmax.
|
||||
result:
|
||||
SIMULATED (N_SLOTS=2, tb_neural_director.v): 4/4 tests PASS --
|
||||
3 jobs submitted to 2 slots (first two dispatch immediately,
|
||||
first-free; third correctly WAITS in the ready queue until a slot
|
||||
frees, then auto-dispatches), each result independently verified;
|
||||
a deliberate 2-long-job burst forces the ready queue to genuinely
|
||||
fill (job_in_ready correctly deasserts after exactly QUEUE_DEPTH
|
||||
queued jobs while both slots are kept busy) and recover once
|
||||
slots/queue drain.
|
||||
SYNTHESIZED (standalone, N_SLOTS=4): 0 CHECK problems, 382 LUT4,
|
||||
366 TRELLIS_FF, 4 CCU2C, 0 DSP.
|
||||
POST-P&R (via harness, real Fmax): 250.50 MHz, PASS at 80MHz with
|
||||
large margin.
|
||||
errors: two real testbench bugs found and fixed during bring-up (not
|
||||
RTL bugs): (1) sim_byte_mem's DEPTH parameter (1024) was smaller
|
||||
than the test's own address range (up to 0x703=1795), an
|
||||
out-of-bounds array access silently returning garbage; (2) the
|
||||
initial completion-wait loop exited as soon as ANY ONE of three
|
||||
jobs' result bytes changed, not all three -- fixed by counting
|
||||
job_out_done pulses instead of polling result memory directly.
|
||||
decision: see decisions.log DEC-0007 (reduced 4-state FSM; dependency
|
||||
handling deferred to M6; per-slot independent behavioral memory
|
||||
instead of shared real PSRAM, deferred to when backend arbitration
|
||||
is actually needed).
|
||||
next_action: M6 -- dependency_manager.v (ready/waiting queue,
|
||||
dependency counters, wake-up, producer tracking) -- the first
|
||||
milestone where job READINESS itself, not just free-slot dispatch,
|
||||
becomes the Director's actual gating condition.
|
||||
|
||||
@@ -48,3 +48,9 @@ bit-exact result: PSRAM-read-back result byte matches hand-computed
|
||||
RTL under test)
|
||||
cycles: 446 (3 tiles), 166 (1 tile), 728 (5 tiles) -- real PSRAM
|
||||
latency dominates, not memory_manager's own control overhead
|
||||
|
||||
[2026-09-05] EXP-0006 -- hardware/v2/sim/tb_neural_director.v
|
||||
test: 4 cases (3-jobs-2-slots first-free dispatch + queueing,
|
||||
backpressure fill/recover)
|
||||
simulator: Verilator 5.050 (--binary --timing)
|
||||
PASS/FAIL: 4/4 PASS
|
||||
|
||||
@@ -40,3 +40,6 @@ CHECK: 0 problems, all 6 configs correctly infer DP16KD (no LUT-RAM
|
||||
[2026-09-05] EXP-0005 -- memory_manager + prefetch_engine (standalone)
|
||||
LUT4=851 TRELLIS_FF=789 CCU2C=108 MULT18X18D=0 (expected, no
|
||||
multiplication in this module). CHECK: 0 problems.
|
||||
|
||||
[2026-09-05] EXP-0006 -- neural_director (N_SLOTS=4, standalone)
|
||||
LUT4=382 TRELLIS_FF=366 CCU2C=4 DSP=0. CHECK: 0 problems.
|
||||
|
||||
@@ -44,3 +44,8 @@ harness_memory_manager.v, see errors.log ERR-0005 for why a harness
|
||||
was needed), real nextpnr-ecp5 --45k --package CABGA381 --speed 8
|
||||
--freq 80 --lpf-allow-unconstrained
|
||||
Fmax: 165.86 MHz -- PASS at 80MHz (real place&route measurement)
|
||||
|
||||
[2026-09-05] EXP-0006 -- neural_director (via harness_neural_director.v,
|
||||
see errors.log ERR-0005 for why), real nextpnr-ecp5 --45k --package
|
||||
CABGA381 --speed 8 --freq 80 --lpf-allow-unconstrained
|
||||
Fmax: 250.50 MHz -- PASS at 80MHz (real place&route measurement)
|
||||
|
||||
Reference in New Issue
Block a user