working with memory

This commit is contained in:
2026-09-02 13:09:20 +02:00
parent d4ae2417a4
commit 16769eaa4b
40 changed files with 1263404 additions and 3560 deletions
+929
View File
@@ -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.73.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
+735
View File
@@ -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.