Files
FPGA-Neural/hardware/v1/docs/DatasheetLatex/chapters/02-architettura.tex
T
2026-09-06 15:02:25 +02:00

81 lines
6.7 KiB
TeX

\chapter[RTL architecture]{RTL architecture and module hierarchy}
\label{ch:arch}
\section{Hierarchical organization}
The design is organized in layers, from the elementary multiply-accumulator up to the
integrated top-level with SPI interface and PSRAM. Each layer encapsulates the previous
one and abstracts away its details: the validated datapath (\code{mac\_unit},
\code{mac8}, \code{neuron\_parallel}) is never modified by the higher orchestration
layers.
\begin{center}
\begin{tikzpicture}[font=\footnotesize,every node/.style={fnblock,minimum width=40mm},
level distance=13mm,sibling distance=0mm]
\node[fnblockD,minimum width=62mm](top){\code{spi\_neuron\_top} \\ {\scriptsize integrated top-level}};
\node[fnblockT,minimum width=62mm,below=8mm of top](arb){\code{mem\_arbiter} \;/\; \code{layer\_sequencer} \\ {\scriptsize 3-port arbitration + layer sequencing}};
\node[fnblock,minimum width=62mm,below=8mm of arb](nm){\code{neuron\_memory} \\ {\scriptsize memory $\leftrightarrow$ neuron bridge, neuron loop}};
\node[fnblock,minimum width=62mm,below=8mm of nm](np){\code{neuron\_parallel} \\ {\scriptsize neuron FSM: groups, bias, activation, saturation}};
\node[fnblockT,minimum width=62mm,below=8mm of np](m8){\code{mac8} \\ {\scriptsize \code{PARALLEL} MACs + balanced adder tree}};
\node[fnblock,minimum width=62mm,below=8mm of m8](mu){\code{mac\_unit} \\ {\scriptsize $x\cdot w$ + sign extension + accumulate}};
\foreach \a/\b in {top/arb,arb/nm,nm/np,np/m8,m8/mu}
\draw[fnarrow] (\a) -- (\b);
% memory branches on the right
\node[fnblockA,minimum width=34mm,right=14mm of nm](ma){\code{int8\_memory\_access}\\{\scriptsize byte $\leftrightarrow$ 16-bit word}};
\node[fnblockA,minimum width=34mm,below=6mm of ma](mi){\code{memory\_interface}\\{\scriptsize req/ready handshake}};
\node[fnblockA,minimum width=34mm,below=6mm of mi](pc){\code{psram\_controller}\\{\scriptsize physical PSRAM bus}};
\draw[fnarrowT] (ma)--(mi); \draw[fnarrowT] (mi)--(pc);
\draw[fnarrowT,dashed] (nm.east) -- (ma.west);
% SPI branches on the left
\node[fnblockA,minimum width=30mm,left=14mm of arb,yshift=6mm](ss){\code{spi\_slave}\\{\scriptsize Mode 0 physical layer}};
\node[fnblockA,minimum width=30mm,below=6mm of ss](se){\code{spi\_engine}\\{\scriptsize opcode FSM + registers}};
\draw[fnarrowT] (ss)--(se);
\draw[fnarrowT,dashed] (se.east) -- (arb.west);
\end{tikzpicture}
\end{center}
\section{Role of each module}
\begin{tabularx}{\textwidth}{L{3.4cm}Y}
\toprule
\rowh \thd{Module} & \thd{Function} \\
\midrule
\code{mac\_unit} & Single multiply-accumulate: $\mathrm{acc\_out}=\mathrm{acc\_in}+(x\cdot w)$, with sign extension of the product to \code{ACC\_WIDTH}. Parametric on \code{DATA\_WIDTH}/\code{ACC\_WIDTH}. \\
\rowa \code{mac8} & \code{PARALLEL} instances of \code{mac\_unit} whose products are summed by a \emph{balanced binary adder tree} of depth $\log_2(\text{PARALLEL})$; the result is added to the input accumulator. \\
\code{neuron\_parallel} & FSM of a single neuron: processes \code{N\_INPUTS} inputs in groups of \code{PARALLEL}, accumulates across groups, adds the bias, applies the activation and saturates to INT8. Includes the processing guard on \code{N\_INPUTS \% PARALLEL} and the runtime width \code{n\_inputs\_real}. \\
\rowa \code{layer} & Instantiates \code{N\_NEURONS} neurons \emph{in parallel} on the same input vector; \code{busy}=OR, \code{done}=AND of the neurons. A purely data-combinational path used in the datapath benchmarks. \\
\code{neuron\_memory} & Integrates computation with memory: reads $X$ (shared) once, then for each neuron re-reads $W$ and bias from RAM and reuses a single \code{neuron\_parallel} instance (memory-bound, one neuron at a time). Output \code{y\_bus} packed neuron-major. \\
\rowa \code{layer\_sequencer} & Chains up to \code{N\_LAYERS} executions of \code{neuron\_memory} by reading a descriptor table written by the host and alternating the ping-pong buffers in RAM (Phase~5). \\
\code{act\_buffer} & Global activation buffer in \code{DP16KD} block RAM, indexed by signal id (Type \#2). \\
\rowa \code{graph\_engine} & Graph-network engine (Type \#2): gather from \code{act\_buffer}, reuses \code{neuron\_parallel}, writes outputs by id (ch.~\ref{ch:grafo}). \\
\code{int8\_memory\_access} & Converts the byte/INT8 interface (byte address) into the 16-bit word interface, selecting the low/high byte via \code{lb\_n}/\code{ub\_n} and \code{addr>>1}. \\
\rowa \code{memory\_interface} & 2-state handshake FSM (IDLE/WAIT) that serializes the single transaction toward the controller. \\
\code{psram\_controller} & Asynchronous parallel PSRAM bus controller with read \textbf{page mode}: 70~ns random access (\code{tAA}), 20~ns same-page bursts (\code{tAPA}) with CE\#/OE\# held asserted; enables page mode on the chip at boot via the configuration register (ch.~\ref{ch:mem}, \S~5.5). Drives \code{ce\_n/oe\_n/we\_n/lb\_n/ub\_n/zz\_n} and the tri-state data bus. \\
\rowa \code{mem\_arbiter} & Fixed-priority arbiter (B$>$C$>$A) among three byte-level masters: \code{spi\_engine} (A), \code{neuron\_memory} (B), \code{layer\_sequencer} (C). \\
\code{spi\_slave} & SPI Mode 0 physical layer, MSB-first, 3-stage CDC synchronizer on SCLK/MOSI/CS\_N, shift register and CS framing. \\
\rowa \code{spi\_engine} & Protocol/opcode FSM and register bank (\code{x\_base}, \code{w\_base}, \code{bias\_addr}, ping-pong base, activation, runtime widths\ldots), with sticky/clear-on-read \code{STATUS.done}. \\
\code{spi\_neuron\_top} & Top-level: connects SPI, arbiter, sequencer, \code{neuron\_memory} and the PSRAM chain; multiplexes control of \code{neuron\_memory} between the sequencer and the direct single-layer path. \\
\bottomrule
\end{tabularx}
\vspace{6pt}
\begin{fnnote}[Simulation models]
\code{psram\_model.v} (in \code{sim/}) and \code{memory\_model.v} are behavioral memory
models used in the testbenches; they are not part of the synthesizable design but they
reproduce the real latency for end-to-end verification.
\end{fnnote}
\section{Two execution paths}
The top-level exposes two mutually exclusive modes toward the same \code{neuron\_memory}
compute engine:
\begin{itemize}
\item \textbf{Single-layer / manual path}: the host sets the bases with
\op{SET\_BASE}, starts with \op{START} and reads with \op{READ\_OUTPUT}.
\code{spi\_engine} drives \code{neuron\_memory} directly.
\item \textbf{Multi-layer path}: the host writes the descriptor table and starts with
\op{RUN\_NETWORK}; \code{layer\_sequencer} takes over control of \code{neuron\_memory}
(while \code{seq\_busy} is high) and chains the layers.
\end{itemize}
The top-level multiplexer switches the control lines of \code{neuron\_memory} based on
\code{seq\_busy}, returning the engine to the direct path at the end of the sequence.