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
This commit is contained in:
Binary file not shown.
+54
-8
@@ -51,15 +51,61 @@ project uses for verification.
|
|||||||
|
|
||||||
\section{What a real host driver would still need to add}
|
\section{What a real host driver would still need to add}
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item A physical transport (SPI, parallel bus, or otherwise) carrying
|
|
||||||
the fields of \S\ref{ch:host}'s own table across a real pin
|
|
||||||
interface --- not designed in this revision.
|
|
||||||
\item A completion-notification path back to the host (V1's own
|
|
||||||
\code{data\_ready\_n}/\code{STATUS.done} has no V2 analogue yet);
|
|
||||||
today, completion is only observable internally
|
|
||||||
(\code{dir\_job\_out\_done}) or by polling the expected result
|
|
||||||
address.
|
|
||||||
\item Per-job \code{bias}/\code{activation} selection, currently
|
\item Per-job \code{bias}/\code{activation} selection, currently
|
||||||
hardcoded to \code{bias=0}/\code{ACT\_RELU} for every job
|
hardcoded to \code{bias=0}/\code{ACT\_RELU} for every job
|
||||||
(\S\ref{ch:datapath}).
|
(\S\ref{ch:datapath}).
|
||||||
\end{itemize}
|
\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}).
|
||||||
|
|||||||
@@ -245,3 +245,73 @@ the user is preparing separately.
|
|||||||
FPGA-TN-02038-2.0 \S3--4. Full schematic capture (BOM, connectors,
|
FPGA-TN-02038-2.0 \S3--4. Full schematic capture (BOM, connectors,
|
||||||
FPGA--RAM/FLASH and PROG sections) pending separately.}
|
FPGA--RAM/FLASH and PROG sections) pending separately.}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
|
\section{Programming architecture (2026-09-07) --- two independent
|
||||||
|
flash devices, ESP32 over JTAG only}
|
||||||
|
\label{sec:prog-addendum}
|
||||||
|
\begin{fnwarn}[Real, closed design -- not a placeholder]
|
||||||
|
Converged after evaluating and rejecting a single-shared-flash and an
|
||||||
|
SSPI-every-boot alternative (see \code{decisions.log} DEC-0041 for the
|
||||||
|
full comparison). This is the current, real architecture.
|
||||||
|
\end{fnwarn}
|
||||||
|
|
||||||
|
\subsection{Two physically separate flash chips}
|
||||||
|
\begin{itemize}
|
||||||
|
\item \textbf{Flash \#1} --- neural-network weights/graph data.
|
||||||
|
V1's own real subsystem (\code{flash\_copy\_engine.v}/
|
||||||
|
\code{flash\_slot\_manager.v}), 4 ordinary GPIO balls. V1's own
|
||||||
|
real balls (\code{flash\_sclk}=E3, \code{flash\_mosi}=D3,
|
||||||
|
\code{flash\_miso}=D5, \code{flash\_cs\_n}=E4) are \textbf{not}
|
||||||
|
reusable in V2 --- confirmed conflict, all four already carry
|
||||||
|
V2's own SDRAM bus. New balls reserved (bank~7, 3.3\,V):
|
||||||
|
\code{flash\_sclk}=B2, \code{flash\_mosi}=E2,
|
||||||
|
\code{flash\_miso}=F2, \code{flash\_cs\_n}=F3. \textbf{Not yet
|
||||||
|
in the LPF} --- the RTL port does not exist in
|
||||||
|
\code{fpga\_neural\_v2\_top.v} yet (a real, separate, open
|
||||||
|
integration task).
|
||||||
|
\item \textbf{Flash \#2} --- boot bitstream only. Connects
|
||||||
|
exclusively to the ECP5's own dedicated sysCONFIG pins, Master
|
||||||
|
SPI mode, auto-boots every power-up, zero ESP32 involvement in
|
||||||
|
normal operation.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\subsection{ESP32 $\leftrightarrow$ ECP5: JTAG only}
|
||||||
|
Neither ESP32-S3 nor ESP32-C6 has a hardware JTAG \emph{master}
|
||||||
|
peripheral (verified against Espressif's own documentation): their
|
||||||
|
native ``USB Serial/JTAG Controller'' lets an external host debug the
|
||||||
|
ESP32 itself --- the wrong direction for driving the ECP5. TCK/TMS/
|
||||||
|
TDI/TDO are therefore bit-banged from ordinary ESP32 GPIO, standard
|
||||||
|
practice. ESP32 updates flash~\#2 by commanding the ECP5's own
|
||||||
|
internal sysCONFIG engine to bridge JTAG writes through to the
|
||||||
|
external flash (real Lattice mechanism, FPGA-TN-02038-2.0 Figure~6.3,
|
||||||
|
``Programming external Flash via JTAG'') --- ESP32 never drives
|
||||||
|
flash~\#2's own SPI pins directly, zero bus contention by
|
||||||
|
construction.
|
||||||
|
|
||||||
|
\subsection{Real ball assignments (CABGA381)}
|
||||||
|
From the official Lattice pinout CSV (\code{FPGA-SC-02034-3-0-
|
||||||
|
ECP5U-45-Pinout.csv} rev.\,3.0) cross-checked against Project
|
||||||
|
Trellis's \code{iodb.json}.
|
||||||
|
|
||||||
|
\begin{fnnote}[JTAG (bank 40/TAP) --- to ESP32]
|
||||||
|
TCK=T5, TMS=U5, TDI=R5, TDO=V4.
|
||||||
|
\end{fnnote}
|
||||||
|
\begin{fnnote}[Dedicated config (bank 8) --- to ESP32]
|
||||||
|
PROGRAMN=W3, INITN=V3, DONE=Y3.
|
||||||
|
\end{fnnote}
|
||||||
|
\begin{fnnote}[CFG{[}2:0{]} (bank 8) --- board jumpers/0$\Omega$, NOT to ESP32]
|
||||||
|
For MSPI, CFG[2:0]$=$[0,1,0] read MSB-first: CFG\_2(R4)$=$GND,
|
||||||
|
CFG\_1(T4)$=$pull-up 1--10\,k$\Omega$ to VCCIO8, CFG\_0(U4)$=$GND.
|
||||||
|
\end{fnnote}
|
||||||
|
\begin{fnnote}[MSPI dedicated/dual-function pins to flash \#2 (bank 8) --- NOT to ESP32]
|
||||||
|
MCLK/CCLK=U3, CSSPIN=R2 (dual w/ HOLDN/DI/BUSY/CEN), D0/MOSI=W2,
|
||||||
|
D1/MISO=V2.
|
||||||
|
\end{fnnote}
|
||||||
|
|
||||||
|
Confirmed real and safe (Lattice FPGA-TN-02039-2.3 sysCONFIG User
|
||||||
|
Guide, \S6.1.2): once User Mode is reached, the MSPI dedicated pins
|
||||||
|
tristate with a weak pull-up, so they never contend with another
|
||||||
|
driver on the same net --- not load-bearing for this specific
|
||||||
|
two-chip architecture (flash \#1/\#2 are physically separate), but
|
||||||
|
confirms the mechanism is real should a future revision ever share a
|
||||||
|
single chip.
|
||||||
|
|||||||
Reference in New Issue
Block a user