Programming an Acorn¶
This page explains how a design reaches an Acorn on fpgas.online, in three layers: the protocol, the connection and the tool. It does not give the commands. Loading is on How to run JTAG by hand on an Acorn on a Raspberry Pi 5. Writing the flash is on How to install the fpgas.online images on an Acorn. The card’s own hardware is on Acorn specifications.
Figure to come
The three layers: JTAG as the protocol, the host’s GPIO pins to P1 or PCIe as the connection, openFPGALoader, OpenOCD and spi_flash.py as the tools. Tracked in docs issue #122.
The protocol: JTAG¶
The Acorn is configured over JTAG. A load over JTAG lands in the FPGA’s SRAM and is gone at the next power cycle. A JTAG load works whatever the card has loaded.
Anything persistent has to go into the SPI flash. The command openFPGALoader --write-flash does not work over the
GPIO JTAG wiring, because its spiOverJtag bridge never toggles CCLK after configuration. Over that wiring JTAG can
only load volatile SRAM.
The connection: GPIO pins to P1, or PCIe¶
PCIe comes through the M.2 slot of the host. JTAG, the serial pair and the spare wires are carried on two cables to GPIO pins of the host. The wiring depends on the carrier the Pi sits in, which sets how many GPIOs it brings out, and not on the site.
GPIO pins to P1¶
On a Raspberry Pi 5 with an M.2 HAT the full 40-pin header is available:
P2 goes to header pins 5-10 and P1 to header pins 19-26.
JTAG has its own pins,
10:9:11:8in the order TDI:TDO:TCK:TMS.The serial pair is on GPIO14/15, and both spare balls (J5, H5) are wired.
libgpiod opens
gpiochip0, so on a Pi 5/dev/gpiochip0must be the header’s chip, the RP1’s. Its number varies from 11 to 15:gpiochip15under kernel 6.12.
On a Compute Blade with a CM4 or CM5 only GPIO2, 3, 4, 14 and 15 are brought out:
P1 goes to the Extension Port, and JTAG is
2:3:4:14: the I²C pair, GPIO4 and the UART TX line.P2’s serial pair goes to the 4-pin UART header, and J5 and H5 are not connected.
The UART header’s TX pin is the same GPIO14 as TMS. The J2 wire has a 470 Ω resistor in it, so that JTAG wins by design; its measurement is test-designs issue #221.
The
gpiochip0link of the Pi 5 is not made, and the PCIe bus address differs per blade.
On both carriers the serial pair lands on the same GPIOs: K2 (FPGA TX) on GPIO15 and J2 (FPGA RX) on GPIO14. One set of FPGA pin constraints and one set of host scripts therefore serves every host.
The pin order and the Pi 5 link are in JTAG from the Pi. The
overlayroot=tmpfs trap is in How to run JTAG by hand on an Acorn on a Raspberry Pi 5. The blade is in
How to run JTAG by hand on an Acorn on a Compute Blade.
Warning
Detach the PCIe endpoint before loading a bitstream. Reconfiguring the FPGA underneath an enumerated endpoint is a surprise removal, and the BCM2712 root complex does not survive it: the host crashes. The rule, the per-host bus address and bringing the endpoint back are in why the endpoint is detached before a load.
PCIe¶
PCIe programming only works on a board that is running a LiteX design with PCIe. With the fpgas.online Acorn design
running, the flash is written over PCIe BAR0 with spi_flash.py. That moves a board onto the golden and operational images, and updates the operational image. The steps are on
How to install the fpgas.online images on an Acorn.
A board on the SQRL factory firmware or the vendor XDMA image first needs the design loaded into SRAM over JTAG. Which bitstreams to use, and which prebuilt ones not to, is under Images.
The tools: openFPGALoader, OpenOCD and spi_flash.py¶
openFPGALoader bit-bangs JTAG through libgpiod; a full XC7A200T bitstream of 1.6 MB takes about 16 s. OpenOCD loads the 2.3 MB fpgas.online SoC over the same wiring in about 24 s. Both load to SRAM only, which is what makes it safe to experiment with.
spi_flash.py is standard-library Python over BAR0 and needs no kernel module. It reads the 32 MiB flash in 58 s and
erases, writes and verifies a 4 MiB slot in about 20 s.
The paths compared¶
Method names the path, Speed what it takes, Persistent whether the result survives a power cycle, and Requires what must be in place first.
Method |
Speed |
Persistent |
Requires |
|---|---|---|---|
GPIO JTAG to SRAM |
16 s (openFPGALoader, 1.6 MB); 24 s (OpenOCD, 2.3 MB) |
No |
the P1 JTAG wiring, with the PCIe endpoint detached first |
PCIe to SPI flash, |
58 s to read 32 MiB; about 20 s for a 4 MiB slot |
Yes |
the fpgas.online Acorn design running, from flash or loaded into SRAM over JTAG |
PCIe to SPI flash, |
waits for its run: test-designs issue #220 |
Yes |
a LiteX PCIe design and the |