Files
FPGA-Neural-Datasheet/files/docs/datasheet/v2-en/chapters/07-hostinterface.tex
T
micheleandClaude Sonnet 5 d8ccc9d494 docs: datasheet addendum for two-flash programming architecture + FPGA_DATA_READY
Adds a real, dated section to ch.10 (Hardware and board) covering the
two-independent-flash architecture (neural-network data vs. boot
bitstream), the ESP32<->ECP5 JTAG-only link, and the real CABGA381
ball assignments (JTAG/PROGRAMN/INITN/DONE/CFG[2:0]/MSPI dedicated
pins), matching decisions.log DEC-0041.

Also closes ch.7's (Host interface) own long-standing "still needed"
list: the physical transport (spi_host_bridge.v) and the completion-
notification path (FPGA_DATA_READY) it used to flag as missing are
both now real -- described with the same system-idle-detector formula
implemented in the RTL.

Compiled clean (44 pages, 0 errors).

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

112 lines
5.6 KiB
TeX

\chapter{Host / graph-loader interface}
\label{ch:host}
\begin{fnwarn}[Scope of this chapter]
V1's own host interface is a real, placed, physically-verified SPI Mode~0
slave (ch.~7 of the V1 datasheet). V2's equivalent --- a node-registration
bus into \code{neural\_multiprocessor.v} --- has, in this revision, been
exercised exclusively from Verilator testbenches and unconstrained
synthesis top-levels. This chapter describes the \textbf{logical}
protocol only; no real host-side driver (SPI or otherwise) has been
built or placed yet. See ch.~\ref{ch:roadmap}.
\end{fnwarn}
\section{Node registration protocol}
A simple valid/ready producer interface, backpressure-safe: the loader
holds \code{reg\_valid} and the node's own fields until \code{reg\_ready}
is observed high on the same cycle, exactly like registering into any
FIFO. \code{reg\_ready} for a given \code{reg\_node\_id} is asserted
whenever that node's own table slot is \code{EMPTY} (\S\ref{ch:sched}).
\begin{tabularx}{\textwidth}{L{3.2cm} C{1.6cm} Y}
\toprule
\rowh \thd{Field} & \thd{Width} & \thd{Meaning} \\
\midrule
\code{reg\_node\_id} & $\lceil\log_2\text{N\_NODES}\rceil$ & This node's own id --- doubles as its table slot index. \\
\rowa \code{reg\_required} & $\lceil\log_2(\text{MAX\_DEPS}{+}1)\rceil$ & How many of \code{reg\_producer\_ids} are meaningful (0 $\Rightarrow$ immediately \code{READY}). \\
\code{reg\_producer\_ids} & \code{MAX\_DEPS}$\times\lceil\log_2\text{N\_NODES}\rceil$ & Packed array of producer node ids this node depends on. \\
\rowa \code{reg\_x\_base} & \code{ADDR\_WIDTH} & Base byte address of this node's activation vector. \\
\code{reg\_w\_base} & \code{ADDR\_WIDTH} & Base byte address of this node's weight vector. \\
\rowa \code{reg\_n\_tiles} & 16 & Number of P\_IN-wide tiles to accumulate. \\
\code{reg\_result\_addr} & \code{ADDR\_WIDTH} & Byte address the computed INT8 result is written to. \\
\bottomrule
\end{tabularx}
\begin{fnnote}[A node id is a real, finite resource]
Because dispatched node table slots are never reclaimed
(\S\ref{ch:sched}), a loader driving many independent jobs over a long
session must use a fresh \code{reg\_node\_id} for each one, within
\code{N\_NODES}. Reusing a value before the system has been reset will
simply be refused (\code{reg\_ready} stays low for an occupied,
non-\code{EMPTY} node id) --- it will not corrupt anything, but it will
also not register.
\end{fnnote}
\section{Result readback}
The computed INT8 result is written to \code{reg\_result\_addr} through
the same real PSRAM chain every other memory access uses --- there is no
separate result-readback port; the host/loader reads the result byte
back from PSRAM directly, the same convention every V2 testbench in this
project uses for verification.
\section{What a real host driver would still need to add}
\begin{itemize}
\item Per-job \code{bias}/\code{activation} selection, currently
hardcoded to \code{bias=0}/\code{ACT\_RELU} for every job
(\S\ref{ch:datapath}).
\end{itemize}
\section{Addendum (2026-09-07) --- real physical transport and
completion signal, both now closed}
\label{sec:host-addendum}
\begin{fnwarn}[Supersedes the two items removed from the list above]
Both real gaps this chapter used to list are closed. This section is
the current, real state.
\end{fnwarn}
\textbf{Physical transport}: \code{spi\_host\_bridge.v}, a real SPI
Mode~0 slave, is the board's actual node-registration transport ---
real ball assignments (\code{spi\_sclk}/\code{spi\_mosi}/
\code{spi\_miso}/\code{spi\_cs\_n}) verified, real place\&route (see
ch.~\ref{ch:hw}). WRITE\_JOB carries the full table from
\S\ref{ch:host} above as an 18-byte payload (grew from 15 after the
64MB memory upgrade widened every address field from 3 to 4 bytes ---
\code{decisions.log} DEC-0039).
\textbf{Completion notification}: \code{FPGA\_DATA\_READY}, a real
output pin (ball \code{G3}, bank~7), closes the exact gap this
chapter used to flag. It is a system-idle detector, not a per-job
pulse --- deliberately, since ``the whole graph has an answer'' and
``one neuron finished'' are different questions and only the former is
useful to a host waiting on a result:
\[
\text{sys\_busy} = \big(\textstyle\bigvee \text{job\_active}\big)
\;\lor\; \lnot\text{queue\_empty} \;\lor\; \text{any\_pending}
\]
where \code{job\_active} is per-slot (already real, \S\ref{ch:sched}),
\code{queue\_empty} is \code{neural\_director.v}'s own dispatch-queue
occupancy, and \code{any\_pending} (new) is an OR-reduce over
dependency\_manager's own node table for any node still
\code{WAITING} or \code{READY} (i.e. registered but not yet
dispatched --- \code{DISPATCHED} nodes are tracked by the two signals
above instead, not here). \code{FPGA\_DATA\_READY} is a sticky
register: set on the \code{sys\_busy} $1\to0$ edge, cleared the
instant \code{sys\_busy} goes high again --- self-clearing, no host
acknowledgement command needed.
\begin{fnnote}[Real, disclosed assumption]
This is correct only if the host finishes registering every node of a
graph before the first one completes. Realistic for this
architecture's own real timing (SPI registration: microseconds;
per-neuron compute: $\sim$195 real measured cycles, \S\ref{ch:impl2})
but not proven for every conceivable host registration pattern --- a
host that deliberately staggers registration across a long enough gap
could observe a premature \code{FPGA\_DATA\_READY} pulse after only
the first node completes.
\end{fnnote}
Bit-exact regression re-verified with an explicit assertion on this
signal (N\_SLOTS=4 and 8, both PASS, see \code{decisions.log}
DEC-0041) and a real \code{nextpnr-ecp5} placement check (0 errors,
\code{data\_ready} placed at \code{G3}).