Tech News
← Back to articles

Interesting SPI Routing with iCE40 FPGAs

read original related products more articles

A few weeks ago I posted about how much fun I was having with the Fomu FPGA development board while travelling. This project from Tim ‘mithro’ Ansell and Sean ‘xobs’ Cross is not new, but remains a favorite of mine because of how portable it is — the entire board can fit in your USB port!

The Fomu includes a Lattice Semiconductor iCE40 UltraPlus 5K, which has been a popular FPGA option over the past few years due to the reverse engineered bitstream format and ability to program it with a fully open source toolchain (see updated repository here). One of the more recent production uses I have heard about is in the Oxide Computer, which I discussed with Nathanael Huffman on an episode of Microarch Club and has also come up on the Oxide & Friends podcast.

One of the most interesting attributes of the Fomu is that, despite the fact that it is programmed over USB, it doesn’t actually include any USB peripheral hardware. Instead, in order to make the board small enough to fit in the USB port, the USB core is implemented in RTL (Fomu uses ValentyUSB) and is included in the Foboot bootloader. Most FPGAs support writing bitstreams directly into SRAM, meaning that it will have to be reprogrammed after a power cycle, or storing a bistream in a separate flash IC that the FPGA will read from when powered on. iCE40 FPGAs are no different, but also include a Non-Volatile Configuration Memory (NVCM), which allows for one-time programming of a bitstream in high-volume applications. From the iCE40 Programming and Configuration Technical Note:

iCE40 components are configured for a specific application by loading a binary configuration bitstream image, generated by the Lattice development system. For high-volume applications, the bitstream image is usually permanently programmed in the on-chip Non-volatile Configuration Memory. However, the bitstream image can also be stored externally in a standard, low-cost commodity SPI serial Flash PROM. The iCE40 component can automatically load the image using the SPI Master Configuration Interface. Similarly, the iCE40 configuration data can be downloaded from an external processor, microcontroller, or DSP using an SPI-like serial interface.

Given that the Fomu is primarily intended for prototyping and education, utilizing the NVCM is unnecessary. However, it does include a GD25Q16CEIGR flash chip for persistent bitstream storage. Despite the Fomu hardware also being open source, I hadn’t spent much time looking at the schematic when developing with it in the past. However, while on the plane ride back from my travels, I was reading some of the documentation for the device and became curious about how the device supported both loading bitstreams into SRAM on the iCE40 and into the external flash.

Other FPGA development boards, such as the Arty A7 I have previously written about, support configuring the FPGA’s SRAM by including a USB to Serial IC (the Arty A7 uses the FTDI FT2232HQ) that can be used to configure the FPGA directly, or configure the FPGA with a bitstream that allows it to talk to the SPI flash, which is subsequently used to store the user bitstream in flash. From the Arty A7 reference manual:

When programming a nonvolatile flash device, a bitstream file is transferred to the flash in a two-step process. First, the FPGA is programmed with a circuit that can program flash devices, and then data is transferred to the flash device via the FPGA circuit (this complexity is hidden from the user by the Xilinx tools). This is called indirect programming. After the flash device has been programmed, it can automatically configure the FPGA at a subsequent power-on or reset event as determined by the mode jumper setting.

However, as previously mentioned, the Fomu’s USB core is implemented in RTL, which presents a few challenges. Namely, the FPGA needs to be “bootstrapped” — we cannot configure the FPGA or the SPI flash via USB without the USB core already running on the FPGA. Fomu uses a bootloader, Foboot, which includes gateware for a RISC-V core (VexRiscv) and various peripherals, as well as software for USB and DFU suppport. If you buy a Fomu, Foboot will already be present on the device. You can update Foboot using the Booster program, but if you somehow perform a faulty update, you could find yourself with a bricked device that cannot be accesed over USB. In that case, you’ll need to be able to access the components by some other means. Or, if you’re like me, you might just be interested in loading alternative gateware and software onto the device.

The Fomu hardware repository has a nice image with some of the board’s test points labeled.

The first thing that I noticed was that there was only one “chip select” ( SPI_CS ) test point. Both the FPGA and the flash IC can act as SPI peripherals, and typically a CS line is required from the controller to each peripheral in a multidrop configuration, or peripherals can be daisy-chained if supported. The iCE40 is particularly interesting in this scenario because, as previously mentioned, it can act as a controller when reading from the flash IC, or as a peripheral when being configured directly. When supplying power, the iCE40 will act as a SPI controller by default and attempt to load a bistream from the flash IC. If we want to program the flash directly via the test points, then we need to keep the iCE40 from attempting to control it. This is possible because the CRESET pin is also available on a test point.

... continue reading