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
22 KiB
FPGA-Neural V2 — Neural Multiprocessor / Dataflow Architecture Obiettivo
Progettare e implementare una V2 dell'acceleratore neurale FPGA contenuto nel repository:
https://github.com/manvalan/FPGA-Neural
La V2 deve evolvere l'architettura V1 trasformandola da un acceleratore principalmente sequenziale a una Neural Multiprocessor / Dataflow Machine, mantenendo V1 come implementazione di riferimento funzionante.
L'obiettivo non è semplicemente aumentare PARALLEL.
L'obiettivo è costruire un'architettura composta da:
molteplici Neural Processor / Perceptron Processor indipendenti; un Neural Director / Orchestrator; un Dependency Manager; un Memory Manager; buffer locali e FIFO; prefetch; forwarding dei risultati; pipeline interne ai Neural Processor; esecuzione concorrente di più neuroni; gestione dinamica delle dipendenze; capacità di eseguire reti regolari, DAG, fuzzy network e strutture con dipendenze non strettamente sequenziali.
Il sistema deve essere progettato come una piccola macchina dataflow neurale, non come una semplice versione più larga dell'architettura V1.
- Regola fondamentale: V1 è il Golden Reference
La V1 funzionante deve essere conservata integralmente.
Non modificare, cancellare o degradare la V1 per implementare la V2.
Struttura obbligatoria:
hardware/ ├── v1/ │ ├── rtl/ │ ├── sim/ │ ├── constraints/ │ ├── synthesis/ │ └── ... │ └── v2/ ├── rtl/ ├── sim/ ├── constraints/ ├── synthesis/ ├── reports/ ├── scripts/ ├── logs/ └── docs/
La V1 deve essere utilizzata come:
riferimento funzionale; riferimento numerico; riferimento prestazionale; riferimento per i test bit-exact; baseline per valutare ogni modifica V2. 2. Hardware target
Target FPGA:
Lattice ECP5U LFE5U-45F-8BG381
La progettazione deve tenere conto delle caratteristiche reali del dispositivo.
Non assumere che una maggiore quantità di DSP/logic implichi automaticamente maggiore prestazione.
Il limite può essere:
timing; routing; fanout; congestione; memoria; larghezza dei bus; mux; distribuzione dei segnali; interconnessioni tra blocchi.
Ogni scelta importante deve quindi essere verificata con sintesi e place-and-route reali.
- Baseline V1
La V1 attuale contiene, tra gli altri:
rtl/neuron_parallel.v rtl/mac8.v rtl/mac_unit.v rtl/neuron_memory.v rtl/layer_sequencer.v rtl/graph_engine.v rtl/act_buffer.v rtl/psram_controller.v rtl/int8_memory_access.v rtl/memory_interface.v rtl/mem_arbiter.v rtl/spi_neuron_top.v
La V1 utilizza:
INT8; accumulazione INT32; PARALLEL=8; MAC paralleli; adder tree bilanciato; bias; activation; saturazione INT8; memoria PSRAM/CellularRAM esterna.
Dati reali già osservati nella V1:
P16 ≈ 52.13 MHz P8 ≈ 61.71 MHz P4 ≈ 75.01 MHz P2 ≈ 87.88 MHz
in una configurazione isolata N_INPUTS=256.
Nel sistema integrato:
P8 ≈ 65.13 MHz
con failure rispetto a un target di 80 MHz.
Il critical path osservato è principalmente legato alla logica del neuron_parallel e alla sua interconnessione, non al controller PSRAM.
Questi dati devono essere considerati misure reali V1, non risultati V2.
- Architettura V2
La V2 deve essere organizzata in due piani.
Control Plane Neural Director │ ├── Scheduler ├── Dependency Manager ├── Ready Queue ├── Waiting Queue └── Processor State Data Plane ┌─────────────────────┐ │ Memory Manager │ └──────────┬──────────┘ │ ┌────────────┼────────────┐ │ │ │ Buffer Buffer Buffer Input Weight Result │ │ │ └────────────┼────────────┘ │ ┌────────────┬───────┴───────┬────────────┐ │ │ │ │ NP0 NP1 NP2 NP3 │ │ │ │ └────────────┴───────────────┴────────────┘ │ Result/Forward
Il numero di processor non deve essere deciso a priori.
Deve essere determinato tramite sweep di sintesi e timing.
- Neural Processor
Il Neural Processor è l'unità fondamentale della V2.
Ogni processor deve essere autonomo e indipendente.
Un processor esegue un neurone alla volta, ma il datapath interno deve essere pipelineizzato.
Configurazione iniziale:
P_IN = 8
Ogni processor inizialmente deve avere:
8 × INT8 multiplier balanced adder tree INT32 accumulator bias activation INT8 saturation local operand registers/FIFO job interface result interface
Pipeline iniziale candidata:
Stage 0 input alignment/register Stage 1 8 multipliers Stage 2 adder tree level 1 Stage 3 adder tree level 2 Stage 4 adder tree level 3 Stage 5 accumulator Stage 6 bias / activation Stage 7 output / saturation
La pipeline può essere modificata se le simulazioni e il timing dimostrano una soluzione migliore.
L'obiettivo principale è il throughput, non la minima latenza possibile.
- Neural Processor FSM
Ogni Neural Processor deve avere una macchina a stati chiaramente definita.
Baseline:
NP_IDLE NP_LOAD_JOB NP_WAIT_OPERANDS NP_LOAD_TILE NP_MAC NP_ACCUM NP_NEXT_TILE NP_FINISH NP_WRITE_RESULT NP_DONE NP_ERROR NP_IDLE
Processor libero e disponibile.
NP_LOAD_JOB
Caricamento del job descriptor.
Inizializzazione:
node ID; numero input; indirizzo input; indirizzo pesi; bias; activation; tile count; accumulator. NP_WAIT_OPERANDS
Attesa degli operandi.
Il processor deve poter rimanere bloccato senza impedire agli altri processor di lavorare.
NP_LOAD_TILE
Caricamento di un tile locale.
NP_MAC
Esecuzione del datapath MAC pipeline.
NP_ACCUM
Aggiornamento dell'accumulatore.
NP_NEXT_TILE
Richiesta del tile successivo.
Il Memory Manager dovrebbe averlo già prefetched.
NP_FINISH
Bias, activation e saturazione.
NP_WRITE_RESULT
Handshake con Memory Manager / result path.
NP_DONE
Il processor ritorna disponibile.
NP_ERROR
Gestione degli errori senza bloccare globalmente il sistema.
- Interfacce del Neural Processor
Evitare grandi mux dinamici come quelli dell'architettura V1.
Preferire:
valid ready data last
per gli stream.
Input:
operand_valid operand_ready input_data weight_data tile_last
Output:
result_valid result_ready result_data node_id
La validità deve essere pipelineizzata insieme ai dati.
Non assumere ritardi fissi senza handshake o valid propagation.
- Neural Processor Array
Creare:
hardware/v2/rtl/neural_processor_array.v
Il modulo deve permettere:
N_PROCESSORS = parametrico P_IN = parametrico
Configurazioni iniziali:
1 × P8 2 × P8 4 × P8 8 × P8
Successivamente esplorare configurazioni maggiori se timing e risorse lo consentono.
Esempi teorici:
4 × P8 = 32 MAC/cycle 8 × P8 = 64 MAC/cycle
Questi sono solo valori teorici.
Non presentarli mai come throughput misurato.
- Neural Director / Orchestrator
Creare:
hardware/v2/rtl/neural_director.v
Il Director controlla l'intero sistema.
Responsabilità:
ricezione dei job; scansione dei job READY; scelta del processor libero; assegnazione; tracking dello stato dei processor; gestione delle dipendenze; rilevamento dei completamenti; wake-up dei job; gestione ready queue; gestione waiting queue; prevenzione dei deadlock; massimizzazione dell'utilizzo dei processor.
FSM iniziale:
DIR_IDLE DIR_SCAN_READY DIR_ALLOCATE DIR_WAIT_DEPENDENCY DIR_MONITOR DIR_COMPLETE DIR_WAKEUP DIR_ERROR
Scheduling iniziale:
first-free
Successivamente valutare:
round-robin least-loaded locality-aware priority-based dependency-aware
La politica migliore deve essere determinata sperimentalmente.
- Dependency Manager
Creare:
hardware/v2/rtl/dependency_manager.v
Ogni nodo deve avere almeno:
node_id state required_dependencies resolved_dependencies producer_information
Esempio:
node 37 required = 4 resolved = 3 state = WAITING
Quando arriva il quarto risultato:
resolved = 4 state = READY
Il nodo può quindi essere assegnato dal Director.
Il sistema deve supportare:
dipendenze multiple; risultati condivisi; più consumer; wake-up; forwarding; backpressure. 11. Dataflow e token
Il modello concettuale deve supportare token:
TOKEN ├── node_id ├── value └── valid
Quando un processor produce un risultato:
Producer │ ├──→ Consumer FIFO │ └──→ Result Buffer
Quando possibile il dato deve essere inoltrato direttamente al consumer senza obbligare il sistema a fare:
processor → external memory → memory controller → buffer → processor
Il risultato può essere contemporaneamente:
forwarded; memorizzato; utilizzato da più consumer. 12. Memory Manager
Creare:
hardware/v2/rtl/memory_manager.v
Il Neural Processor non deve accedere direttamente alla PSRAM.
Il Memory Manager deve occuparsi di:
input activations; weights; results; prefetch; buffering; FIFO; arbitration; forwarding; gestione latenza; double buffering; memory request scheduling.
Il processor deve vedere principalmente:
data available
e non:
PSRAM latency 13. Prefetch
Creare:
hardware/v2/rtl/prefetch_engine.v
Usare inizialmente una strategia:
compute tile N │ └── concurrently ──→ prefetch tile N+1
Con double buffering:
Buffer A → COMPUTE Buffer B → PREFETCH
swap
Buffer B → COMPUTE Buffer A → PREFETCH
Priorità:
HIGH operand required now MEDIUM next tile LOW future tile 14. Buffer
Creare:
hardware/v2/rtl/activation_buffer.v hardware/v2/rtl/weight_buffer.v hardware/v2/rtl/result_buffer.v
La profondità deve essere parametrica.
Valutare anche:
FIFO depth buffer depth numero porte BRAM mapping routing timing
Non assumere che buffer più grandi siano automaticamente migliori.
- Memoria esterna
NON iniziare modificando il controller PSRAM.
Mantenere inizialmente il backend esistente.
Astrarre il Memory Manager dal backend:
Memory Manager │ ▼ Memory Backend Interface │ ▼ PSRAM Controller
Solo dopo aver misurato il sistema V2 valutare eventuali alternative:
SRAM; PSRAM; SDRAM; DDR; QSPI; altre memorie o risorse esterne.
Qualsiasi modifica hardware esterna deve essere motivata da dati reali.
- Parallelismo
Due parametri fondamentali:
P_IN N_PROCESSORS
P_IN indica il numero di MAC paralleli dentro un Neural Processor.
N_PROCESSORS indica quanti Neural Processor operano contemporaneamente.
Eseguire sweep almeno su:
P_IN = 2, 4, 8
e:
N_PROCESSORS = 1, 2, 4, 6, 8, 12, 16...
fino al limite imposto da:
LUT; FF; DSP; BRAM; routing; timing.
La configurazione finale deve essere scelta sulla base del throughput effettivo, non dell'utilizzo massimo delle risorse.
- Dataflow Core
Creare:
hardware/v2/rtl/dataflow_core.v
Il modulo integra:
Neural Director Dependency Manager Memory Manager Prefetch Engine Neural Processor Array Activation Buffer Weight Buffer Result Buffer
Architettura:
JOBS
│
▼
┌─────────────────┐
│ Neural Director │
└───────┬─────────┘
│
┌───────▼─────────┐
│ Dependency │
│ Manager │
└───────┬─────────┘
│
▼
┌─────────────────┐
│ Memory Manager │
└───────┬─────────┘
│
┌─────────┼─────────┐
▼ ▼ ▼
NP0 NP1 NP...
│ │ │
└─────────┼─────────┘
│
▼
RESULTS
- Scheduling dinamico
Il sistema deve permettere che:
NP0 → node A NP1 → node B NP2 → node C NP3 → WAIT
Se NP3 attende un risultato:
NP3 WAIT
non deve bloccare:
NP0 NP1 NP2
Quando il risultato arriva:
Producer ↓ Dependency Manager ↓ dependency resolved ↓ job READY ↓ Director ↓ free processor 19. Supporto a reti diverse
L'architettura deve essere sufficientemente generale per supportare:
Layer regolari input → layer → layer → output DAG ┌── node B ──┐ node A ┤ ├→ node E └── node C ──┘ Fuzzy network
con dipendenze irregolari e numero variabile di ingressi.
Cloud / sparse graph
con nodi attivati dinamicamente.
Non costruire il sistema assumendo esclusivamente una rete fully-connected regolare.
- Simulazione obbligatoria
Ogni componente deve avere un testbench.
Creare:
hardware/v2/sim/ ├── tb_neural_processor.v ├── tb_neural_processor_array.v ├── tb_memory_manager.v ├── tb_prefetch_engine.v ├── tb_dependency_manager.v ├── tb_neural_director.v └── tb_dataflow_core.v
Test obbligatori:
test funzionali; random test; extreme INT8; pipeline; stall; backpressure; dependency; wake-up; forwarding; multi-processor concurrency; deadlock detection; data-loss detection; bit-exact comparison con V1.
Valori INT8 da includere:
-128 -127 -1 0 1 126 127 21. Test bit-exact
Ogni risultato V2 deve essere confrontabile con V1.
Per gli stessi:
inputs weights bias activation network
deve essere verificato:
V1 result == V2 result
salvo differenze esplicitamente documentate e matematicamente giustificate.
- Performance simulation
La simulazione deve misurare almeno:
total_cycles compute_cycles stall_cycles memory_wait_cycles processor_busy_cycles processor_idle_cycles completed_neurons completed_tiles processor_utilization memory_utilization effective_throughput stall_percentage
Eseguire anche sweep della latenza memoria:
0 cycles 1 cycle 2 cycles 4 cycles 8 cycles 16 cycles
L'obiettivo è misurare quanto efficacemente il prefetch nasconde la latenza.
- Sintesi e Place & Route
Ogni configurazione deve essere realmente verificata con:
Icarus / Verilator Yosys nextpnr-ecp5
Non inventare risultati.
Non stimare il timing come se fosse una misura.
Distinguere sempre:
THEORETICAL RTL SIMULATION SYNTHESIS POST-P&R MEASUREMENT
Il valore Fmax ufficiale della configurazione deve provenire dal place-and-route reale.
- Benchmark
Per ogni configurazione creare:
hardware/v2/reports/ ├── simulation/ ├── synthesis/ ├── timing/ └── experiments/
Esempio:
hardware/v2/reports/experiments/EXP-0001/ ├── experiment.yaml ├── simulation.log ├── synthesis.log ├── timing.log ├── results.txt └── notes.md
Ogni benchmark deve contenere almeno:
Fmax processors P_IN MAC/cycle LUT FF DSP BRAM cycles/neuron neurons/s stall % effective MAC/s 25. LOGGING OBBLIGATORIO Questa è una regola fondamentale del progetto.
OGNI attività significativa deve essere registrata.
Nessuna modifica, simulazione, sintesi, benchmark, decisione architetturale o errore deve essere perso.
Creare:
hardware/v2/logs/ ├── development.log ├── architecture.log ├── simulation.log ├── synthesis.log ├── timing.log ├── benchmark.log ├── decisions.log ├── experiments.log └── errors.log
Il registro principale deve essere:
hardware/v2/logs/experiments.log
Ogni esperimento deve avere un identificativo univoco:
EXP-0001 EXP-0002 EXP-0003 ...
Gli ID non devono essere riutilizzati.
- Contenuto minimo di ogni log
Ogni evento significativo deve contenere:
timestamp experiment_id git_commit session/agent module configuration action reason command result errors decision next_action
Per synthesis/timing includere anche:
LUT FF DSP BRAM Fmax critical path WNS/TNS se disponibili
Per simulazione:
test vectors cycles PASS/FAIL bit-exact result stall cycles memory wait utilization 27. Logging delle decisioni
Ogni scelta architetturale importante deve essere registrata in:
hardware/v2/logs/decisions.log
Formato concettuale:
DEC-0001
DATE: ...
DECISION: Use 4 independent P8 Neural Processors.
WHY: ...
EVIDENCE: EXP-0001 EXP-0002 EXP-0003
ALTERNATIVES: P4 × 8 P8 × 4 P16 × 2
RESULT: ...
STATUS: ACCEPTED
Le decisioni devono essere basate su dati quando possibile.
- Nessuna sovrascrittura dei risultati
I risultati precedenti non devono essere cancellati o sovrascritti.
Se:
EXP-0017 = PASS EXP-0018 = FAIL EXP-0019 = PASS
tutti e tre devono rimanere.
Un risultato negativo è comunque un risultato utile.
Deve essere possibile ricostruire la storia:
idea ↓ implementazione ↓ test ↓ fallimento/successo ↓ modifica ↓ nuovo test ↓ decisione 29. Riproducibilità
Ogni esperimento deve essere riproducibile.
Il log deve permettere di sapere:
quale commit quale configurazione quali parametri quale toolchain quale comando quale testbench quali constraint quale risultato
Ogni report deve essere associato al commit Git utilizzato.
Se il working tree contiene modifiche non committate, questo deve essere esplicitamente registrato.
- Regola contro risultati inventati
È vietato presentare dati non misurati come dati reali.
Esempio:
4 × P8 @ 80 MHz = 2.56 GMAC/s
deve essere indicato:
THEORETICAL
Finché non esiste una misura reale.
Un risultato:
Fmax = 83.7 MHz
può essere dichiarato misurato solo se ottenuto da:
nextpnr-ecp5
con relativa configurazione e report salvati.
- Sweep automatici
Creare:
hardware/v2/scripts/sweep/
Gli script devono poter eseguire automaticamente combinazioni di:
P_IN N_PROCESSORS FIFO depth buffer depth pipeline configuration
e produrre automaticamente:
simulation synthesis place-and-route timing resource utilization benchmark
Ogni configurazione deve generare un proprio:
EXP-XXXX
e registrarlo nei log.
- Confronto V1 vs V2
Il benchmark finale deve produrre una tabella:
V1 V2
Fmax LUT FF DSP BRAM MAC/cycle cycles/neuron neurons/s stall % memory utilization processor utilization effective MAC/s
Ogni numero deve essere classificato come:
THEORETICAL SIMULATED SYNTHESIZED POST-P&R 33. Roadmap di implementazione M1 — Neural Processor
Implementare:
hardware/v2/rtl/neural_processor.v
P8.
Input forniti direttamente dal testbench.
Obiettivo:
bit-exact V1 pipeline funzionante
Eseguire simulation + synthesis + timing.
M2 — Processor Array
Implementare:
neural_processor_array.v
Testare:
1 2 4 8
processor.
Misurare:
timing; risorse; throughput; utilization. M3 — Buffers
Implementare:
activation_buffer.v weight_buffer.v result_buffer.v M4 — Memory Manager
Implementare:
memory_manager.v prefetch_engine.v
Inizialmente utilizzare il backend PSRAM esistente.
M5 — Neural Director
Implementare:
neural_director.v
Scheduling iniziale:
first-free M6 — Dependency Manager
Implementare:
dependency_manager.v
Aggiungere:
ready; waiting; dependency counters; wake-up; producer tracking. M7 — Dataflow Core
Integrare:
dataflow_core.v M8 — PSRAM integration
Integrare il controller V1 senza modificarlo inizialmente.
Misurare il comportamento reale.
M9 — Full benchmark
Confrontare V1/V2.
M10 — Optimization
Solo sulla base dei dati:
pipeline; P_IN; numero processor; buffer; FIFO; scheduling; prefetch; routing; memoria. 34. Principi architetturali non negoziabili V1 rimane intatta. V2 vive esclusivamente sotto hardware/v2/.... Nessun risultato inventato. Ogni misura deve provenire dagli strumenti appropriati. Ogni modifica deve essere registrata. Ogni esperimento deve avere un ID. Nessun risultato precedente deve essere sovrascritto. Ogni decisione importante deve avere una motivazione. Ogni benchmark deve essere riproducibile. Un processor bloccato non deve bloccare gli altri. Il Neural Processor non deve conoscere direttamente la memoria esterna. Il Director gestisce WHAT deve essere eseguito. Il Memory Manager gestisce COME rendere disponibili i dati. Il Neural Processor gestisce COME eseguire il calcolo. Ottimizzare il throughput effettivo, non il numero di DSP utilizzati. Evitare grandi mux e interconnessioni globali quando possibile. Favorire località fisica e pipeline. Le configurazioni devono essere esplorate sperimentalmente. Ogni modifica deve essere confrontata con la baseline. Il progetto deve mantenere una cronologia completa e ricostruibile dello sviluppo. 35. Filosofia finale
La V2 deve evolvere FPGA-Neural verso:
NEURAL DIRECTOR
│
┌────────────┼────────────┐
│ │ │
READY WAITING DEPENDENCY
QUEUE QUEUE MANAGER
│
▼
MEMORY MANAGER
│
┌─────────┼─────────┐
│ │ │
INPUT WEIGHT RESULT
BUFFER BUFFER BUFFER
│ │ │
└─────────┼─────────┘
│
┌──────────────┼──────────────┐
│ │ │
NP0 NP1 NP...
│ │ │
└──────────────┼──────────────┘
│
DATAFLOW / FORWARD
Il risultato finale deve essere una macchina neurale parallela e dataflow, capace di mantenere occupati più Neural Processor contemporaneamente, nascondere la latenza della memoria, gestire dipendenze dinamiche e scalare il numero di processor in funzione dei limiti reali dell'ECP5.
Il processo di sviluppo deve essere completamente tracciabile:
IDEA ↓ ARCHITECTURE LOG ↓ IMPLEMENTATION ↓ SIMULATION ↓ SYNTHESIS ↓ PLACE & ROUTE ↓ MEASUREMENT ↓ EXPERIMENT LOG ↓ DECISION LOG ↓ NEXT EXPERIMENT
Non deve esistere una modifica "non registrata", una misura "senza report" o una decisione architetturale "senza motivazione".