This guide takes you from zero to a running design on a Xilinx Series 7 development board using only open-source tools. No Vivado, no licenses:
- Yosys — RTL synthesis (
synth_xilinx) - nextpnr-xilinx — place and route
- prjxray + prjxray-db — bitstream generation (
fasm2frames,xc7frames2bit) - openFPGALoader — programming the board over JTAG
Supported device families: Spartan-7, Artix-7, Kintex-7 and Zynq-7. Demo designs live in the demo-projects repository; their CI matrix shows which board/design combinations pass on the current toolchain.
- Linux (or macOS x86; Windows users should use the container option)
git- A Series 7 development board and its USB cable (JTAG, usually FTDI-based)
- ~10 GB of free disk space
Pick one of the four options below. Nix is the recommended path because it gives you one shell with all tools, consistent versions, and nothing installed into your system.
Install the Nix package manager:
sh <(curl -L https://nixos.org/nix/install) --daemonEnable flakes by adding this to ~/.config/nix/nix.conf (or /etc/nix/nix.conf):
experimental-features = nix-command flakes
Then enter a shell with the complete toolchain:
nix develop github:openXC7/toolchain-nixThe shell sets up PATH, PYTHONPATH, PRJXRAY_DB_DIR, and the chip database
variables automatically. First run downloads everything — the shell prompt
should change to [nix(openXC7)] when you are in.
For Windows, WSL, or macOS, or if you prefer a fully isolated environment:
git clone https://github.com/openXC7/toolchain-nix
cd toolchain-nix/container
make build
make runInside the container, clone the demo projects and build as usual (see below).
You can also build an image directly with
nix build -L ".#dockerImage.x86_64-linux" and run it with docker run.
The simplest pip-installable option:
pip install apio
apio install systemSee the Apio documentation for supported boards and usage.
The toolchain-installer repository has a script that downloads, builds and
installs everything into /opt/openxc7:
git clone https://github.com/openXC7/toolchain-installer
cd toolchain-installer
./toolchain-sources-builder.sh
source /opt/openxc7/export.sh # adds tools to PATH etc.Building from source takes a while (yosys, nextpnr-xilinx, prjxray and the database), but it works on any Linux without Nix.
The demo projects repository contains a blinky project for many boards.
Pick the one that matches your board, for example the Digilent Arty A7:
git clone https://github.com/openXC7/demo-projects
cd demo-projects/blinky-digilent-artyBuild the bitstream:
makemake runs the whole flow: Yosys synthesis, nextpnr-xilinx place and route,
bitstream assembly. When it finishes you have:
| File | What it is |
|---|---|
blinky.json |
Synthesized netlist |
blinky.fasm |
Placed and routed design (FASM format) |
blinky.frames |
Converted configuration frames |
blinky.bit |
Final bitstream, ready to program |
Program the FPGA:
make programThis invokes openFPGALoader --board <BOARD> --bitstream blinky.bit. The
BOARD name is defined in each project's Makefile. If the LED does not
blink, see Troubleshooting.
On other boards, the steps are identical — only the directory changes:
| Project | Board | Family | Part | openFPGALoader --board |
|---|---|---|---|---|
blinky-digilent-arty |
Digilent Arty A7 | artix7 | xc7a35tcsg324-1 |
arty |
blinky-digilent-basys-3 |
Digilent Basys 3 | artix7 | xc7a35tcpg236-1 |
basys3 |
blinky-digilent-zybo |
Digilent Zybo Z7-10 | zynq7 | xc7z010clg400-1 |
zybo_z7_10 |
blinky-qmtech |
QMTech Kintex-7 | kintex7 | xc7k325tffg676-1 |
qmtechKintex7 |
blinky-stlv7325 |
Sitlinv STLV7325 | kintex7 | xc7k325tffg676-1 |
stlv7325 |
blinky-kc705 |
Xilinx KC705 | kintex7 | xc7k325tffg900-2 |
kc705 |
blinky-genesys2 |
Digilent Genesys 2 | kintex7 | xc7k325tffg900-2 |
genesys2 |
The toolchain has no board-specific binaries: any supported Series 7 board can
be targeted, provided the correct FAMILY, PART, BOARD and pin
constraints are set.
Each demo project is a few files. blinky-digilent-arty contains:
blinky.v— the Verilog designblinky.xdc— pin and timing constraints (openXC7 dialect of XDC)Makefile— selectsFAMILY,PART,BOARDandPROJECT, includes../openXC7.mk
The shared openXC7.mk defines the build rules:
yosys -p "synth_xilinx ..."— synthesize to a JSON netlistnextpnr-xilinx --chipdb ... --xdc ... --json ... --fasm ...— place & routefasm2frames --part ... --db-root ...— convert FASM to configuration framesxc7frames2bit ...— assemble the bitstream
Environment variables the Makefiles use (exported automatically by the Nix shell, or set them yourself when building from source):
NEXTPNR_XILINX_DIR,NEXTPNR_XILINX_PYTHON_DIR— nextpnr-xilinx locationPRJXRAY_DB_DIR— prjxray database<FAMILY>_CHIPDB— chip database directory, e.g.ARTIX7_CHIPDBfor artix7. Point it atdemo-projects/chipdb/; prebuilt chip databases are committed there, so you normally never need to regenerate one.
Once your board blinks, try:
- Another blinky project from the table above — compare the flow, not the code
litex-ddr-arty-s7orlitex-minimal-arty-s7— a LiteX SoC with DDR supportpicosoc,vexriscvorserv— small RISC-V SoCsprimitive-tests— standalone tests for FPGA primitives (LUTs, DSPs, BRAM, IO logic)
The test matrix dashboard shows the current pass/fail state of every demo project on recent CI runs — useful to check that your board/design combination is expected to work.
Copy an existing blinky directory, then edit four things:
FAMILY = artix7 # one of spartan7, artix7, kintex7, zynq7
PART = xc7a35tcsg324-1
BOARD = arty # openFPGALoader board name
PROJECT = mydesign # name of your top module and .xdc fileAdd mydesign.v and mydesign.xdc in the same directory, then make.
- Issues: openXC7/nextpnr-xilinx, openXC7/demo-projects
- Chat: the openXC7 Matrix room
- More documentation:
nextpnr-xilinx/docsin the source tree
make reports missing nextpnr-xilinx, fasm2frames or xc7frames2bit
You are not in the toolchain environment. Enter it (nix develop github:openXC7/toolchain-nix), shadow the container, or source
/opt/openxc7/export.sh if you built from source.
make wants to rebuild a chip database and fails on bbaexport
The <FAMILY>_CHIPDB directory must contain a prebuilt device .bin. Use the
committed one in demo-projects/chipdb/ and export the matching variable,
e.g. export ARTIX7_CHIPDB=/path/to/demo-projects/chipdb.
make program cannot find the cable
Check the board is connected and visible:
openFPGALoader --detectOn Linux, FTDI cables need the right permissions; see the openFPGALoader installation notes for udev rules.
Programming succeeds but the design does nothing
A .bit can assemble and program successfully and still be wrong — e.g. after
a truncated intermediate file. Delete the build artifacts (make clean) and
rebuild. Check your FAMILY/PART in the Makefile against the board, and
your pins in the .xdc against the board schematic.