working with memory
This commit is contained in:
@@ -0,0 +1,929 @@
|
||||
# FPGA-Neural — Analisi datapath e benchmark ECP5
|
||||
|
||||
## 1. Obiettivo
|
||||
|
||||
Questa fase del progetto FPGA-Neural ha avuto lo scopo di verificare il comportamento sintetizzabile e le prestazioni del core neurale parametrico sul dispositivo:
|
||||
|
||||
**Lattice LFE5U-45F-8BG381C**
|
||||
|
||||
Configurazione FPGA:
|
||||
|
||||
- ECP5-45F
|
||||
- Speed grade: `-8`
|
||||
- Package: `CABGA381`
|
||||
- 72 blocchi `MULT18X18D`
|
||||
- circa 43.8k LUT/FF equivalenti
|
||||
|
||||
La configurazione funzionale utilizzata nei benchmark è:
|
||||
|
||||
```text
|
||||
DATA_WIDTH = 8 bit
|
||||
ACC_WIDTH = 32 bit
|
||||
N_INPUTS = 256
|
||||
N_NEURONS = 4
|
||||
PARALLEL = variabile
|
||||
|
||||
Il datapath implementa:
|
||||
|
||||
INT8 × INT8
|
||||
↓
|
||||
INT16
|
||||
↓
|
||||
sign extension
|
||||
↓
|
||||
INT32
|
||||
↓
|
||||
accumulation
|
||||
↓
|
||||
+ bias
|
||||
↓
|
||||
ReLU
|
||||
↓
|
||||
INT8 saturation
|
||||
|
||||
Lo scopo principale del benchmark è stato determinare il compromesso tra:
|
||||
|
||||
numero di MAC paralleli;
|
||||
utilizzo dei DSP;
|
||||
complessità del datapath;
|
||||
routing;
|
||||
frequenza massima;
|
||||
latenza di elaborazione.
|
||||
2. Architettura RTL
|
||||
|
||||
L'attuale datapath è organizzato gerarchicamente:
|
||||
|
||||
layer
|
||||
│
|
||||
┌────────┴────────┐
|
||||
│ │
|
||||
neuron 0 neuron N
|
||||
│ │
|
||||
▼ ▼
|
||||
neuron_parallel neuron_parallel
|
||||
│ │
|
||||
▼ ▼
|
||||
mac8 mac8
|
||||
│ │
|
||||
MAC × PARALLEL MAC × PARALLEL
|
||||
|
||||
Ogni neurone elabora N_INPUTS ingressi a gruppi di PARALLEL.
|
||||
|
||||
Con:
|
||||
|
||||
N_INPUTS = 256
|
||||
|
||||
il numero di gruppi è:
|
||||
|
||||
GROUPS = 256 / PARALLEL
|
||||
|
||||
Pertanto:
|
||||
|
||||
PARALLEL Gruppi per neurone
|
||||
16 16
|
||||
8 32
|
||||
4 64
|
||||
2 128
|
||||
|
||||
I quattro neuroni vengono elaborati contemporaneamente.
|
||||
|
||||
3. MAC unit
|
||||
|
||||
Il modulo mac_unit implementa un singolo prodotto-accumulatore.
|
||||
|
||||
Per la configurazione INT8:
|
||||
|
||||
x : signed INT8
|
||||
w : signed INT8
|
||||
|
||||
Il prodotto è:
|
||||
|
||||
INT8 × INT8 = INT16
|
||||
|
||||
Il risultato viene quindi esteso con segno a 32 bit:
|
||||
|
||||
INT16 → INT32
|
||||
|
||||
e sommato all'accumulatore.
|
||||
|
||||
L'operazione fondamentale è quindi:
|
||||
|
||||
acc_out = acc_in + (x × w)
|
||||
|
||||
L'implementazione è completamente parametrica rispetto a:
|
||||
|
||||
DATA_WIDTH
|
||||
ACC_WIDTH
|
||||
4. Balanced adder tree
|
||||
|
||||
Una modifica importante rispetto alla prima implementazione è stata la sostituzione dell'accumulatore combinazionale lineare con un balanced binary adder tree.
|
||||
|
||||
Una riduzione lineare avrebbe prodotto:
|
||||
|
||||
((((p0 + p1) + p2) + p3) + ...)
|
||||
|
||||
con profondità:
|
||||
|
||||
O(PARALLEL)
|
||||
|
||||
La nuova implementazione utilizza invece:
|
||||
|
||||
sum
|
||||
/ \
|
||||
sum sum
|
||||
/ \ / \
|
||||
p0 p1 p2 p3
|
||||
|
||||
La profondità diventa:
|
||||
|
||||
O(log2(PARALLEL))
|
||||
|
||||
Per esempio:
|
||||
|
||||
PARALLEL = 8
|
||||
→ 3 livelli
|
||||
|
||||
PARALLEL = 16
|
||||
→ 4 livelli
|
||||
|
||||
PARALLEL = 32
|
||||
→ 5 livelli
|
||||
|
||||
Questa modifica riduce significativamente la profondità combinazionale del datapath.
|
||||
|
||||
5. neuron_parallel
|
||||
|
||||
neuron_parallel esegue il calcolo di un singolo neurone.
|
||||
|
||||
Il funzionamento è:
|
||||
|
||||
start
|
||||
↓
|
||||
group 0
|
||||
↓
|
||||
group 1
|
||||
↓
|
||||
...
|
||||
↓
|
||||
group N
|
||||
↓
|
||||
+ bias
|
||||
↓
|
||||
ReLU
|
||||
↓
|
||||
saturation
|
||||
↓
|
||||
done
|
||||
|
||||
Durante ogni ciclo viene elaborato un gruppo di:
|
||||
|
||||
PARALLEL
|
||||
|
||||
prodotti.
|
||||
|
||||
L'accumulatore mantiene il risultato tra un gruppo e il successivo.
|
||||
|
||||
6. Test funzionale
|
||||
|
||||
Il testbench sim/parametric_tb.v utilizza:
|
||||
|
||||
DATA_WIDTH = 8
|
||||
N_INPUTS = 256
|
||||
N_NEURONS = 4
|
||||
PARALLEL = variabile
|
||||
ACC_WIDTH = 32
|
||||
|
||||
Sono stati definiti quattro casi di test.
|
||||
|
||||
N0 — accumulazione su più gruppi
|
||||
|
||||
Input:
|
||||
|
||||
x = 1
|
||||
|
||||
Pesi:
|
||||
|
||||
primi 32 = +1
|
||||
restanti = 0
|
||||
|
||||
Risultato:
|
||||
|
||||
32 × 1 × 1 = 32
|
||||
|
||||
Output atteso:
|
||||
|
||||
32
|
||||
|
||||
Questo test verifica soprattutto la corretta gestione dell'accumulatore attraverso più gruppi.
|
||||
|
||||
N1 — bias
|
||||
|
||||
Pesi:
|
||||
|
||||
tutti = 0
|
||||
|
||||
Bias:
|
||||
|
||||
+10
|
||||
|
||||
Output atteso:
|
||||
|
||||
10
|
||||
N2 — ReLU
|
||||
|
||||
Pesi:
|
||||
|
||||
tutti = -1
|
||||
|
||||
Input:
|
||||
|
||||
tutti = +1
|
||||
|
||||
Il risultato è negativo.
|
||||
|
||||
La ReLU produce:
|
||||
|
||||
0
|
||||
N3 — saturazione
|
||||
|
||||
Pesi:
|
||||
|
||||
primi 32 = +4
|
||||
restanti = 0
|
||||
|
||||
Input:
|
||||
|
||||
tutti = +1
|
||||
|
||||
Risultato:
|
||||
|
||||
32 × 4 = 128
|
||||
|
||||
L'uscita INT8 positiva viene saturata:
|
||||
|
||||
128 → 127
|
||||
7. Risultato simulazione
|
||||
|
||||
Il test è passato con PARALLEL=16:
|
||||
|
||||
PARALLEL = 16
|
||||
|
||||
PASS N0: 32
|
||||
PASS N1: 10
|
||||
PASS N2: 0 (ReLU)
|
||||
PASS N3: 127 (saturation)
|
||||
|
||||
INT8 PARAMETRIC TEST PASSED
|
||||
|
||||
È passato anche con PARALLEL=32:
|
||||
|
||||
PARALLEL = 32
|
||||
|
||||
PASS N0: 32
|
||||
PASS N1: 10
|
||||
PASS N2: 0 (ReLU)
|
||||
PASS N3: 127 (saturation)
|
||||
|
||||
INT8 PARAMETRIC TEST PASSED
|
||||
|
||||
La correttezza funzionale del datapath parametrico è quindi confermata.
|
||||
|
||||
8. Sintesi e Place & Route
|
||||
|
||||
Dopo la simulazione il datapath è stato sintetizzato per ECP5 utilizzando:
|
||||
|
||||
Yosys
|
||||
|
||||
e successivamente piazzato e instradato con:
|
||||
|
||||
nextpnr-ecp5
|
||||
|
||||
Target:
|
||||
|
||||
LFE5U-45F
|
||||
CABGA381
|
||||
Speed grade -8
|
||||
|
||||
Il wrapper di benchmark genera internamente:
|
||||
|
||||
input;
|
||||
pesi;
|
||||
bias;
|
||||
segnali di test.
|
||||
|
||||
In questo modo non vengono portati all'esterno i giganteschi bus del modello neurale.
|
||||
|
||||
Il top-level espone solamente:
|
||||
|
||||
clk
|
||||
rst
|
||||
start
|
||||
y_bus
|
||||
busy
|
||||
done
|
||||
|
||||
Questa modifica è stata fondamentale.
|
||||
|
||||
Il primo tentativo esponeva infatti direttamente:
|
||||
|
||||
x_bus ≈ 2048 bit
|
||||
weights ≈ 8192 bit
|
||||
bias ≈ 32 bit
|
||||
|
||||
portando a oltre 10.000 I/O fisiche richieste.
|
||||
|
||||
Il risultato era:
|
||||
|
||||
TRELLIS_IO: 10309/245
|
||||
|
||||
e quindi un errore di placement.
|
||||
|
||||
Il problema non era la dimensione logica del circuito, ma esclusivamente il numero di I/O.
|
||||
|
||||
9. PARALLEL = 16
|
||||
|
||||
Risorse sintetizzate:
|
||||
|
||||
LUT4 ≈ 2531
|
||||
DFF = 186
|
||||
|
||||
Risorse FPGA:
|
||||
|
||||
MULT18X18D = 64 / 72
|
||||
|
||||
quindi:
|
||||
|
||||
88% dei DSP
|
||||
|
||||
Timing:
|
||||
|
||||
Fmax ≈ 52.13 MHz
|
||||
Tcrit ≈ 19.18 ns
|
||||
|
||||
Il percorso critico risultava fortemente influenzato dal routing.
|
||||
|
||||
Configurazione:
|
||||
|
||||
PARALLEL = 16
|
||||
N_NEURONS = 4
|
||||
|
||||
produce:
|
||||
|
||||
16 × 4 = 64 MAC simultanei
|
||||
10. PARALLEL = 8
|
||||
|
||||
Risorse:
|
||||
|
||||
MULT18X18D = 32 / 72
|
||||
|
||||
quindi:
|
||||
|
||||
32 DSP
|
||||
|
||||
Con quattro neuroni:
|
||||
|
||||
8 × 4 = 32 MAC simultanei
|
||||
|
||||
Timing:
|
||||
|
||||
Fmax ≈ 61.71 MHz
|
||||
Tcrit ≈ 16.20 ns
|
||||
|
||||
Composizione del percorso critico:
|
||||
|
||||
logic ≈ 6.43 ns
|
||||
routing ≈ 9.77 ns
|
||||
total ≈ 16.20 ns
|
||||
|
||||
Questa configurazione è particolarmente importante perché corrisponde esattamente al target originale di:
|
||||
|
||||
32 MAC hardware simultanei
|
||||
11. PARALLEL = 4
|
||||
|
||||
Risorse:
|
||||
|
||||
LUT4 = 804
|
||||
DFF = 194
|
||||
|
||||
MULT18X18D = 16 / 72
|
||||
|
||||
Quindi:
|
||||
|
||||
16 MAC simultanei
|
||||
|
||||
Timing:
|
||||
|
||||
Fmax ≈ 75.01 MHz
|
||||
Tcrit ≈ 13.33 ns
|
||||
|
||||
Composizione:
|
||||
|
||||
logic ≈ 6.67 ns
|
||||
routing ≈ 6.66 ns
|
||||
total ≈ 13.33 ns
|
||||
|
||||
In questa configurazione logica e routing sono quasi perfettamente bilanciati.
|
||||
|
||||
12. PARALLEL = 2
|
||||
|
||||
Risorse:
|
||||
|
||||
LUT4 = 481
|
||||
DFF = 198
|
||||
|
||||
MULT18X18D = 8 / 72
|
||||
|
||||
Quindi:
|
||||
|
||||
8 MAC simultanei
|
||||
|
||||
Timing finale dopo routing:
|
||||
|
||||
Fmax ≈ 87.88 MHz
|
||||
Tcrit ≈ 11.38 ns
|
||||
|
||||
Composizione:
|
||||
|
||||
logic ≈ 6.43 ns
|
||||
routing ≈ 4.95 ns
|
||||
total ≈ 11.38 ns
|
||||
|
||||
Il design è stato quindi verificato con target:
|
||||
|
||||
80 MHz
|
||||
|
||||
ottenendo:
|
||||
|
||||
87.88 MHz
|
||||
|
||||
e:
|
||||
|
||||
PASS
|
||||
|
||||
Il margine teorico rispetto a 80 MHz è:
|
||||
|
||||
T80MHz = 12.50 ns
|
||||
|
||||
12.50 - 11.38 ≈ 1.12 ns
|
||||
13. Tabella comparativa
|
||||
PARALLEL MAC/neurone Neuroni MAC totali DSP Fmax Tcrit 80 MHz
|
||||
16 16 4 64 64 52.13 MHz 19.18 ns FAIL
|
||||
8 8 4 32 32 61.71 MHz 16.20 ns FAIL
|
||||
4 4 4 16 16 75.01 MHz 13.33 ns FAIL
|
||||
2 2 4 8 8 87.88 MHz 11.38 ns PASS
|
||||
14. Interpretazione
|
||||
|
||||
I risultati mostrano chiaramente il trade-off fondamentale.
|
||||
|
||||
Riducendo PARALLEL:
|
||||
|
||||
PARALLEL ↓
|
||||
↓
|
||||
MAC simultanei ↓
|
||||
↓
|
||||
DSP ↓
|
||||
↓
|
||||
adder tree ↓
|
||||
↓
|
||||
routing/congestione ↓
|
||||
↓
|
||||
Fmax ↑
|
||||
|
||||
ma contemporaneamente:
|
||||
|
||||
PARALLEL ↓
|
||||
↓
|
||||
numero gruppi ↑
|
||||
↓
|
||||
cicli necessari ↑
|
||||
↓
|
||||
latenza ↑
|
||||
|
||||
Quindi la frequenza massima non è sufficiente per scegliere la configurazione.
|
||||
|
||||
Occorre considerare il throughput complessivo:
|
||||
|
||||
throughput ≈ MAC_per_cycle × clock_frequency
|
||||
|
||||
A parità di quattro neuroni:
|
||||
|
||||
P2
|
||||
8 MAC × 87.88 MHz
|
||||
≈ 703 M MAC/s
|
||||
P4
|
||||
16 MAC × 75.01 MHz
|
||||
≈ 1.20 G MAC/s
|
||||
P8
|
||||
32 MAC × 61.71 MHz
|
||||
≈ 1.97 G MAC/s
|
||||
P16
|
||||
64 MAC × 52.13 MHz
|
||||
≈ 3.34 G MAC/s
|
||||
|
||||
Questi valori sono una misura teorica del throughput del datapath MAC, non ancora del throughput end-to-end della rete, perché non includono i limiti della memoria esterna, del trasferimento dei pesi e del controller.
|
||||
|
||||
15. Scelta architetturale
|
||||
|
||||
Il risultato più importante del benchmark è che PARALLEL=8 rimane il candidato naturale per l'architettura V1 se l'obiettivo iniziale di progetto è mantenere circa:
|
||||
|
||||
32 MAC simultanei
|
||||
|
||||
Infatti:
|
||||
|
||||
PARALLEL = 8
|
||||
N_NEURONS = 4
|
||||
|
||||
→ 32 MAC
|
||||
→ 32 DSP / 72
|
||||
→ 61.71 MHz
|
||||
|
||||
L'utilizzo DSP è ancora relativamente basso:
|
||||
|
||||
44% circa
|
||||
|
||||
lasciando risorse per:
|
||||
|
||||
controller memoria;
|
||||
buffer;
|
||||
interfaccia SPI;
|
||||
DMA;
|
||||
gestione layer;
|
||||
eventuali pipeline;
|
||||
future funzioni di controllo.
|
||||
|
||||
PARALLEL=2 è invece la configurazione più semplice da temporizzare tra quelle testate:
|
||||
|
||||
87.88 MHz
|
||||
|
||||
e passa il target di 80 MHz.
|
||||
|
||||
Tuttavia richiede:
|
||||
|
||||
128 gruppi
|
||||
|
||||
per elaborare un neurone da 256 ingressi.
|
||||
|
||||
Per questo motivo non è opportuno adottarlo automaticamente come configurazione definitiva solo perché raggiunge la frequenza più elevata.
|
||||
|
||||
16. Timing a 100 MHz
|
||||
|
||||
Il target di:
|
||||
|
||||
100 MHz
|
||||
|
||||
non viene attualmente raggiunto.
|
||||
|
||||
Il miglior risultato è:
|
||||
|
||||
87.88 MHz
|
||||
|
||||
con PARALLEL=2.
|
||||
|
||||
Il percorso critico è ancora:
|
||||
|
||||
weight FF
|
||||
↓
|
||||
MULT18X18D
|
||||
↓
|
||||
products
|
||||
↓
|
||||
adder/carry chain
|
||||
↓
|
||||
acc_next
|
||||
↓
|
||||
ReLU / saturation
|
||||
↓
|
||||
output FF
|
||||
|
||||
Il problema non è quindi un'elevata occupazione delle risorse FPGA.
|
||||
|
||||
Al contrario, con P2 l'FPGA è utilizzato molto poco:
|
||||
|
||||
DSP ≈ 11%
|
||||
LUT ≈ 1%
|
||||
FF ≈ 0%
|
||||
|
||||
Il limite è principalmente temporale e dipende dal datapath combinazionale.
|
||||
|
||||
Per superare 100 MHz sarà probabilmente necessario introdurre una o più pipeline interne.
|
||||
|
||||
Questa ottimizzazione non è però ancora necessaria per procedere con la prossima fase architetturale.
|
||||
|
||||
17. Vincoli LPF
|
||||
|
||||
Durante questi benchmark il file:
|
||||
|
||||
synth/ecp5/top.lpf
|
||||
|
||||
è stato lasciato senza vincoli di pin.
|
||||
|
||||
nextpnr viene eseguito con:
|
||||
|
||||
--lpf-allow-unconstrained
|
||||
|
||||
Pertanto i numerosi warning relativi a I/O non vincolate sono intenzionali.
|
||||
|
||||
Il benchmark verifica quindi:
|
||||
|
||||
sintesi
|
||||
placement
|
||||
routing
|
||||
timing
|
||||
|
||||
e non:
|
||||
|
||||
pin assignment
|
||||
I/O standard della scheda
|
||||
signal integrity
|
||||
|
||||
I vincoli LPF reali verranno aggiunti quando sarà definito il pinout della scheda FPGA-Neural.
|
||||
|
||||
18. Decisione per la prossima fase
|
||||
|
||||
Non è utile proseguire con benchmark PARALLEL=1.
|
||||
|
||||
Il punto di interesse architetturale è già stato individuato.
|
||||
|
||||
La prossima fase deve spostare il progetto dal benchmark sintetico verso l'architettura reale:
|
||||
|
||||
HOST
|
||||
│
|
||||
│ SPI
|
||||
▼
|
||||
FPGA interface
|
||||
│
|
||||
▼
|
||||
Memory interface
|
||||
│
|
||||
┌───────────┴───────────┐
|
||||
▼ ▼
|
||||
PSRAM 8 MB FPGA BRAM
|
||||
│ │
|
||||
└──────────┬────────────┘
|
||||
▼
|
||||
tile/buffer
|
||||
│
|
||||
▼
|
||||
MAC engine
|
||||
│
|
||||
▼
|
||||
accumulator
|
||||
│
|
||||
▼
|
||||
activation
|
||||
│
|
||||
▼
|
||||
output
|
||||
|
||||
Il core layer e neuron_parallel dovrà quindi essere separato dalla memoria fisica attraverso una Memory Interface.
|
||||
|
||||
19. Memoria V1
|
||||
|
||||
La memoria di lavoro prevista è:
|
||||
|
||||
ISSI IS66WVE4M16EBLL-70BLI
|
||||
|
||||
Caratteristiche:
|
||||
|
||||
64 Mbit
|
||||
8 MB
|
||||
4M × 16
|
||||
parallel PSRAM
|
||||
asynchronous/page mode
|
||||
70 ns
|
||||
2.7–3.6 V
|
||||
48-TFBGA
|
||||
6 × 8 mm
|
||||
|
||||
La memoria volatile sarà utilizzata come working memory durante l'inferenza.
|
||||
|
||||
La memoria persistente prevista è:
|
||||
|
||||
Winbond W25Q128JVS
|
||||
|
||||
con:
|
||||
|
||||
128 Mbit
|
||||
16 MB
|
||||
SPI NOR Flash
|
||||
|
||||
La divisione dei ruoli è:
|
||||
|
||||
W25Q128JVS
|
||||
↓
|
||||
persistent storage
|
||||
↓
|
||||
weights
|
||||
biases
|
||||
network metadata
|
||||
FPGA/network configuration
|
||||
|
||||
e:
|
||||
|
||||
IS66WVE4M16EBLL
|
||||
↓
|
||||
runtime working memory
|
||||
↓
|
||||
input/output tensors
|
||||
intermediate data
|
||||
weight tiles
|
||||
|
||||
Infine:
|
||||
|
||||
FPGA BRAM
|
||||
↓
|
||||
local working buffers
|
||||
tiles
|
||||
accumulators
|
||||
20. Conclusioni
|
||||
|
||||
La fase di caratterizzazione del datapath ha prodotto i seguenti risultati:
|
||||
|
||||
Il datapath INT8/INT32 è funzionalmente corretto.
|
||||
Il test parametrico è passato.
|
||||
Il balanced adder tree ha sostituito con successo la precedente riduzione lineare.
|
||||
Il design è sintetizzabile per LFE5U-45F.
|
||||
Il placement e routing sono stati completati correttamente.
|
||||
Il problema iniziale delle migliaia di I/O è stato eliminato spostando i test vector all'interno del wrapper.
|
||||
PARALLEL=8 implementa esattamente 32 MAC simultanei con quattro neuroni.
|
||||
PARALLEL=2 raggiunge 87.88 MHz e supera il target di 80 MHz.
|
||||
Il limite attuale a 100 MHz è dovuto al percorso combinazionale, non alla saturazione delle risorse FPGA.
|
||||
Non è necessario continuare il benchmark verso PARALLEL=1.
|
||||
|
||||
La baseline architetturale rimane quindi:
|
||||
|
||||
LFE5U-45F-8BG381C
|
||||
INT8 / INT32
|
||||
256 inputs
|
||||
4 neurons
|
||||
PARALLEL parametrico
|
||||
|
||||
con:
|
||||
|
||||
PARALLEL = 8
|
||||
|
||||
come candidato principale per la configurazione orientata al throughput e:
|
||||
|
||||
PARALLEL = 2
|
||||
|
||||
come riferimento per la configurazione orientata alla frequenza.
|
||||
|
||||
La prossima attività significativa è l'integrazione della Memory Interface con la PSRAM esterna, mantenendo PARALLEL come parametro del motore computazionale.
|
||||
|
||||
Appendice A — Toolchain
|
||||
Yosys
|
||||
|
||||
Yosys è il tool di sintesi RTL.
|
||||
|
||||
Flusso:
|
||||
|
||||
Verilog RTL
|
||||
↓
|
||||
elaborazione
|
||||
↓
|
||||
ottimizzazione
|
||||
↓
|
||||
mapping ECP5
|
||||
↓
|
||||
JSON netlist
|
||||
|
||||
Versione utilizzata:
|
||||
|
||||
Yosys 0.68+post
|
||||
|
||||
Binary:
|
||||
|
||||
/opt/homebrew/bin/yosys
|
||||
Project Trellis
|
||||
|
||||
Project Trellis fornisce il database open-source dell'architettura ECP5 e gli strumenti necessari all'implementazione.
|
||||
|
||||
Tra gli strumenti disponibili:
|
||||
|
||||
ecppack
|
||||
ecppll
|
||||
ecpbram
|
||||
ecpunpack
|
||||
|
||||
Installazione utilizzata:
|
||||
|
||||
/tmp/prjtrellis/install
|
||||
nextpnr-ecp5
|
||||
|
||||
nextpnr-ecp5 esegue:
|
||||
|
||||
placement
|
||||
routing
|
||||
timing analysis
|
||||
|
||||
Versione:
|
||||
|
||||
nextpnr-0.11.1-19-g8dbcee5
|
||||
|
||||
Binary:
|
||||
|
||||
/tmp/nextpnr/build/nextpnr-ecp5
|
||||
|
||||
Parametri principali:
|
||||
|
||||
--45k
|
||||
|
||||
seleziona LFE5U-45F.
|
||||
|
||||
--package CABGA381
|
||||
|
||||
seleziona il package.
|
||||
|
||||
--speed 8
|
||||
|
||||
seleziona speed grade -8.
|
||||
|
||||
--json
|
||||
|
||||
carica la netlist generata da Yosys.
|
||||
|
||||
--lpf
|
||||
|
||||
carica i vincoli di pin.
|
||||
|
||||
--lpf-allow-unconstrained
|
||||
|
||||
permette I/O non vincolate.
|
||||
|
||||
--freq 80
|
||||
|
||||
richiede un timing target di 80 MHz.
|
||||
|
||||
Icarus Verilog
|
||||
|
||||
Icarus Verilog viene utilizzato per la simulazione RTL.
|
||||
|
||||
Esempio:
|
||||
|
||||
iverilog -g2012 \
|
||||
-Ptb.PARALLEL=16 \
|
||||
-o sim/parametric_256x4_p16 \
|
||||
sim/parametric_tb.v \
|
||||
rtl/mac_unit.v \
|
||||
rtl/mac8.v \
|
||||
rtl/neuron_parallel.v \
|
||||
rtl/layer.v
|
||||
|
||||
Esecuzione:
|
||||
|
||||
vvp sim/parametric_256x4_p16
|
||||
|
||||
Icarus verifica principalmente la correttezza funzionale del RTL.
|
||||
|
||||
Appendice B — Differenza tra simulazione e implementazione
|
||||
Simulazione
|
||||
Icarus Verilog
|
||||
|
||||
verifica:
|
||||
|
||||
algebra signed;
|
||||
prodotti;
|
||||
accumulazione;
|
||||
gruppi;
|
||||
bias;
|
||||
ReLU;
|
||||
saturazione;
|
||||
segnali busy e done.
|
||||
Implementazione
|
||||
Yosys
|
||||
+
|
||||
nextpnr-ecp5
|
||||
|
||||
verifica:
|
||||
|
||||
sintetizzabilità;
|
||||
mapping FPGA;
|
||||
LUT;
|
||||
FF;
|
||||
DSP;
|
||||
placement;
|
||||
routing;
|
||||
timing;
|
||||
Fmax.
|
||||
|
||||
Le due verifiche sono complementari.
|
||||
r
|
||||
Appendice C — Stato attuale
|
||||
RTL funzionale PASS
|
||||
Simulazione parametrica PASS
|
||||
Sintesi ECP5 PASS
|
||||
Placement PASS
|
||||
Routing PASS
|
||||
|
||||
PARALLEL=16 52.13 MHz
|
||||
PARALLEL=8 61.71 MHz
|
||||
PARALLEL=4 75.01 MHz
|
||||
PARALLEL=2 87.88 MHz
|
||||
|
||||
Target 80 MHz, P2 PASS
|
||||
Target 100 MHz FAIL
|
||||
|
||||
Memory Interface DA IMPLEMENTARE
|
||||
PSRAM controller DA IMPLEMENTARE
|
||||
Host SPI interface DA IMPLEMENTARE
|
||||
Layer engine reale PROSSIMA FASE
|
||||
@@ -0,0 +1,735 @@
|
||||
# FPGA Neural Network Engine
|
||||
|
||||
Hardware Neural Network Engine based on FPGA + dedicated RAM.
|
||||
|
||||
The project implements a **parametric hardware accelerator for neural networks**, designed to be reusable across different embedded systems and applications.
|
||||
|
||||
The fundamental design principle is that the neural-network computation is performed entirely inside the FPGA, while the host system communicates with the engine through a simple hardware-independent interface such as SPI.
|
||||
|
||||
---
|
||||
|
||||
## 1. Project Goal
|
||||
|
||||
The goal of this project is to develop a reusable **Neural Network Engine implemented in FPGA hardware**.
|
||||
|
||||
The engine is composed of:
|
||||
|
||||
- FPGA;
|
||||
- dedicated RAM connected to the FPGA;
|
||||
- host interface, initially SPI and potentially Dual SPI.
|
||||
|
||||
The host system is not part of the neural-network computational datapath.
|
||||
|
||||
Possible host systems include:
|
||||
|
||||
- Linux SoCs;
|
||||
- Raspberry-Pi-like systems;
|
||||
- ESP32;
|
||||
- microcontrollers;
|
||||
- other embedded processors;
|
||||
- development PCs.
|
||||
|
||||
The same Neural Network Engine architecture should therefore be usable in completely different systems.
|
||||
|
||||
```text
|
||||
HOST SYSTEM
|
||||
┌─────────────────────────┐
|
||||
│ │
|
||||
│ Linux / ESP32 / MCU │
|
||||
│ │
|
||||
│ Configuration │
|
||||
│ Training │
|
||||
│ Control │
|
||||
└────────────┬────────────┘
|
||||
│
|
||||
SPI / Dual SPI
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ FPGA │
|
||||
│ │
|
||||
│ Neural Network Engine │
|
||||
│ │
|
||||
│ Compute / Control │
|
||||
│ │
|
||||
└────────────┬────────────┘
|
||||
│
|
||||
│
|
||||
Dedicated RAM
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2. Architectural Principle
|
||||
|
||||
The FPGA is the actual neural-network accelerator.
|
||||
|
||||
The RAM required by the neural network is physically associated with the FPGA and is **not part of the host system memory**.
|
||||
|
||||
The host only provides:
|
||||
|
||||
- configuration;
|
||||
- network parameters;
|
||||
- input data;
|
||||
- control;
|
||||
- result retrieval.
|
||||
|
||||
The neural-network calculations themselves are executed by the FPGA.
|
||||
|
||||
This separation is a fundamental architectural requirement.
|
||||
|
||||
---
|
||||
|
||||
# 3. Hardware Configuration vs Network Configuration
|
||||
|
||||
An important distinction is made between the **hardware architecture of the accelerator** and the **parameters of the neural network**.
|
||||
|
||||
## 3.1 FPGA hardware configuration
|
||||
|
||||
The physical architecture of the Neural Network Engine is defined when the FPGA design is synthesized and implemented.
|
||||
|
||||
Typical hardware parameters include:
|
||||
|
||||
```text
|
||||
N_INPUTS
|
||||
N_NEURONS
|
||||
N_LAYERS
|
||||
PARALLEL
|
||||
DATA_WIDTH
|
||||
ACCUMULATOR_WIDTH
|
||||
```
|
||||
|
||||
These parameters can therefore be Verilog/SystemVerilog parameters or equivalent synthesis-time configuration values.
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
N_INPUTS = 32
|
||||
N_NEURONS = 4
|
||||
PARALLEL = 8
|
||||
```
|
||||
|
||||
defines a specific hardware implementation optimized for that architecture.
|
||||
|
||||
The resulting FPGA bitstream contains the corresponding datapath.
|
||||
|
||||
---
|
||||
|
||||
## 3.2 Neural-network configuration
|
||||
|
||||
Once the FPGA has been configured and initialized, the actual neural-network parameters can be loaded through the host interface.
|
||||
|
||||
These parameters may include:
|
||||
|
||||
- weights;
|
||||
- biases;
|
||||
- activation parameters;
|
||||
- quantization parameters;
|
||||
- network-specific constants.
|
||||
|
||||
These values are stored in the RAM associated with the FPGA.
|
||||
|
||||
Therefore:
|
||||
|
||||
```text
|
||||
FPGA BITSTREAM
|
||||
│
|
||||
│ defines hardware architecture
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ Neural Network │
|
||||
│ Hardware Engine │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
│ loads
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ Dedicated RAM │
|
||||
│ │
|
||||
│ weights │
|
||||
│ biases │
|
||||
│ parameters │
|
||||
│ buffers │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
This provides an important separation between **hardware specialization** and **network data**.
|
||||
|
||||
---
|
||||
|
||||
# 4. Application-Specific Neural Networks
|
||||
|
||||
The Neural Network Engine is not intended to implement one fixed neural network.
|
||||
|
||||
Instead, each application can define its own network.
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
Application A
|
||||
16 inputs
|
||||
8 neurons
|
||||
1 output
|
||||
|
||||
Application B
|
||||
32 inputs
|
||||
16 neurons
|
||||
4 outputs
|
||||
|
||||
Application C
|
||||
64 inputs
|
||||
multiple layers
|
||||
custom parallelism
|
||||
```
|
||||
|
||||
The FPGA hardware can then be generated specifically for the required architecture.
|
||||
|
||||
This allows the design to exploit the FPGA resources efficiently rather than implementing a completely generic and potentially inefficient neural-network processor.
|
||||
|
||||
---
|
||||
|
||||
# 5. Parametric Compute Engine
|
||||
|
||||
The current implementation contains a parametric neural-network layer.
|
||||
|
||||
A validated configuration is:
|
||||
|
||||
```text
|
||||
N_INPUTS = 32
|
||||
N_NEURONS = 4
|
||||
PARALLEL = 8
|
||||
```
|
||||
|
||||
The datapath processes the inputs in parallel groups.
|
||||
|
||||
Conceptually:
|
||||
|
||||
```text
|
||||
32 inputs
|
||||
│
|
||||
├── 8 parallel MACs
|
||||
│
|
||||
├── 8 parallel MACs
|
||||
│
|
||||
├── 8 parallel MACs
|
||||
│
|
||||
└── 8 parallel MACs
|
||||
│
|
||||
▼
|
||||
Accumulation
|
||||
│
|
||||
▼
|
||||
Bias
|
||||
│
|
||||
▼
|
||||
Activation
|
||||
│
|
||||
▼
|
||||
Output
|
||||
```
|
||||
|
||||
The architecture is intended to scale by changing the synthesis parameters.
|
||||
|
||||
---
|
||||
|
||||
# 6. Current Functional Validation
|
||||
|
||||
The `32 × 4 / PARALLEL = 8` configuration has been successfully simulated.
|
||||
|
||||
Test output:
|
||||
|
||||
```text
|
||||
========================================
|
||||
PARAMETRIC LAYER TEST
|
||||
N_INPUTS = 32
|
||||
N_NEURONS = 4
|
||||
PARALLEL = 8
|
||||
========================================
|
||||
|
||||
PASS N0: 8192
|
||||
PASS N1: 4096
|
||||
PASS N2: 0 (ReLU)
|
||||
PASS N3: 16384
|
||||
|
||||
========================================
|
||||
PARAMETRIC TEST PASSED
|
||||
========================================
|
||||
```
|
||||
|
||||
Validated functionality:
|
||||
|
||||
- multiple inputs;
|
||||
- multiple neurons;
|
||||
- parallel MAC processing;
|
||||
- accumulation across multiple input groups;
|
||||
- bias handling;
|
||||
- independent neuron outputs;
|
||||
- ReLU activation;
|
||||
- parametric layer architecture.
|
||||
|
||||
The corresponding test has been committed to the repository.
|
||||
|
||||
Commit:
|
||||
|
||||
```text
|
||||
test: validate parametric 32x4 layer with parallelism 8
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 7. FPGA Boot and Initialization
|
||||
|
||||
The FPGA is configured during system initialization using its normal FPGA configuration mechanism.
|
||||
|
||||
The FPGA bitstream defines the hardware architecture of the Neural Network Engine.
|
||||
|
||||
Conceptually:
|
||||
|
||||
```text
|
||||
Power-on
|
||||
│
|
||||
▼
|
||||
FPGA configuration
|
||||
│
|
||||
│ bitstream
|
||||
▼
|
||||
Neural Network Engine available
|
||||
│
|
||||
▼
|
||||
Host initialization
|
||||
│
|
||||
│ SPI
|
||||
▼
|
||||
Load network parameters
|
||||
│
|
||||
▼
|
||||
Load weights / biases
|
||||
│
|
||||
▼
|
||||
Engine ready
|
||||
```
|
||||
|
||||
This means that the host does **not dynamically construct the FPGA datapath** during normal operation.
|
||||
|
||||
The datapath already exists in hardware.
|
||||
|
||||
The host configures the network data that the datapath operates on.
|
||||
|
||||
---
|
||||
|
||||
# 8. Host Interface
|
||||
|
||||
The primary external interface is intended to be:
|
||||
|
||||
```text
|
||||
SPI
|
||||
```
|
||||
|
||||
with possible future support for:
|
||||
|
||||
```text
|
||||
Dual SPI
|
||||
```
|
||||
|
||||
The interface must remain independent of the host operating system.
|
||||
|
||||
The same hardware protocol should therefore be usable from:
|
||||
|
||||
```text
|
||||
Linux
|
||||
ESP32
|
||||
MCU
|
||||
PC
|
||||
```
|
||||
|
||||
The host interface should provide access to:
|
||||
|
||||
- control registers;
|
||||
- status;
|
||||
- network configuration;
|
||||
- RAM;
|
||||
- input data;
|
||||
- output data;
|
||||
- start/stop control;
|
||||
- completion status.
|
||||
|
||||
A conceptual command sequence is:
|
||||
|
||||
```text
|
||||
RESET
|
||||
│
|
||||
▼
|
||||
CONFIGURE
|
||||
│
|
||||
▼
|
||||
LOAD NETWORK PARAMETERS
|
||||
│
|
||||
▼
|
||||
LOAD WEIGHTS
|
||||
│
|
||||
▼
|
||||
LOAD BIASES
|
||||
│
|
||||
▼
|
||||
LOAD INPUT
|
||||
│
|
||||
▼
|
||||
START
|
||||
│
|
||||
▼
|
||||
WAIT FOR DONE
|
||||
│
|
||||
▼
|
||||
READ OUTPUT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 9. Dedicated FPGA RAM
|
||||
|
||||
The RAM is considered part of the Neural Network Engine.
|
||||
|
||||
It is not intended to be supplied by the host system.
|
||||
|
||||
Depending on the final architecture, RAM may contain:
|
||||
|
||||
```text
|
||||
Weights
|
||||
Biases
|
||||
Input buffers
|
||||
Intermediate layer buffers
|
||||
Output buffers
|
||||
Network parameters
|
||||
```
|
||||
|
||||
The memory architecture must be designed according to:
|
||||
|
||||
- number of parallel MAC units;
|
||||
- data width;
|
||||
- required bandwidth;
|
||||
- number of layers;
|
||||
- buffering requirements;
|
||||
- FPGA block-RAM resources;
|
||||
- possible external RAM requirements.
|
||||
|
||||
The preferred architecture is that the FPGA directly controls this memory.
|
||||
|
||||
---
|
||||
|
||||
# 10. Training
|
||||
|
||||
Training and inference are conceptually separated.
|
||||
|
||||
The first implementation does not require the FPGA to perform the complete training process.
|
||||
|
||||
Training can be performed externally:
|
||||
|
||||
```text
|
||||
PC / Linux / other host
|
||||
│
|
||||
│ training
|
||||
▼
|
||||
Network weights
|
||||
│
|
||||
│ SPI
|
||||
▼
|
||||
FPGA RAM
|
||||
```
|
||||
|
||||
The FPGA then performs inference using the resulting parameters.
|
||||
|
||||
This approach greatly reduces the complexity of the initial hardware implementation.
|
||||
|
||||
However, the architecture should not prevent future implementation of hardware-assisted or fully hardware-based training.
|
||||
|
||||
---
|
||||
|
||||
# 11. Inference
|
||||
|
||||
During inference, the host only supplies input data and retrieves the result.
|
||||
|
||||
```text
|
||||
HOST
|
||||
│
|
||||
Input
|
||||
│
|
||||
│ SPI
|
||||
▼
|
||||
┌───────────────┐
|
||||
│ FPGA │
|
||||
│ │
|
||||
│ Neural Network│
|
||||
│ Engine │
|
||||
│ │
|
||||
└───────┬───────┘
|
||||
│
|
||||
Output
|
||||
│
|
||||
│ SPI
|
||||
▼
|
||||
HOST
|
||||
```
|
||||
|
||||
The host is not involved in the individual MAC operations.
|
||||
|
||||
This provides:
|
||||
|
||||
- deterministic computation;
|
||||
- reduced host workload;
|
||||
- hardware parallelism;
|
||||
- predictable latency;
|
||||
- independence from the host CPU architecture.
|
||||
|
||||
---
|
||||
|
||||
# 12. Multi-Layer Architecture
|
||||
|
||||
The current implementation starts from a single parametrized layer.
|
||||
|
||||
The intended architecture is eventually:
|
||||
|
||||
```text
|
||||
Input
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Layer 0 │
|
||||
└──────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Layer 1 │
|
||||
└──────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Layer 2 │
|
||||
└──────┬───────┘
|
||||
│
|
||||
▼
|
||||
Output
|
||||
```
|
||||
|
||||
Intermediate data will be stored in FPGA-controlled memory buffers.
|
||||
|
||||
The number and size of layers should ultimately be part of the hardware generation process.
|
||||
|
||||
---
|
||||
|
||||
# 13. Reusability
|
||||
|
||||
The main purpose of the architecture is reuse.
|
||||
|
||||
A future project should be able to use the same general Neural Network Engine architecture with a different hardware configuration.
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
Project A
|
||||
N_INPUTS = 32
|
||||
N_NEURONS = 8
|
||||
PARALLEL = 8
|
||||
|
||||
Project B
|
||||
N_INPUTS = 64
|
||||
N_NEURONS = 16
|
||||
PARALLEL = 16
|
||||
|
||||
Project C
|
||||
N_INPUTS = 128
|
||||
N_NEURONS = 32
|
||||
PARALLEL = 32
|
||||
```
|
||||
|
||||
The HDL architecture remains conceptually the same while synthesis parameters generate an implementation appropriate for the target application.
|
||||
|
||||
---
|
||||
|
||||
# 14. Design Philosophy
|
||||
|
||||
The project should be considered a:
|
||||
|
||||
> **Reusable FPGA Neural Network Accelerator Platform**
|
||||
|
||||
rather than a single neural-network implementation.
|
||||
|
||||
The application determines:
|
||||
|
||||
```text
|
||||
Input size
|
||||
Network topology
|
||||
Number of layers
|
||||
Number of neurons
|
||||
Parallelism
|
||||
Numerical precision
|
||||
Activation functions
|
||||
Memory requirements
|
||||
Performance requirements
|
||||
```
|
||||
|
||||
The hardware generator then produces the corresponding FPGA implementation.
|
||||
|
||||
---
|
||||
|
||||
# 15. Development Roadmap
|
||||
|
||||
## Phase 1 — Parametric Layer
|
||||
|
||||
- [x] Parametric inputs
|
||||
- [x] Parametric neurons
|
||||
- [x] Parametric parallelism
|
||||
- [x] Accumulation
|
||||
- [x] Bias
|
||||
- [x] ReLU
|
||||
- [x] 32×4 / P=8 functional test
|
||||
|
||||
## Phase 2 — Parameter Sweep
|
||||
|
||||
Validate multiple combinations of:
|
||||
|
||||
```text
|
||||
N_INPUTS
|
||||
N_NEURONS
|
||||
PARALLEL
|
||||
```
|
||||
|
||||
including configurations where the number of inputs is not an exact multiple of the parallelism.
|
||||
|
||||
## Phase 3 — Memory Architecture
|
||||
|
||||
Define:
|
||||
|
||||
- weight memory;
|
||||
- bias memory;
|
||||
- input buffers;
|
||||
- output buffers;
|
||||
- intermediate buffers;
|
||||
- memory addressing;
|
||||
- bandwidth requirements.
|
||||
|
||||
## Phase 4 — SPI Interface
|
||||
|
||||
Implement:
|
||||
|
||||
- SPI controller;
|
||||
- register map;
|
||||
- RAM access;
|
||||
- configuration protocol;
|
||||
- input/output protocol;
|
||||
- status and control.
|
||||
|
||||
## Phase 5 — Multi-Layer Network
|
||||
|
||||
Implement:
|
||||
|
||||
- multiple layers;
|
||||
- intermediate buffers;
|
||||
- layer sequencing;
|
||||
- configurable activation functions.
|
||||
|
||||
## Phase 6 — Host Software
|
||||
|
||||
Develop host-side drivers for:
|
||||
|
||||
- Linux;
|
||||
- ESP32.
|
||||
|
||||
The same FPGA protocol should be usable by both.
|
||||
|
||||
## Phase 7 — Optimization
|
||||
|
||||
Evaluate:
|
||||
|
||||
- pipeline depth;
|
||||
- MAC parallelism;
|
||||
- memory bandwidth;
|
||||
- numerical precision;
|
||||
- FPGA resource utilization;
|
||||
- latency;
|
||||
- throughput.
|
||||
|
||||
## Phase 8 — Optional Hardware Training
|
||||
|
||||
Investigate:
|
||||
|
||||
- backpropagation;
|
||||
- gradient calculation;
|
||||
- weight updates;
|
||||
- hardware-assisted training.
|
||||
|
||||
---
|
||||
|
||||
# 16. Long-Term Vision
|
||||
|
||||
The final objective is to create a reusable hardware block that can be integrated into different future MIKILAB projects.
|
||||
|
||||
```text
|
||||
APPLICATION
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
Linux ESP32
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
│
|
||||
SPI / Dual SPI
|
||||
│
|
||||
▼
|
||||
┌────────────────────────┐
|
||||
│ FPGA │
|
||||
│ │
|
||||
│ Neural Network Engine │
|
||||
│ │
|
||||
│ ┌────────────────────┐ │
|
||||
│ │ Control │ │
|
||||
│ ├────────────────────┤ │
|
||||
│ │ Input Interface │ │
|
||||
│ ├────────────────────┤ │
|
||||
│ │ NN Compute Core │ │
|
||||
│ ├────────────────────┤ │
|
||||
│ │ Activation │ │
|
||||
│ ├────────────────────┤ │
|
||||
│ │ Output Interface │ │
|
||||
│ └────────────────────┘ │
|
||||
│ │
|
||||
│ Dedicated RAM │
|
||||
│ │
|
||||
└────────────────────────┘
|
||||
```
|
||||
|
||||
The host platform can change without changing the fundamental Neural Network Engine architecture.
|
||||
|
||||
The FPGA becomes a dedicated neural-computation peripheral, analogous to other hardware accelerators, but optimized specifically for the neural-network topology required by each application.
|
||||
|
||||
---
|
||||
|
||||
# 17. Current Status
|
||||
|
||||
| Component | Status |
|
||||
|---|---|
|
||||
| Parametric neuron layer | OK Working |
|
||||
| Parametric input count | OK |
|
||||
| Parametric neuron count | OK |
|
||||
| Parametric parallelism | OK |
|
||||
| Accumulation | OK |
|
||||
| Bias | OK |
|
||||
| ReLU | OK |
|
||||
| 32×4 / P=8 validation | OK |
|
||||
| Dedicated RAM architecture | - Design |
|
||||
| SPI interface | Planned |
|
||||
| Dual SPI | Future |
|
||||
| Multi-layer engine | Planned |
|
||||
| Linux host driver | Planned |
|
||||
| ESP32 host driver | Planned |
|
||||
| Hardware training | Future |
|
||||
|
||||
---
|
||||
|
||||
## Core architectural principle
|
||||
|
||||
**The FPGA implements the neural-network machine.
|
||||
The FPGA owns its RAM.
|
||||
The host configures and uses the machine.
|
||||
The network topology is specialized at FPGA build time, while its trained parameters are loaded into FPGA-local memory at initialization.**
|
||||
|
||||
This separation is the foundation of the project.
|
||||
Reference in New Issue
Block a user