Files
website/content/posts/mimasfirmware-01.md
Jojojoppe 4ff4ecb4f3
All checks were successful
Build and deploy Hugo website / build-and-deploy (push) Successful in 8s
Created first 3 blogposts from old website
2025-06-18 17:30:18 +02:00

7.0 KiB

+++ title = "Mimas Spartan 6 FPGA - New firmware, driver and PC-FPGA interface" tags = ["Driver", "Embedded", "Firmware", "FPGA"] date = "2022-03-17" +++

View project on github

The Numato Lab Mimas Spartan 6 FPGA development board is a simple FPGA development board with a Xilinx Spartan 6 (xc6slx9) on it with a usb interface for programming the on-board flash. The flash is a 16 Mb SPI flash connected to both the FPGA an a Microchip PIC (18f14k50). The PIC runs firmware which presents itself as serial port to the connected PC and uses a python script to upload the generated bit-file.

Since the original firmware used a 9600 baud serial connection, the uploading of the bitfile it takes quite some time to upload. And next to that communication between the FPGA and the USB port is not implemented even though the PIC has connections to the FPGA. This was the reason to develop new firmware which could program the SPI flash faster and has an FPGA-USB interface for serial communication and/or datalogging purposes (like a logic analyzer).

The repository for this project contains the firmware for the PIC (in the firmware folder), the driver for programming and comunicating with the PIC (in the driver folder) and some usefull VHDL blocks for communication between the PIC and the FPGA. Information specific for the firmware, driver of hardware are located in their folders.

FPGA-PIC Interface

The full schematics of the Mimas board can be found here (which are published by Numato Lab under the CC BY-SA licence). The relevant parts are shown below. As can be seen, 7 lines are directly connected to the FPGA (D[0..3], CLK, RD and WR) next to the SPI bus which both the FPGA and the MCU use to communicate to the SPI flash. The SPI bus is used for the communication between the FPGA and the MCU (while keeping the SPI flash disabled). Next to the SPI bus the CLK line from the mentioned signals is used as reset line to reset the FPGA from the MCU.

PIC side of the FPGA-PIC interface
PIC side of the interface
FPGA side of the FPGA-PIC interface
FPGA side of the interface
Hardware-firmware interface pinout of the IP block
Interface IP block pinout

The project also provides an IP block written in VHDL which can be used together with this interface. It translates the serial data into 6 general purpose ports and two 8 bit channels. Each time a serial transfer takes place the IP block sends out the status of the 6 general purpose inputs and the internal buffer for channel 0 and 1 while it receives the values for the 6 general purpose outputs and the data for channels 0 and 1. When the transfer is complete the GPIO data and the channel data are clocked to the output and the valid line for the channel is held high for one clock period.

The transfer message consist out of 3 bytes: one status byte with GPIO values and a byte for each channel. The status byte has the 6 GPIO bits and a bit for both channels indicating if the corresponding byte contains valid data. If this bit is low it means that there is no data transfered over that channel. All data is sent MSB first.

Serial transfer layout
Serial transfer layout

With the current SPI settings on the MCU the communication happens at roughly 272 kB per second over SPI if all the SPI transfers are spaced like in the captured image below. Unfortunately due to the path the data takes (PC->USB->MCU->SPI and back) the spacing between consecutive 'packets' are much larger and results in roughly 15 kB per second (or 5000 transfers per second/bps over one endpoint).

Signals captured with a logic analyzer
Signals captured with a logic analyzer

USB Message Format

The PIC registers itself as a classless USB device with device ID 0000:0001. It serves one endpoint on interface 0 which is used for all communication. The commands and other data are done with bulk writes/reads and the message layout is as stated in the table below.

NOTE: The USB device ID is not a registered and valid VID-PID pair! Feel free to change the pair (which should be done in firmware/usb_descriptors.c line 14-15 and driver/mimasdriver/mimas_interface.py line 6-7).

Command group Command Arguments Extra info
NOP (0x00) Does nothing
FLASH (0x01) NOP (0x00) Does nothing
FLASH (0x01) PROGRAM (0x01) llllaaaa Write a sector starting from a for l bytes
FLASH (0x01) READ (0x02) llllaaaa Read a sector from flash starting from a for l bytes. Perform l/64 bulk reads.
FLASH (0x01) GETID (0x03) Get the flash ID. Perform 1 bulk read.
HF (0x02) NOP (0x00) Does nothing
HF (0x02) TRANSFER (0x01) GAB Transfer one message to the FPGA. G contains the GPIO bits and the status bits and A and B contain the channel data. Perform 1 bulk read to get a message back (in the same format).
HF (0x02) HRST (0x02) Assert reset line
HF (0x02) LRST (0x03) Deassert reset line

Why not…

  • Why not adding a simple serial link between the FPGA and the PIC instead of the SPI interface with two channels? Well… I wish I could have done that. As can be seen in the schematic the RX line is used as SPI chip select for the flash so using the hardware UART in the PIC is not an option, hence this bit-banged solution.

  • Why not using USB-CDC for the communication instead of this custom protocol? To be honest, I wanted to do that! Unfortunately I couldn't get the combination of custom endpoint for programming and CDC class interface for communication working correctly so I switched it to the current setup. This does not mean that it wont be implented forever though. Next to that I really want to design some on-chip logic analyzers which is easier with the current setup than to do that over UART.