FPGA Helper

A programming and communication interface for FPGAs

Public Chat
Similar projects worth following
This project is a combination of open source hardware and software that provide features commonly needed in FPGA designs, primarily: programming interface, USB communication, and analog signals. While there are solutions for all these features today, they are typically not available in a single solution and in many cases they are not open and may require closed source utilities that are only available for a limited number of platforms. This project is being designed to run on any operating system and being an open source project, the features of this project can be expanded over time to add additional utilities and support for more targets.

The goal of this project is to bring FPGA development one step closer to Adafruit easy.

This project is a combination of open source hardware and software that provide features commonly needed in FPGA designs, primarily: programming interface, USB communication, and analog signals.  This project is being designed to run on any operating system and being an open source project, the features of this project can be expanded over time to add additional utilities and support for more targets.


Since this project is intended to be used with any operating system, the initial target will be the Lattice iCE40 series since Project IceStorm is the only tool that runs on multiple operating systems.  IceStorm currently supports the iCE40 HX1K, HX8K, and UltraPlus.  The initial version of the FPGA-Helper board will be able to connect directly to the following boards:

Programming (SPI):

In order to provide "Adafruit easy" programming on multiple operating systems, the FPGA-Helper will allow for drag-n-drop programming using USB Flashing Format (UF2).  The initial version of the board has an SOIC 8 location that can be loaded with a larger flash device to allow for upgrading the size of the flash provided on the target board.

USB Communication (UART):

The FPGA-Helper will implement a standard USB-CDC virtual serial port that can be used for communication between the FPGA and a computer.

Analog I/O (I2C):

The FPGA-Helper will implement the seesaw protocol to give the FPGA access to additional peripherals in the programmer MCU.

  • 1 × NSR05F30NXT5G Discrete Semiconductors / Diodes and Rectifiers
  • 1 × FTSH-105-01-F-DV-K Connectors and Accessories / Board-to-Board and Card Edge Connectors
  • 1 × 61201021621 Electronic Components / Misc. Electronic Components
  • 1 × W25Q64JVSSIQ 64Mbit SPI Flash Memory
  • 1 × APA102-2020 Serial RGB LED

View all 11 components

  • November Update

    greg11/25/2018 at 16:50 0 comments

    I haven't had much time and things are progressing slowly, but I have made some progress.  I was able to add support for the on board flash in circuitpython so that it can be used for the circuitpy drive storage.  The code is posted in my github repo:

    I added a new fpga_helper_express board in addition to the fpga_helper board to keep the option not to use the on board flash for circuitpython.  The reason I want to keep this option is because circuitpython will put a file system on the flash that is not compatible with the internal SPI loader in the FPGA, and it will be difficult to share a single flash device with both circuitpython and the FPGA.  When this circuit gets integrated on a board with the FPGA, I don't want to require two SPI flash devices.  I will need to modify circuitpython to put the binary image on the flash without the file system so the FPGA can load directly from it.  This work is TBD.

    Another option would be to have circuitpython push the image from flash into the FPGA.  The reason I am avoiding this is because many FPGA's from a variety of vendors can load from similar SPI flash that are straightforward to program.  If were to push the code into the FPGA using circuitpython, I would have to customize it for every different target, which I would rather not do.   

    FPGA's with integrated storage are different story, since there is no external SPI device to program.  The MachXO2/3 series from Lattice have internal non-volatile storage that can be loaded through JTAG, SPI or I2C.  Since the I2C signals are so easy to get to with the qwiic connector, I think I will work to add support to configure the MachXO2/3 using circuitpython.  Using the on board flash to cache the image in this case is not as much of a penalty if you are only using this board as a programmer and disconnect it when you are done.  You can program as many targets as you want with the single programmer.  The extra flash device is more of a burden if you are integrating it permanently.

  • September 30th Update

    greg10/01/2018 at 05:10 2 comments

    The board is up and running and software development is making good progress.

    The UF2 bootloader and CircuitPython are up and running on the board. 

    The dotstar LED and QWIIC I2C connector are both accessible through CircuitPython.  Here is a link to a video showing the board fading the LED and reading a Qwiic NFCPROM:

  • The obligatory blinking lights video

    greg09/05/2018 at 03:17 0 comments

  • It's alive!

    greg09/03/2018 at 05:25 0 comments

    I received the boards and they passed the smoke test.  Great job MacroFab!

    It didn't take too long to get the uf2-samdx1 bootloader running on it:

    I started working on circuitpython and seesaw ports, but those will take a bit more time.  For now I will focus on the basic uf2 interface to the SPI flash.

  • Did I mention CircuitPython?

    greg08/20/2018 at 00:26 0 comments

    As mentioned previously, UF2 was created to make it easier to work with CircuitPython.  The boards upon which this circuit is based were designed to run CircuitPython and one of the first steps for bringing up and checking out this board will be to port and run CircuitPython.  Having a board like this capable of running CircuitPython could almost justify the project on its own.  This will be on of the first CircuitPython boards with any of Qwiic, UEXT, and PMOD connection options, let alone all three.  CircuitPython also provides an easier way for FPGA developers create scripts and utilities in an environment that might be easier for them to work with than the native embedded C/C++.  

  • Power Considerations

    greg08/20/2018 at 00:12 0 comments

    The primary power input for the board will be +5V from the USB connector.  This will need to be regulated down to +3.3V for all the circuitry on the board.  In the case where the flash memory is populated on this board and it is connected to provide the image to the target FPGA, it should not be necessary to connect the USB cable and the board will draw power from the target board through the PMOD or UEXT connector.  To enable two different power sources, a diode is placed in-line with the USB power input and a Pch MOSFET is connected in-line with the PMOD/UEXT power pins.  The gate of the MOSFET is connected to a voltage divider from the USB power input so that the MOSFET is off when USB power is present, and enabled when only the PMOD/UEXT power is present.  The gate is also tied to PA28 on the MCU so that the controller can detect when USB power is present, and so that it can also override the signal to deliver power from USB to the PMOD or UEXT connectors for additional flexibility.

  • Connection Details

    greg08/20/2018 at 00:03 0 comments

    Here are details on the connector pinouts:

    Micro USB












  • Board Strategy

    greg08/19/2018 at 23:28 0 comments

    With a framework in mind and the host controller family selected, the next step is determining what all needs to be connected to the controller.  Let's start by listing the features:

    • USB connector
    • Target Interface (SPI, I2C, UART)
    • Analog/GPIO
    • RGB LED
    • Reset button
    • In-circuit debug connector

    The target interface consists of multiple interfaces and deserves some additional consideration.  

    The SPI interface will be connected to a serial flash device in parallel with the target FPGA.  We can hold the FPGA in configuration reset and load code into the flash device on the target board, or we can load code into a flash device mounted on this board with the target board in configuration reset or disconnected.  The SPI programming bus is located at two headers on the iCE40UP breakout board, one pinned out for an Ardvark connector which does not have any power, and one at a dual row PMOD header with power and 4 additional I/O.  We will target the PMOD header so we have access to power and the additiona I/O.  The Olimex boards connect the programming signals to a UEXT connector.  In addition to the SPI signals, the UEXT connector also includes CRESET, CDONE and two I/O in the UART locations.  The I2C signals in the UEXT connector are used for CRESET and CDONE, so we will need another connector to get I2C to the Olimex boards.  To keep the board area down, I will add a Qwiic connector for the extra I2C port.

    Since much of the code will be coming from Adafruit projects, I will use the same RGB LED connections found on the Tricket M0 and ItsyBitsy boards.

    The debug connector will primarily be used for development so I will use a small SMT connector on the back side of the board that can be left off in production.  There is a standard 50mil pitch 10pin header that is common with ARM MCU's and there is even room for a debug console UART if you follow the MAXDAP pinout from the MAX32625PICO board.

    For the extra analog/GPIO signals, I'll include another single row header with an extra power and ground signal.

  • Where to begin

    greg08/19/2018 at 22:54 0 comments

    The goal of this project is to make FPGA development much easier and more accessible, similar to the recent advances in embedded firmware development.  We will need to address many of the same issues, like how to conveniently load code into hardware, and how to communicate with a computer, and how to support development on more than one operating system.  Fortunately, many of the advancements in embedded firmware development are directly applicable so we can learn from them and apply the best practices.  

    The most operating system agnostic implementation that I have seen is the cloud based ARM mbed environment.  While a cloud based development environment has limitations, the use of USB mass-storage class drag-n-drop for programming is a great idea that is spreading.  There is a great summary of the genesis of the UF2 file format at the makecode blog which pretty much covers all the reasons why I have chosen to use this for the programming interface in this project.

    The UF2 bootloader was originally implemented on the SAMD21 which is very popular at Adafruit.  In addition to the bootloader code, there are many other open source programs available for this MCU (like seesaw and CircuitPython).  In order to keep the scope of this project manageable, I will use the SAMD21 so that I can spend less time porting to a new platform, and more time on the critical features.

View all 9 project logs

View all 4 instructions

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates