SEC Module · Secure Enclave
spi_master_quad · Winbond W25Q64JV · Quad-SPI over PMOD

Quad-SPI interface to external NVM flash

The SEC module stores helper data, the key fingerprint, the nonce reservation ceiling, and encrypted records in one external W25Q64JV flash chip. Access is mediated by a single Quad-SPI master. This page describes the command flow used for initialization, programming, polling, reading, address guarding, and trace collection.

scroll freely through the chapters
SEC MODULE — flash interface SCLK CS_N IO0 / DQ0 IO1 / DQ1 IO2 / DQ2 IO3 / DQ3 Main FSM + status_ctrl command source fe_done gate: helper vs. app TX FIFO {rrw,addr,data} 57b RX FIFO {addr,data} spi_master_quad Quad-SPI master bit engine · 35-state FSM S_IDLE cmd — edge 0 SCLK · mode 0 shreg ········ INIT IDLE QUAD RX W25Q64JV 8 MB Quad-SPI NVM · on PMOD SR2 · QE (quad enable) SR1 · BUSY · WEL 0x000000 helper data guarded · write-blocked when enrolled 0x002000 … application records page one record = one 256 B page QPP 0x32 writes · FRDQ 0x6B reads f_SCLK ≈ 12.5 MHz @ 100 MHz clk CS gap ≥ 16 cycles between commands
Scroll to inspect the bus sequence.
Interface overview

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

Chapter 1

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 = 1write this 32-bit word to flash address addr.
  • rrw = 0read the word at addr — 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.

Chapter 2 · runs once after reset

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 data 0x02 — set QE = SR2[1].
  • poll RDSR1 (0x05) until the BUSY bit 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.

Chapter 3

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.

Chapter 4 · write

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.

Chapter 5 · write

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 the BUSY bit;
  • if still busy, raise CS, wait the gap, and poll again;
  • only when BUSY = 0 is 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.

Chapter 6 · read

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.

Chapter 7 · guard

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.

Chapter 8 · observability

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.

Epilogue

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.

Flash command set

The implementation uses five opcodes. Phase lengths are counted in SCLK cycles.

OpcodeNamePhasesUsed for
0x06WRENcmd (8)Unlock before any status-write or program
0x05RDSR1cmd (8) + data out (8)Read status — the BUSY poll after every write
0x31WRSR2cmd (8) + data in (8)Set the Quad-Enable bit at boot
0x32Quad Page Programcmd (8) + addr (24) + 8 quad = 40Write one 32-bit word to flash
0x6BFast Read Quad Outputcmd (8) + addr (24) + 8 dummy + 8 quad = 48Read one 32-bit word from flash

Mode 0 (CPOL = 0, CPHA = 0), MSB first. A single-line Fast Read (0x0B) also exists as a robustness fallback for the read path — see Verification.