External flash access path
The SEC module has no internal non-volatile memory. Helper data, the key fingerprint, the nonce ceiling and every encrypted record live in a single external chip — a Winbond W25Q64JV, 8 MB of Quad-SPI flash sitting on the subsystem's PMOD header.
The module connects to the flash through six wires: a clock, chip-select,
and four data lines. The spi_master_quad block controls this interface.
Boot reads, helper-data writes, counter updates, and application records all use
this path.
Reading the colours: ■ clock / command · ■ standard line traffic · ■ quad data (4 bits/clock) · ■ FIFO jobs & metadata
FIFO-based command interface
Other blocks do not drive SCLK directly. They submit commands through the TX FIFO. Each entry is a 57-bit word:
{ rrw, addr[23:0], data[31:0] } // 1 + 24 + 32 = 57 bit
rrw = 1→ write this 32-bit word to flash addressaddr.rrw = 0→ read the word ataddr— the result comes back through the RX FIFO, tagged with its address.
The master processes entries in order. FIFO fullness provides back-pressure to the producer.
Enabling quad mode after reset
The flash powers up in single-line mode. Before quad transfers are used, the master sets the chip's Quad-Enable bit without software involvement:
WREN(0x06) — unlock the status register for writing.WRSR2(0x31) with data0x02— setQE = SR2[1].- poll
RDSR1(0x05) until theBUSYbit reads 0.
After this sequence, init_done is asserted and the Main FSM may start
submitting FIFO entries. Until then, the master does not consume queued jobs.
SPI mode and bit-level datapath
The master speaks SPI Mode 0, MSB first. SCLK idles low; the master changes its output on the falling edge and samples the incoming line on the rising edge, so data is sampled after it has settled.
The datapath is organized around three components:
- a shift register emits one bit per clock in standard mode, or a whole nibble (4 bits across DQ0–DQ3) per clock in quad mode;
- an edge counter is preloaded for each phase (8 for a command, 24 for an address, 8 for quad data) and counts the phase down to its last clock;
- a clock divider turns the 100 MHz system clock into a ~12.5 MHz SCLK.
Quad mode transfers four bits per clock, reducing the number of data-phase clocks for a 32-bit word from 32 to 8.
Writing a word with Quad Page Program
To store a word the master issues a Quad Page Program (0x32).
Command and address are transmitted on one line; the 32 data bits are transmitted
four at a time across DQ0–DQ3:
0x32 + addr[23:0] // 8 + 24 SCLK, standard line
8 quad cycles // 32 data bits, 4 per clock
= 40 SCLK total
Every program is preceded by its own WREN, because the flash clears WEL
after each write). The bytes land in the target page; the TX FIFO drains one entry
as each word commits.
Busy polling after programming
Flash programming completes after the command phase. After every page program, the master polls the status register:
- send
RDSR1(0x05), read back theBUSYbit; - if still busy, raise CS, wait the gap, and poll again;
- only when
BUSY = 0is the next FIFO job allowed to start.
A write operation reports completion only after the flash has committed every word.
The next FIFO entry starts only after BUSY clears.
Reading a word with Fast Read Quad Output
The read path uses Fast Read Quad
Output (0x6B) plus the address, then waits out 8 dummy cycles
for bus turnaround. During this interval the master releases the data lines before the
flash drives them. Then 32 bits return, four per clock:
0x6B + addr[23:0] // 8 + 24 SCLK, standard line
8 dummy + 8 quad // turnaround, then 32 read bits
= 48 SCLK total
The assembled word, together with its address, is pushed into the RX FIFO for the Main FSM. The dummy-cycle handoff was also the source of an FPGA-only read issue described in Verification.
Hardware address guard
The helper data used for key reconstruction is stored at the bottom of flash. To protect this reserved region after enrollment, the master implements a hardware address guard:
- once enrolled (
fe_done = 1), any write whose address falls inside the reserved helper region is rejected before SCLK starts; - reads remain allowed so boot reconstruction can load helper data.
The check is implemented in the master rather than in firmware. A violation raises
addr_violation, drops the job, and is escalated by the Main FSM.
Command trace for observability
A read-only command trace ring (register 0x040) logs every flash command the
master sends — its type and address — plus running tallies of erases, programs and
reads.
After an encryption, firmware can read the trace back over APB and confirm the exact sequence: "1 sector erase, then 64 programs, at these addresses, in this order." It does not touch the data path; it is used for observability in simulation and FPGA bring-up.
in simulation
Checks that the emitted commands match the expected sequence.
on hardware
Firmware can read the ring back over UART during bring-up.
Flash interface summary
The flash interface uses a small command set and one hardware owner. The master enables quad mode, programs and reads words through FIFO entries, polls completion, guards reserved regions, and records command activity for debug and verification.
Continue with:
- Encrypt & Decrypt — how the records carried on this bus are produced and consumed.
- Verification — how the command sequence was checked in simulation and on FPGA.
- Register reference — the trace ring and related software-visible registers.