This blog post gets you started with Project IceStorm, a fully open source Verilog-to-Bitstream flow for iCE40 FPGAs. First we will cover installation of the toolchain on Linux and Mac OS X. Then a simple blinky program is synthesized, routed and programmed on a Lattice iCEStick. At the end some further resources are collected.
Work in progress!
Overview
FPGA stands for "Field Programmable Gate Array", it is essentially a huge array of logic gates which can be arbitrarily connected to make a circuit of your choice.
Installation
Four tools need to be installed:
yosys
: Verilog RTL synthesis- Icarus Verilog: Verilog simulation and synthesis tool
iverilog
: The compilervvp
: Simulation runtime engine
arachne-pnr
: Place and route tool for FPGAs- icestorm: Tools for generating and manipulating iCE40 bitstreams
- icebox
- icebram
- icecompr
- icefuzz
- icemulti
icepack
- icepll
iceprog
- icetime
- chip databases
If you want to compile and install all four yourself and install in the default /usr/local
location, then you can use Dimitri del Marmol's excellent icetools set of scripts. Just run icestorm.sh
and you're set.
If you also want to visualize simulated waveforms you have to install a fifth tool GTKWave.
Linux
You can also install the tools
apt-get install verilog
apt-get install icestorm
apt-get install fpga-icestorm
Optional:
apt-get install gtkwave
Mac OS X
If you use Mac homebrew it is not a good idea to install into /usr/local
. You can use the following steps to install all four:
Prerequisites
brew install bison gawk pkg-config git mercurial graphviz python python3 libftdi0 libffi
Yosys and Icarus-Verilog
Fortunately yosys
and iverilog
are already packaged in homebrew:
brew install yosys icarus-verilog
Unfortunately, arachne-pnr
and icestorm
are not available on homebrew, yet, so we have to build them ourselves.
Icestorm
git clone https://github.com/cliffordwolf/icestorm.git
cd icestorm
PYTHONPATH=`brew --prefix`/lib/python$PYTHONVERSION/site-packages/ make -j
I don't want to install the tools in /usr/local
because that's owned by homebrew. Instead I'd like to use $HOME/.local
:
# dry run. Remove the -n to actually install
make -n install DESTDIR=$HOME/.local PREFIX=
Arachne-pnr
Arachne-pnr consists of the executable and three chip databases that contain the details of the topologies. Again, I choose to install into .local
instead of the default /usr/local
:
git clone https://github.com/cseed/arachne-pnr.git
cd arachne-pnr
make -n PREFIX=$HOME/.local
make -n PREFIX=$HOME/.local install
libftdi0
The iceprog
programmer is responsible for burning the bitstream onto the device. iceprog
uses the libgtdi0
library which cannot be used while the official FTDI USB serial driver is installed. To check whether FTDI's driver is installed run
kextstat | grep FTDIUSBSerialDriver
Then, if necessary, uninstall the FTDI driver.
sudo kextunload -b com.FTDI.driver.FTDIUSBSerialDriver
The driver can be re-installed with the opposite command:
sudo kextload -b com.FTDI.driver.FTDIUSBSerialDriver
Optional: GTKWave
brew install caskroom/cask/gtkwave
Blinky
Blinky is the "Hello World" for FPGAs. The goal is to get the green LED of the iCEStick board to blink continuously.
Verilog
blinky.v
// blinky.v
// Blink the green LED with frequency 12e6/2^24 = 0.7Hz approx.
module top (clk_in, led_green_out, led_red_out);
input clk_in;
output led_green_out;
reg [23:0] counter;
assign led_green_out = counter[23];
assign led_red[3:0] = 4'b0;
always @ (posedge clk_in) begin
counter <= counter + 1;
end
endmodule
Pin assignment blinky.pcf
:
set_io clk_in 21
set_io led_green_out 95
set_io led_red[0] 96
set_io led_red[1] 97
set_io led_red[2] 98
set_io led_red[3] 99
yosys -p "synth_ice40 -top top -blif build/blinky.blif" blinky.v
arachne-pnr -d 1k -P tq144 -o build/blinky.asc -p blinky.pcf build/blinky.blif
icepack build/blinky.asc build/blinky.bin
iceprog build/blinky.bin
Here's a Makefile for this workflow:
all: build/blinky.bin
build/blinky.bin: build/blinky.asc
icepack $< $@
build/blinky.asc: blinky.pcf build/blinky.blif
arachne-pnr -d 1k -P tq144 -o $@ -p $^
build/blinky.blif: blinky.v
yosys -p "synth_ice40 -top top -blif $@" $^
prog: build/blinky.bin
iceprog build/blinky.bin
clean:
rm build/*
.PHONY: prog clean
The default target is build/blinky.bin
. To write this to flash invoke the prog
target. Finally, clean the build directory with the clean
target.
Simulation
Time->Zoom->Zoom Full
Resources
Other Build scripts
- BQ labs have a complete set of build scripts for Linux, Mac OS and Windows.
PlatformIO
"PlatformIO is an open source ecosystem for IoT development"
Platform.io support a few iCE40 boards.
Verilog
- Verilog cheat sheet
- Digital Design and Computer Architecture: ARM Edition by Sarah Harris and David Harris, Morgan Kaufmann, 2015. Preview on Google books.