Skip to content

Instantly share code, notes, and snippets.

@fm4dd
Last active October 9, 2023 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fm4dd/2af1e45aadc3aac8290ac3127ab45e72 to your computer and use it in GitHub Desktop.
Save fm4dd/2af1e45aadc3aac8290ac3127ab45e72 to your computer and use it in GitHub Desktop.

Gatemate E1 Board - SPI Flash Programming and Boot Operation

2023-10-08 FM4DD

These are my notes from analyzing the Cologne Chip Gatemate E1 DevBoard flash programming and flash boot operations, which I could not find (or overlooked) inside the Gatemate technical documentation. It answers the question what SPI protocol and speed is used during FPGA initialization from flash.

SPI Flash Signal Access

The Gatemate E1 board implements the Macronix MX25R6435F SPI Flash memory. The MX25R6435F is a 64Mbit (8MByte) Serial NOR Flash that can operate in multiple modes up to 80Mhz Quad SPI. Datasheet and details at: https://www.mxic.com.tw/en-us/products/NOR-Flash/Pages/Ultra-Low-Power-Flash.aspx

The Gatemate E1 board provides the J3 header that gives direct access to the SPI signal lines interfacing the flash IC. This is great for external programming with the Gatemate FPGA Programmer, and for connecting a oscilloscope/protocol analyzer. I am using a Kingst LA2016 (200MS/s) analyzer under Sigrok Pulseview.

The Gatemate E1 Board with header J3 (SPI flash interface) connected to the protocol analyzer

SPI Flash Programming

The E1 board has a onboard USB programmer interface, using the FTDi 2232H USB bridge IC. Direct programming of FPGA code into the flash can be done with openFPGALoader -b gatemate_evb_spi -f <bitstream-file>. For analysis I am using the "blink" example included as part of the Cologne Chip toolchain package. Below shows the programming step of the "blink" example, reporting a programming speed of 6MHz.

SPI Flash Programming Protocol

The binary bitstream file of the "blink" example starts with the following byte sequence:

fm@nuc7fpga:~/cc-toolchain-linux/workspace/blink$ hexdump -C blink_00.cfg.bit | head -2
00000000  d9 01 ed 96 10 4d d6 00  00 00 00 33 00 00 00 00  |.....M.....3....|
00000010  dd 01 8d f1 01 45 d7 c1  18 fc 40 82 28 08 08 02  |.....E....@.(...|

The bitsream file is 42198 bytes:

fm@nuc7fpga:~/cc-toolchain-linux/workspace/blink$ ls -l blink_00.cfg.bit 
-rw-r--r-- 1 fm fm 42198 Oct  7 09:36 blink_00.cfg.bit

Below trace shows the beginning 3 bitstream bytes "d9 01 ed", written into flash at address 0x00000000:

Zooming further in, the markers measure the clock period. The programming SPI speed shows as 6.25Mhz. It could be a little off because of the lower 50MHz sampling, the clock's sample points are not exact.

openFPGA Flash Programming - SPI Protocol Parameters

Parameter Value
SPI clock speed 6.25Mhz
SPI write CMD 0x02 (Page Program, 256 bytes)
SPI Polarity/Phase mode 0 (CPOL=0, CPHA=0)
SPI Duplex mode half-duplex (MOSI/MISO separate)

openFPGA SPI Programming Write Sequence

[power-up] - RDP/RES (release from deep pwrdown) - RDID - RDID - REMS - WREN - BE (block erase 0x000000) - RDSR (repeat until erase done) - WREN - RDSR - PP (1st 256 Bytes) - RDSR - PP (2nd 256 Bytes) - RDSR - ... - PP (last 214 Bytes) - RDSR (repeats, wait for write complete) - unknown_cmd(0xbc) - unknown_cmd(0x28) ...

(shortened for readability). 165 PP write commands are needed to transfer the 42198 byte bitstream data (164x256 bytes, + 1x214 bytes = 42198 bytes). Before writing the bitstream, a block erase (BE) command was issued that writes '1's into the first 64kbyte block area from 0x000000 to 0x00FFFF.

SPI Flash Boot

Below is the capture of the FPGA SPI boot sequence after power-up of the E1 board. We can see the FASTREAD command, followed bty the same "blink" program bitstream byte sequence we programmed before: "d9 01 ed 96 10 4d ..."

Also visible above is the existence of a single "dummy" byte after the MOSI command, and before the MISO output data. The SPI clock period measures as 30ns, or 33.33MHz. This requires setting the protocol analyzer to its highest sampling rate (and it is still not capturing the exact edge).

Gatemate E1 FPGA Boot - SPI Protocol Parameters

Parameter Value
SPI clock speed 33.33Mhz
SPI read CMD 0x0B (FAST_READ - all data in one go)
SPI Polarity/Phase mode 0 (CPOL=0, CPHA=0)
SPI Duplex mode half-duplex (MOSI/MISO separate)

Gatemate E1 FPGA Boot Sequence

[power-up] - RDID (8x repeat) - RDID/MFID - RDID - RDID/MFID - FASTREAD (42195 bytes) - CS up

Thanks to FASTREAD, the E1 board boots up in 23ms for the "blink" program.