\chapter{Parameters and configurability} \label{ch:param} \section{Build parameters (synthesis-time)} The hardware architecture is fixed at synthesis through the following Verilog parameters. They determine the datapath contained in the bitstream and its capacity \emph{ceiling}. \begin{tabularx}{\textwidth}{L{3.0cm} C{1.8cm} Y} \toprule \rowh \thd{Parameter} & \thd{Default} & \thd{Meaning} \\ \midrule \code{DATA\_WIDTH} & 8 & Data width (INT8). \\ \rowa \code{ACC\_WIDTH} & 32 & Accumulator width (INT32). \\ \code{N\_INPUTS} & 32 / 256 & Maximum number of inputs per neuron (benchmark baseline: 256). \\ \rowa \code{N\_NEURONS} & 1 / 4 & Maximum number of neurons per layer. \\ \code{PARALLEL} & 8 & Simultaneous hardware MACs per neuron; must divide \code{N\_INPUTS} and should be a power of two. \\ \rowa \code{N\_LAYERS} & 4 & Maximum number of layers chainable by \code{layer\_sequencer}. \\ \code{ADDR\_WIDTH} & 23 & Byte-address width (8~MB). \\ \rowa \code{MEM\_DATA\_WIDTH} & 16 & Width of the physical PSRAM data bus. \\ \code{CLK\_FREQ\_MHZ} & 80 & Frequency used in the PSRAM timing formulas (must be aligned to the real oscillator). \\ \bottomrule \end{tabularx} \begin{fnwarn}[\texttt{N\_INPUTS} \% \texttt{PARALLEL} constraint] \code{PARALLEL} must divide \code{N\_INPUTS} exactly, otherwise the elaboration guard fires (ยง\ref{ch:datapath}). The same constraint applies at runtime to \code{n\_inputs\_real}. \end{fnwarn} \section{Runtime network width} A single bitstream serves any topology \emph{up to} the build maximum. The actual width of each execution is a separate value, set by the host: \begin{itemize} \item \code{n\_inputs\_real} --- inputs actually used in this execution (must be a multiple of \code{PARALLEL}); \item \code{n\_neurons\_real} --- neurons actually computed in this execution. \end{itemize} Both default to the build maximum, so any caller that leaves them unconnected processes the full width as before the ports were introduced. \begin{fnnote}[Real early termination] This is not mere address bookkeeping: the two values directly bound the hardware loops (X/W reads of \code{neuron\_memory}, MAC group count of \code{neuron\_parallel} and the length of the ping-pong copy for \code{RUN\_NETWORK}). A narrower layer actually \emph{computes} and \emph{copies} faster and does not require zero-padding of the RAM for the unused tail: data beyond \code{n\_inputs\_real}/\code{n\_neurons\_real} is never read. \end{fnnote} This lets a network taper within a single chained execution, for example $256\to64\to16\to4$, with each layer declaring its own actual width in the descriptor table (ch.~\ref{ch:seq}). \subsection{Measured savings} Early termination was measured end-to-end: \begin{tabularx}{\textwidth}{L{5.5cm} C{3.0cm} Y} \toprule \rowh \thd{Test} & \thd{Cycles} & \thd{Comparison} \\ \midrule \code{neuron\_parallel\_tb.v} (T7) & 3 vs 6 & reduced vs full, with ``garbage'' data in the skipped lanes (proof that they are not read). \\ \rowa \code{neuron\_memory\_tb.v} (T5) & 209 vs 788 & 8-of-32 vs full 32, through the real PSRAM stack. \\ \bottomrule \end{tabularx} \section{Characterized configurations} Some combinations validated in simulation and/or synthesis: \begin{tabularx}{\textwidth}{C{2.0cm} C{2.0cm} C{2.0cm} Y} \toprule \rowh \thd{N\_INPUTS} & \thd{N\_NEURONS} & \thd{PARALLEL} & \thd{Notes} \\ \midrule 32 & 4 & 8 & First functional parametric test (Phase~1). \\ \rowa 256 & 4 & 2/4/8/16 & Datapath benchmark sweep (Phase~7). \\ 32 & 1..3 & 8 & Single/multi-neuron memory integration (Phase~3). \\ \rowa 4 & 4 & 2 & End-to-end 2-layer \code{RUN\_NETWORK} test over real SPI. \\ \bottomrule \end{tabularx} \section{Build versus runtime summary} \begin{center} \begin{tikzpicture}[font=\footnotesize,node distance=6mm] \node[fnblockD,minimum width=54mm,minimum height=15mm](b){\textbf{BUILD (synthesis)}\\[2pt] {\scriptsize N\_INPUTS, N\_NEURONS, N\_LAYERS,}\\{\scriptsize PARALLEL, DATA\_WIDTH, ACC\_WIDTH}\\{\scriptsize $\Rightarrow$ machine ceiling}}; \node[fnblockT,right=16mm of b,minimum width=54mm,minimum height=15mm](r){\textbf{RUNTIME (host, SPI)}\\[2pt] {\scriptsize n\_inputs\_real, n\_neurons\_real,}\\{\scriptsize activation, num\_layers, weights/bias}\\{\scriptsize $\Rightarrow$ actual network}}; \draw[fnbus] (b) -- node[fnlbl,above]{$\le$} (r); \end{tikzpicture} \end{center}