Files
FPGA-Neural-Datasheet/files/docs/datasheet/en/chapters/06-sequencer.tex
T
micheleandClaude Sonnet 5 0e73eb4726 docs: bring datasheet/ into the main repo under hardware/v2/docs
Was a separate, untracked directory (DataSheet/) outside the repo.
Renamed to lowercase and moved in as hardware/v2/docs/datasheet/, with
its own .gitignore for LaTeX build byproducts (compiled PDFs stay
tracked, .aux/.log/.toc/etc do not). Now versioned and shares this
repo's own remote instead of living untracked on disk.

Content: IT+EN LaTeX chapter sources, reference manufacturer PDFs, and
compiled datasheet PDFs including the 2026-09-07 SDRAM upgrade
addendum (AS4C32M16SB-7BIN part/pinout/timing) in the v2-en chapters.

Note: hardware/v2/docs/DatasheetLatex/ (and the v1 sibling) is a
separate, already-tracked, differently-structured LaTeX document that
predates this move -- left untouched, not merged, since its chapter
set and content differ and merging was not requested.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
2026-09-07 05:09:14 +02:00

112 lines
5.2 KiB
TeX

\chapter[Memory, multi-neuron and multi-layer]{Memory integration, multi-neuron and multi-layer}
\label{ch:seq}
\section{\texttt{neuron\_memory} --- memory/neuron bridge}
\code{neuron\_memory} connects the compute datapath to memory and manages the loop over
the neurons. It reads the $X$ vector only once (shared input), then for each neuron
re-reads $W$ and bias from RAM and feeds them to a single reused instance of
\code{neuron\_parallel}: the design is memory-bound, one neuron computed at a time,
without duplicating the datapath. The output is \code{y\_bus}, packed neuron-major
(\code{DATA\_WIDTH*N\_NEURONS} bits).
\begin{center}
\begin{tikzpicture}[font=\scriptsize,node distance=13mm]
\node[fnstate](idle){IDLE};
\node[fnstate,right=of idle](rx){READ\_X};
\node[fnstate,right=of rx](rw){READ\_W};
\node[fnstate,below=10mm of rw](rb){READ\_BIAS};
\node[fnstate,left=of rb](sn){START\_N};
\node[fnstate,left=of sn](wn){WAIT\_N};
\draw[fnarrow] (idle)--node[fnlbl,above]{start}(rx);
\draw[fnarrow] (rx)--node[fnlbl,above]{X read}(rw);
\draw[fnarrow] (rw)--(rb);
\draw[fnarrow] (rb)--(sn);
\draw[fnarrow] (sn)--(wn);
\draw[fnarrow] (wn) to[bend left=18] node[fnlbl,above]{next neuron}(rw);
\draw[fnarrow] (wn) to[bend right=28] node[fnlbl,below]{last neuron: done}(idle);
\end{tikzpicture}
\end{center}
The states are IDLE, READ\_X, READ\_W, READ\_BIAS, START\_N, WAIT\_N. After the last
neuron the FSM returns to IDLE and asserts \code{done}. The count of neurons and inputs
actually processed is given by \code{n\_neurons\_real}/\code{n\_inputs\_real}
(ch.~\ref{ch:param}).
\section{\texttt{layer\_sequencer} --- multi-layer network}
\code{layer\_sequencer} chains up to \code{N\_LAYERS} executions of the same
\code{neuron\_memory} instance, realizing a dense feed-forward network \emph{without}
touching the validated compute core. It reads a descriptor table written by the host and
alternates the two output buffers in RAM (ping-pong).
\begin{center}
\begin{tikzpicture}[font=\scriptsize,node distance=13mm]
\node[fnstate](i){IDLE};
\node[fnstate,right=of i](rd){READ\\DESC};
\node[fnstate,right=of rd](rw){READ\\WAIT};
\node[fnstate,below=10mm of rw](sl){START\\LAYER};
\node[fnstate,left=of sl](wl){WAIT\\LAYER};
\node[fnstate,left=of wl](ci){COPY\\ISSUE};
\node[fnstate,below=9mm of ci](cw){COPY\\WAIT};
\draw[fnarrow] (i)--node[fnlbl,above]{run\_start}(rd);
\draw[fnarrow] (rd)--(rw);
\draw[fnarrow] (rw)--(sl);
\draw[fnarrow] (sl)--(wl);
\draw[fnarrow] (wl)--(ci);
\draw[fnarrow] (ci)--(cw);
\draw[fnarrow] (cw) to[bend left=15] node[fnlbl,left]{next layer}(rd);
\draw[fnarrow] (cw) to[bend right=12] node[fnlbl,below]{last: seq\_done}(i);
\end{tikzpicture}
\end{center}
\subsection{Ping-pong buffers}
Layer~0 reads the external input \code{x\_base}. Layer $k>0$ reads from the buffer
written by layer $k-1$; the output of each layer is copied into the other buffer,
alternating A and B. The final output remains both in \code{y\_bus} (readable with
\op{READ\_OUTPUT}) and in the ping-pong buffer into which it was copied.
\begin{center}
\begin{tikzpicture}[font=\scriptsize,node distance=7mm]
\node[fnblockA,minimum width=18mm](x){X\\\code{x\_base}};
\node[fnblockD,right=10mm of x,minimum width=20mm](l0){Layer 0};
\node[fnblock,right=10mm of l0,minimum width=18mm](ba){buf A};
\node[fnblockD,right=10mm of ba,minimum width=20mm](l1){Layer 1};
\node[fnblock,right=10mm of l1,minimum width=18mm](bb){buf B};
\node[fnblockD,right=10mm of bb,minimum width=20mm](l2){Layer 2};
\draw[fnarrow] (x)--(l0); \draw[fnarrow] (l0)--(ba);
\draw[fnarrow] (ba)--(l1); \draw[fnarrow] (l1)--(bb);
\draw[fnarrow] (bb)--(l2);
\draw[fnarrowT,dashed] (l2.south) to[bend left=25] node[fnlbl,below]{copy into buf A} (ba.south);
\end{tikzpicture}
\end{center}
\subsection{Descriptor table}
Written by the host into RAM at \code{table\_base} with \op{WRITE\_RAM}; \code{N\_LAYERS}
entries of 11 bytes each, MSB-first:
\begin{tabularx}{\textwidth}{L{3.4cm} C{1.6cm} Y}
\toprule
\rowh \thd{Field} & \thd{Bytes} & \thd{Meaning} \\
\midrule
\code{w\_base} & 3 & Weight base of the layer. \\
\rowa \code{bias\_addr} & 3 & Bias base of the layer. \\
\code{activation} & 1 & Layer activation (low 2 bits, cf. \code{ACT\_*}). \\
\rowa \code{n\_inputs\_real} & 2 & Actual inputs of the layer (multiple of \code{PARALLEL}). \\
\code{n\_neurons\_real} & 2 & Actual neurons of the layer. \\
\midrule
\rowh \thd{Total} & \thd{11} & per entry/layer \\
\bottomrule
\end{tabularx}
\begin{fnnote}[Copy proportional to the actual width]
The sequencer copies exactly \code{n\_neurons\_real} bytes of \code{y\_bus} into the
ping-pong buffer (not the full build width): a narrower layer is copied faster, without
zero-padding in RAM. Each activation is read per-layer from the table, independent of the
\code{activation} register of the single-layer path.
\end{fnnote}
\section{Hierarchy of the \texttt{busy}/\texttt{done} signals}
In the multi-layer path, \code{STATUS.busy} is the OR of the single-layer and sequencer
busy signals, while \code{STATUS.done} latches only at completion of the \emph{last}
layer, not at each intermediate layer (ch.~\ref{ch:spi}). The top-level returns control
of \code{neuron\_memory} to the direct \op{START} path at the end of the sequence.