Open-Source FPGA Toolchains: Yosys, nextpnr, APIO
An FPGA project needs tools that turn RTL into a configured device. Vendor tools are common in industry, but open-source flows are excellent for learning because the stages are visible: lint, simulate, synthesize, place, route, pack, program, and inspect reports.
Learning Objectives
By the end of this lesson, you should be able to:
- name the main stages from HDL source to programmed FPGA;
- explain what Yosys, nextpnr, IceStorm, Project Trellis, Verilator, Icarus Verilog, GHDL, GTKWave, and APIO do;
- run a basic open-source iCE40 build flow;
- understand which commands are board-family-specific;
- identify common toolchain and constraints failures.
The Toolchain Stack
Simulation proves intended behavior for test cases. Synthesis maps RTL to logic resources. Place-and-route maps that logic to actual locations and wires in the selected FPGA. Bitstream packing converts the routed design into the device configuration format.
Common Open-Source Tools
| Tool | Job | Typical use |
|---|---|---|
| Yosys | Synthesis from Verilog/SystemVerilog subset | map RTL to FPGA resources |
| nextpnr | Place-and-route | implement a netlist on a selected FPGA |
| Project IceStorm | iCE40 database, packing, programming helpers | iCE40 learning boards |
| Project Trellis | ECP5 database support | Lattice ECP5 devices |
| Verilator | Fast linting and simulation for Verilog/SystemVerilog | CI and larger simulations |
| Icarus Verilog | Lightweight Verilog simulation | beginner testbenches |
| GHDL | VHDL analysis, elaboration, and simulation | VHDL projects |
| GTKWave | Waveform viewing | inspect VCD/FST traces |
| APIO | Beginner project wrapper | board projects and repeatable commands |
Open-source support depends on device family. Always check whether your exact FPGA, package, board programmer, and constraint format are supported.
Example Raw iCE40 Flow
This conceptual sequence targets an iCE40 UltraPlus 5K device. Your board may need different package, clock, pin, and programmer settings.
yosys -p "read_verilog blinky.v; synth_ice40 -top blinky -json blinky.json"
nextpnr-ice40 --up5k --package sg48 --json blinky.json --pcf blinky.pcf --asc blinky.asc
icepack blinky.asc blinky.bin
iceprog blinky.bin
Read it like this:
yosysreads RTL and writes a synthesized JSON netlist;nextpnr-ice40places and routes for the selected iCE40 device/package and PCF constraints;icepackpacks the routed ASCII design into a binary bitstream;iceprogprograms the board.
APIO for Beginner Projects
APIO wraps common open-source FPGA commands behind project-level commands. It is useful when the lesson goal is FPGA design rather than command flag archaeology.
apio examples fetch alhambra-ii/getting-started
apio lint
apio sim
apio build
apio test
apio devices scan-usb
apio upload
Use the wrapper, but do not let it hide the engineering flow. You still need to know which files define source modules, testbenches, pins, clocks, board targets, and expected timing.
Constraints and Board Files
The RTL signal name led does not automatically know which physical pin connects to LED1. That mapping comes from constraints. For a simple iCE40 PCF file:
set_io clk 35
set_io led 21
Other families use different formats. Xilinx projects commonly use XDC. Intel projects use QSF plus SDC timing constraints. Lattice examples may use PCF, LPF, or family-specific files depending on the toolchain.
Constraint files are design inputs, not optional decoration. A wrong pin can make a correct design appear broken. A missing clock constraint can hide a real timing failure.
Worked Example: Choosing a Flow
Scenario: You have an iCE40 learning board and want to blink an LED.
A disciplined beginner loop is:
- fetch or create a known-good board project;
- confirm the board target, package, and programmer;
- run
apio lintor a direct simulator/linter command; - run a small simulation if the module has behavior beyond a wire;
- run
apio buildor the raw Yosys/nextpnr flow; - read warnings, utilization, and timing output;
- run
apio uploador the board programmer; - change one thing and repeat.
This loop keeps failures local. If you change board files, RTL, constraints, and upload method all at once, debugging becomes unnecessarily difficult.
Exercise
Create a project notebook table for your board:
| Stage | Command | Main output | Failure symptom |
|---|---|---|---|
| Lint | |||
| Simulation | |||
| Synthesis | |||
| Place-and-route | |||
| Pack bitstream | |||
| Upload |
If you do not have hardware yet, fill it for an iCE40 board using the example commands above. Add the exact FPGA part number, package, oscillator frequency, and LED pin from the board documentation.
Common Mistakes
- Copying commands without changing device, package, or board options.
- Forgetting the constraint file or using a constraint file for another board.
- Simulating a testbench successfully but never checking synthesis warnings.
- Treating timing warnings as harmless text.
- Uploading to hardware before checking pin voltage and board schematic.
- Assuming open-source support covers every feature of every FPGA family.
Summary
Open-source FPGA flows make the build process visible. Yosys synthesizes RTL, nextpnr places and routes supported families, family tools pack and program bitstreams, and APIO can wrap the loop for students. Learn the raw stages first, then use wrappers to move faster without losing sight of constraints, reports, and device support.
Next: Design Flow: Synthesis, Place-and-Route, and Bitstream.
Further Reading
- Yosys documentation: synthesis commands and
synth_ice40. - nextpnr documentation and supported architecture notes.
- APIO documentation and board examples.
- Project IceStorm and Project Trellis documentation.
- Verilator, Icarus Verilog, GHDL, and GTKWave documentation.