Three chapters (docs/latex/), sourced from the real project docs (BOM.md, PHYSICAL_REALIZATION.md, ARCHITECTURE_ANALYSIS.md, experiments.log) -- no invented numbers: - hardware.tex: board components, DDR3/FPGA/flash/ESP32, real pinout, SPI protocol, boot procedure. - architecture.tex: packed INT8 MAC core, N=8 hybrid systolic architecture (shared-weight broadcast), hierarchical arbiter, result writeback, why N=8 is the DDR3-bandwidth-bound sweet spot. - tests_timing.tex: verification methodology, real functional test results table, full real P&R signoff history (N=2 through N=16), the definitive N=8 signoff (WNS=0.000ns), and an honestly-caveated ESP32-S3 comparison (real historical ECP5 measurement vs. the superseded, never-verified Artix-7 projection). main.tex ties the three together as report chapters. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUG92aM9m68TRc4rG55BcC
291 lines
11 KiB
TeX
291 lines
11 KiB
TeX
\chapter{Descrizione hardware}
|
|
\label{chap:hardware}
|
|
|
|
\section{Panoramica della scheda}
|
|
|
|
Il progetto realizza un acceleratore neurale su una scheda custom
|
|
(non una dev-board commerciale), basata su un componente FPGA nudo
|
|
Xilinx Artix-7, affiancato da memoria DDR3 reale, una flash di
|
|
configurazione dedicata e un microcontrollore ESP32 come processore
|
|
host/centrale. La scheda non utilizza moduli di sviluppo preassemblati:
|
|
ogni parte è stata scelta, verificata in reperibilità reale (LCSC) e
|
|
posizionata pin-per-pin a partire da un vero place-and-route Vivado,
|
|
non da valori stimati.
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{lll}
|
|
\toprule
|
|
\textbf{Componente} & \textbf{Parte} & \textbf{Note} \\
|
|
\midrule
|
|
FPGA & XC7A100T-CSG324-2 & Speed grade $-2$ \\
|
|
DDR3 SDRAM & 2$\times$ Micron MT41J128M16JT-125:K & 2Gb, x16, canale fisico a 32 bit \\
|
|
Flash di configurazione & Winbond W25Q32JVSSIQ & 32Mbit, SOIC-8, esclusiva della FPGA \\
|
|
Host / processore centrale & ESP32-S3-WROOM-1-N16R8 & 16MB flash, 8MB PSRAM \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Componenti principali, tutti verificati realmente reperibili su LCSC.}
|
|
\end{table}
|
|
|
|
\section{FPGA: Xilinx XC7A100T-CSG324-2}
|
|
|
|
Il componente centrale è un Artix-7 XC7A100T, package CSG324 (324 BGA),
|
|
speed grade $-2$. La scelta dello speed grade $-2$ (corretta rispetto
|
|
a un'ipotesi iniziale $-1$) non comporta alcuna differenza di die,
|
|
package o footprint: offre solamente un margine di timing strettamente
|
|
migliore, confermato dai reali segni di place-and-route (Capitolo~\ref{chap:tests}).
|
|
|
|
Risorse rilevanti utilizzate dal design (target reale N=8,
|
|
Capitolo~\ref{chap:architecture}):
|
|
|
|
\begin{itemize}
|
|
\item 240 DSP48E1 totali disponibili; 64 utilizzati (26.7\%).
|
|
\item 63400 LUT disponibili; 12535 utilizzate (19.77\%).
|
|
\item 126800 registri disponibili; 19902 utilizzati (15.70\%).
|
|
\item Nessuna BRAM utilizzata.
|
|
\end{itemize}
|
|
|
|
\section{Memoria DDR3}
|
|
|
|
Il canale DDR3 è realizzato con due chip Micron
|
|
MT41J128M16JT-125:K (2Gb, x16, DDR3-1600) collegati in parallelo,
|
|
formando un canale fisico reale a \textbf{32 bit} (bus dati raddoppiato
|
|
rispetto alla configurazione iniziale a 16 bit di un solo chip). Le linee
|
|
di indirizzo/comando/controllo sono condivise e distribuite
|
|
identicamente a entrambi i chip; le linee DQ/DQS/DM sono invece divise
|
|
16 bit per chip.
|
|
|
|
Il canale DDR3 è pilotato dal MIG (Memory Interface Generator) di
|
|
Xilinx, generato realmente per questo esatto part number. I due
|
|
domini di clock reali coinvolti sono:
|
|
|
|
\begin{itemize}
|
|
\item \textbf{sys\_clk\_p/n} --- clock differenziale della PHY
|
|
DDR3, \textbf{310.078\,MHz} (periodo 3.225\,ns).
|
|
\item \textbf{ui\_clk / clk\_pll\_i} --- dominio di calcolo interno,
|
|
derivato dal PLL del MIG con rapporto 2:1 dal clock PHY,
|
|
\textbf{155.039\,MHz}. Tutta la logica neurale (Director, arbitraggio,
|
|
PE) gira in questo dominio.
|
|
\end{itemize}
|
|
|
|
Questa combinazione di frequenze non è una scelta libera: è l'unica
|
|
uscita reale del calcolatore JEDEC/PLL del wizard MIG di Vivado per
|
|
questo speed grade e questa larghezza di canale, e determina
|
|
direttamente il vincolo di temporizzazione usato in ogni place-and-route
|
|
reale del progetto (Capitolo~\ref{chap:tests}).
|
|
|
|
\subsection{Convenzione di indirizzamento in DDR3}
|
|
|
|
Pesi e attivazioni condividono lo stesso spazio di indirizzi DDR3,
|
|
indirizzato a parola. La parola nativa è a 32 bit
|
|
(\texttt{BURST\_LEN=8} per transazione, cio\`e 256 bit/burst).
|
|
|
|
\begin{itemize}
|
|
\item \textbf{Pesi}: l'insieme di pesi di un layer parte all'indirizzo
|
|
parola \texttt{layer\_index * WORDS\_PER\_LAYER}, letto in burst
|
|
sequenziali in un buffer on-chip una sola volta per job (riuso reale
|
|
attraverso pi\`u posizioni).
|
|
\item \textbf{Attivazioni}: quattro tile consecutivi (8 valori INT8
|
|
ciascuno) condividono un solo burst da 256 bit; la selezione del
|
|
quarto di burst \`e latenziata al momento della richiesta (non un
|
|
multiplexer indicizzato a runtime), preservando il margine di
|
|
temporizzazione.
|
|
\end{itemize}
|
|
|
|
\section{Flash di configurazione}
|
|
|
|
Una Winbond W25Q32JVSSIQ (32Mbit / 4MB, SOIC-8) ospita il bitstream
|
|
di configurazione (circa 30.5Mbit per un XC7A100T pieno) ed \`e
|
|
collegata \textbf{esclusivamente} alla FPGA --- l'ESP32 non ha alcun
|
|
collegamento elettrico diretto ad essa. L'unico percorso elettrico
|
|
dall'ESP32 alla flash \`e un relay software attraverso la FPGA
|
|
(opcode SPI \texttt{0x40 FLASH\_XFER}, \S\ref{sec:spi-protocol}).
|
|
|
|
\section{Host: ESP32-S3}
|
|
|
|
Il processore host \`e un modulo ESP32-S3-WROOM-1-N16R8 (16MB flash,
|
|
8MB PSRAM, dual-core), verificato realmente reperibile su LCSC. Comunica
|
|
con la FPGA tramite un bus SPI dedicato dove la \textbf{FPGA \`e
|
|
slave}, e --- tramite la FPGA come relay --- raggiunge la flash di
|
|
configurazione su un secondo bus SPI fisicamente distinto dove la
|
|
\textbf{FPGA \`e master}.
|
|
|
|
\section{Assegnazione dei pin (reale, dal design instradato)}
|
|
|
|
Tutti i pin elencati sotto provengono da un vero file di vincoli
|
|
generato da Vivado (XDC), non da valori ipotizzati.
|
|
|
|
\subsection{DDR3 (fissati dall'hardware PHY della FPGA)}
|
|
|
|
I pin DDR3 sono generati dal wizard MIG e non sono una scelta libera:
|
|
banchi \textbf{34/35}, standard \texttt{SSTL15}/\texttt{DIFF\_SSTL15}
|
|
(1.5V). Il clock di riferimento differenziale \texttt{clk\_ref\_p/n}
|
|
vive necessariamente nel \textbf{banco 14} (regola di piazzamento
|
|
UG586 del wizard per questo package), a \textbf{2.5V} (\texttt{LVDS\_25}) ---
|
|
un vincolo che ha richiesto lo spostamento del bus SPI della flash
|
|
(si veda sotto), poich\'e un banco pu\`o avere una sola tensione VCCO.
|
|
|
|
\subsection{SPI di gestione (ESP32 $\leftrightarrow$ FPGA, FPGA slave)}
|
|
|
|
Banco 15, colonna di bordo del package (tracce corte), \texttt{LVCMOS33}:
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{lll}
|
|
\toprule
|
|
\textbf{Segnale} & \textbf{Pin} & \textbf{Direzione (lato FPGA)} \\
|
|
\midrule
|
|
sclk & A15 & input \\
|
|
mosi & B16 & input \\
|
|
miso & B17 & output \\
|
|
cs\_n & A16 & input \\
|
|
sys\_rst & G13 & input (pin provvisorio) \\
|
|
data\_ready\_n & D14 & output (IRQ sticky attivo-basso) \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Pinout del bus SPI di gestione, banco 15, VCCO assunto 3.3V.}
|
|
\end{table}
|
|
|
|
\subsection{SPI della flash di configurazione (FPGA $\leftrightarrow$ flash, FPGA master)}
|
|
|
|
Originariamente sui pin dedicati di configurazione Master-SPI della
|
|
FPGA (banco 14); spostati nel \textbf{banco 16} per risolvere un
|
|
conflitto reale di VCCO con \texttt{clk\_ref} (rilevato da un vero
|
|
fallimento di \texttt{place\_design}, non ipotizzato):
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{llll}
|
|
\toprule
|
|
\textbf{Segnale} & \textbf{Pin} & \textbf{Direzione} & \textbf{Note} \\
|
|
\midrule
|
|
flash\_mosi & D9 & output & banco 16 (era K17, banco 14) \\
|
|
flash\_miso & D10 & input & banco 16 (era K18, banco 14) \\
|
|
flash\_cs\_n & C9 & output & banco 16 (era L13, banco 14) \\
|
|
(CCLK) & E9 & output & pilotato internamente via \texttt{STARTUPE2} \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Pinout del bus SPI della flash, banco 16, VCCO 3.3V.}
|
|
\end{table}
|
|
|
|
\subsection{Controllo di configurazione FPGA (banco 0, non negoziabile)}
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{ll}
|
|
\toprule
|
|
\textbf{Segnale} & \textbf{Pin} \\
|
|
\midrule
|
|
PROGRAM\_B & P9 \\
|
|
INIT\_B & P7 \\
|
|
DONE & P10 \\
|
|
M0 / M1 / M2 & P12 / P13 / P11 \\
|
|
CFGBVS & P8 \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\end{table}
|
|
|
|
Per il boot autonomo da Master SPI: \texttt{M[2:0] = 001}.
|
|
|
|
\subsection{JTAG}
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{ll}
|
|
\toprule
|
|
\textbf{Segnale} & \textbf{Pin} \\
|
|
\midrule
|
|
TCK & E10 \\
|
|
TDI & E11 \\
|
|
TMS & E12 \\
|
|
TDO & E13 \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\end{table}
|
|
|
|
Usato per la programmazione di fabbrica/recupero quando la flash \`e
|
|
vuota, e per debug --- pilotato via bit-banging da firmware ESP32
|
|
(non ancora implementato, lavoro software separato).
|
|
|
|
\section{Alimentazione (stato di avanzamento)}
|
|
|
|
La ricerca dei componenti di alimentazione \`e parziale e onestamente
|
|
dichiarata incompleta:
|
|
|
|
\begin{itemize}
|
|
\item \textbf{VCCINT} (1.0V, alimentazione core FPGA): candidato
|
|
reale identificato, Infineon IR38060 (SupIRBuck integrato, fino a
|
|
6A) --- \textbf{stock non confermato}.
|
|
\item \textbf{VTT} (terminazione DDR3, opzionale): candidato reale
|
|
TI TPS51200 --- la necessit\`a effettiva dipende dalla lunghezza
|
|
reale delle tracce sul layout, non ancora stabilita da questo
|
|
progetto (nessuna simulazione di signal integrity eseguita).
|
|
\item \textbf{VCCAUX (1.8V) e VCCO per banco} (1.5V banchi 34/35,
|
|
2.5V banco 14, 3.3V banchi 15/16): \textbf{non ancora ricercati}.
|
|
\end{itemize}
|
|
|
|
\section{Oscillatori di clock}
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{lll}
|
|
\toprule
|
|
\textbf{Segnale} & \textbf{Frequenza richiesta} & \textbf{Stato} \\
|
|
\midrule
|
|
sys\_clk\_p/n & 310.077\,MHz differenziale & Nessun SKU a catalogo a questa
|
|
esatta frequenza; candidato reale SiTime SiT9122 (oscillatore MEMS
|
|
programmabile 220--625\,MHz) --- richiede un ordine a specifica, non
|
|
ancora confermato in stock. \\
|
|
clk\_ref\_p/n & 200\,MHz differenziale LVDS & \textbf{Confermato reale,
|
|
in stock}: SiTime SiT9121AC-2CF-33E-200.00000, LCSC C835051. \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\end{table}
|
|
|
|
\section{Protocollo SPI di gestione (per il firmware ESP32)}
|
|
\label{sec:spi-protocol}
|
|
|
|
Un byte di opcode (MSB-first) per transazione CS-basso, gestito da
|
|
\texttt{spi\_host\_bridge\_v3.v}:
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{lp{2.3cm}p{3.5cm}p{5cm}}
|
|
\toprule
|
|
\textbf{Opcode} & \textbf{Nome} & \textbf{Payload} & \textbf{Scopo} \\
|
|
\midrule
|
|
0x00 & NOP & 0 byte & inerte \\
|
|
0x0F & RESET & 0 byte & soft-reset \\
|
|
0x10 & WRITE\_JOB & 16 byte & sottomette un job di inferenza \\
|
|
0x20 & STATUS & 0 $\to$ 1 byte & bit di stato (busy, ultimo job accettato) \\
|
|
0x01 & WRITE\_MEM & $4+2N$ byte & scrittura raw in DDR3 ($N$ parole) \\
|
|
0x02 & READ\_MEM & 6 $\to$ 2$N$ byte & lettura raw da DDR3 ($N$ parole) \\
|
|
0x30 & REG\_WRITE & 5 byte & scrive un registro di controllo \\
|
|
0x31 & REG\_READ & 1 $\to$ 4 byte & legge un registro di stato/ID \\
|
|
0x40 & FLASH\_XFER & $N \to N{+}2$ byte & passthrough grezzo verso la flash \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Riepilogo del protocollo SPI di gestione. Il layout completo dei campi \`e documentato nell'intestazione di \texttt{spi\_host\_bridge\_v3.v}.}
|
|
\end{table}
|
|
|
|
Un pin dedicato \texttt{data\_ready\_n} (attivo-basso, sticky) permette
|
|
all'ESP32 di essere interrupt-driven invece di eseguire polling
|
|
continuo su STATUS.
|
|
|
|
\section{Procedura di avvio (boot)}
|
|
|
|
Due percorsi reali, entrambi presenti sulla scheda per progetto:
|
|
|
|
\begin{enumerate}
|
|
\item \textbf{Primo avvio / recupero (JTAG, pilotato da ESP32)}:
|
|
su una scheda vergine la flash \`e vuota --- solo JTAG pu\`o
|
|
inizializzarla (vincolo reale, non aggirabile via SPI finch\'e
|
|
la FPGA non esegue gi\`a la logica che relaya i comandi).
|
|
\item \textbf{Avvio normale (Master SPI, autonomo)}: a ogni
|
|
accensione successiva la FPGA si auto-configura dalla flash
|
|
tramite il proprio hardware dedicato, senza intervento dell'ESP32.
|
|
\item \textbf{Aggiornamento firmware sul campo} (\texttt{FLASH\_XFER}):
|
|
a FPGA gi\`a in funzione, l'ESP32 pu\`o riscrivere la flash
|
|
relayando byte SPI-NOR grezzi attraverso la FPGA.
|
|
\end{enumerate}
|