CONTENTS

Home
Updates
Software
Electronics
Music
Resume
Contact


YouTube
BlueSky
GitHub
LinkedIn


Open-Source FPGA Development

Posted: April 15, 2025
Updated: March 1, 2026

Introduction

This was originally instructions on how to build the open source dev tools for doing development with the Tang Nano board but has been updated for:

  • GOWIN GW2AR-LV18QN88C8/I7 (Sipeed Tang Nano 20K)
  • GOWIN GW2A-LV18PG256C8/I7 (Sipeed Tang Primer 20K)
  • Lattice ice40 (ice40)
  • MachXO2
  • ECP5

The open source tool to complile are yosys / nextpnr. For me, compiling yosys was pretty easy but nextpnr (or nextpnr-himbaechel) wasn't straight forward to compile on Ubuntu. It unfortunately needs some Python modules that aren't in the Ubuntu apt so it takes forcing the install from PIP. To not break my main Linux system I did the compile under Docker.

To make sure I didn't forget how to do this I'm writing it all down here. Further down this page there is also steps for compiling for ice40 in the same container. Hopefully this can help some others too. This document also assumes basic knowledge of Docker.

Hoping to clean this page up a little bit and organize it a little better ...

Related Projects @mikekohn.net

FPGA: FPGA VGA, Nexys2, Glow In The Dark Memory, Intel 8008, F100-L, RISC-V, x86 / 68000, MIPS, MSP430, PowerPC, W65C832, Apollo 11, PDP-11

Setting Up Docker

The first steps are to set up a docker container to hold all the development tools. This allows the tools to be build and installed without modifying (and possibly leaving files all over) the host's operating system.

If docker isn't installed, on Ubuntu it can be done with:

sudo apt install docker.io

After it installs, it might be good to add your username to the docker group so it doesn't have to be run with sudo.

First step after docker is installed is to pull the lastest debian image with docker:

docker pull debian:latest

Next the docker container can be started:

docker run --rm -it debian:latest /bin/bash

Building Yosys

The next step is to build Yosys. Yosys is the first step of building an FPGA project. To build it follow these steps:

apt update apt install git g++ cmake \ build-essential clang lld bison flex \ libreadline-dev gawk tcl-dev libffi-dev git \ graphviz xdot pkg-config python3 libboost-system-dev \ libboost-python-dev libboost-filesystem-dev zlib1g-dev

Next clone and build Yosys:

cd mkdir source cd source git clone https://github.com/YosysHQ/yosys.git cd yosys git submodule update --init --recursive make

GOWIN FPGA Support

Need to install some prerequisites for nextpnr-himbaechel:

apt install \ libboost-dev \ libboost-filesystem-dev \ libboost-thread-dev \ libboost-program-options-dev \ libboost-iostreams-dev \ libboost-dev apt install libeigen3-dev apt install pip pip install --break-system-packages apycula

There have been times when I've updated yosys / nextpnr without updateing apycula, which broke the builds from working properly... so apycula should be updated often. To udpate apycula at a later time:

pip install --upgrade --break-system-packages apycula

Next need to clone and build nextpnr-himbaechel:

cd cd source git clone https://github.com/YosysHQ/nextpnr.git cd nextpnr git submodule update --init --recursive mkdir build_gowin cd build_gowin cmake .. -DARCH="himbaechel" -DHIMBAECHEL_UARCH="gowin" make

Now all the dev tools should be built. The last thing missing is openFPGAloader. That didn't appear to be a part of Ubuntu either so it seems it needs to be built from source. This one is probably better though to build on the host and not in the container.

Before doing that, it would probably be a good idea to "commit" the container so instances of it can be started later without rebuilding the devkits. To save the container first the container id needs to be found. That can be done with:

docker ps

In my case, the container id is d20cae9d3ad2 so to save a new image based on a snapshot of this container with the image name fpga_dev:

docker commit d20cae9d3ad2 fpga_dev

This can take some time. After it finishes, this container can be exited. To start a new container based on the new fpga_dev image:

docker run --rm -it -v /code/fpga/gowin_blink:/fpga fpga_dev /bin/bash

The -v part is used to mount a directory from the host system /code/fpga/gowin_blink to /fpga inside the container. This will allow the Verilog project to be built in the container leaving the resulting binary on the host system. Also all files can be edited on the host rather than inside the container.

Inside the container some environment variables should be set:

export PATH=$PATH:/root/source/yosys:/root/source/nextpnr/build

A test program for the Tang Nano that blinks an LED with a Makefile can be downloaded here:

gowin_blink.tar.gz

The Makefile for the blink program looks like this:

PROGRAM=blink default: yosys -q \ -p "synth_gowin -top $(PROGRAM) -json $(PROGRAM).json -family gw2a" \ src/$(PROGRAM).v nextpnr-himbaechel -r \ --json $(PROGRAM).json \ --write $(PROGRAM)_pnr.json \ --freq 27 \ --vopt family=GW2A-18C \ --vopt cst=tangnano20k.cst \ --device GW2AR-LV18QN88C8/I7 gowin_pack -d GW2A-18C -o $(PROGRAM).fs $(PROGRAM)_pnr.json

To flash the board with the blink.fs file, build openFPGALoader on the host and do:

sudo build/openFPGALoader --scan-usb sudo build/openFPGALoader --ftdi-serial 2023030621 ~/source/fpga/gowin_blink/blink.fs

Replace 2023030621 with the serial number for the specific Tang Nano board.

Tang Primer 20k

To build a project with the Tang Primer 20k FPGA board, the following can be done:

nextpnr-himbaechel -r \ --json $(PROGRAM).json \ --write $(PROGRAM)_pnr.json \ --freq 27 \ --vopt family=GW2A-18C \ --vopt cst=tangnano20k.cst \ --device GW2A-LV18PG256C8/I7 gowin_pack -d GW2A-LV18PG256C8/I7 -o $(PROGRAM).fs $(PROGRAM)_pnr.json

Ice40

Some extra things can be done to have this container hold a devkit for ice40 too. First is to clone and build icestorm:

apt install libftdi1-dev cd cd source git clone https://github.com/YosysHQ/icestorm.git cd icestorm make make install

This installs chipdb in /usr/local/share/icebox. And then from nextpnr:

cd cd nextpnr mkdir build_ice40 cd build_ice40 cmake .. -DARCH=ice40 make

If there is a problem with nextpnr finding chipdb, then chipdb can be installed with:

apt install nextpnr-ice40-chipdb

Setting up a PATH variable so all the tools can be found:

export PATH=$PATH:/root/source/yosys:/root/source/nextpnr/build_ice40:/root/source/icestorm/icepack

As a side note: out of the docker container, I've sometimes had to do nextpnr cmake with:

cmake .. -DBUILD_PYTHON=0 -DARCH=ice40

ECP5 and MachXO2

To do either ECP5 or MachXO2, first libtrellis has to be installed. That can be done with:

git clone https://github.com/YosysHQ/prjtrellis cd prjtrellis/libtrellis cmake . make make install cd /usr/local/share/trellis git clone https://github.com/YosysHQ/prjtrellis-db.git rm -rf database ln -s prjtrellis-db database

To Build nextpnr with MachXO2:

cd cd source/nextpnr mkdir build_machxo2 cd build_machxo2 cmake .. -DARCH=machxo2 make

To Build nextpnr with ECP5:

cd cd source/nextpnr mkdir build_ecp5 cd build_ecp5 cmake .. -DARCH=ecp5 make

Copyright 1997-2026 - Michael Kohn