This is a simple demo for compiling of Haskell code into FPGA configuration.
Field Programmable Gate Arrays (FPGAs) are a cheap and fast tool for prototyping hardware descriptions that can be later used for creating chips.
Haskell is a lazy functional programming language, which lends itself readily to both very high level descriptions of software, and very low level descriptions of hardware, due its solid mathematical underpinnings.
This demo uses fully open source toolchain:
- CλaSH for compiling Haskell into Verilog,
- Yosys Verilog compiler to compile Verilog code into
.blif
format, - Arachne Place-N-Route to perform routing onto the Lattice ICE40 H1K device,
- IceStorm toolchain in order to generate FPGA bitstream and upload it into Lattice IceStick device.
This project used as a project template for your own experiments
with Haskell and FPGAs. In this case, please remove README.md
file after cloning.
This one uses a single counter to show a binary stopwatch with a range of 2⁵ seconds.
-
First install the IceStorm toolchain: On the latest Ubuntu you may install from the repository:
sudo apt-get install -y fpga-icestorm yosys arachne-pnr
Otherwise you might compile from the latest source:
-
IceStorm utilities themselves:
git clone https://github.com/cliffordwolf/icestorm.git icestorm make -j4 -DPREFIX=$HOME/icestorm make -DPREFIX=$HOME/icestorm install
For Linux you also might want to enable write access through FTDI USB device:
cat - <<EOF > /etc/udev/rules.d/53-lattice-ftdi.rules ACTION=="add", ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", MODE:="666" EOF
-
Arachne PNR tool:
git clone https://github.com/cseed/arachne-pnr.git arachne-pnr cd arachne-pnr make -j$(nproc) -DDEST_DIR=$HOME/icestorm -DICEBOX=$HOME/icestorm/share/icebox/ make install
-
Yosys Verilog compiler:
git clone https://github.com/cliffordwolf/yosys.git yosys cd yosys make -j$(nproc) -DPREFIX=$HOME/icestorm make -DPREFIX=$HOME/icestorm install
-
-
-
To install GHC and Cabal on Linux:
apt-get install ghc cabal-install
-
To install GHC on Windows it is recommended to either use
.msi
package of Haskell Platform or Stack installation utility. -
From within this environment, use
cabal-install
to setupclash-ghc
package:cabal install clash-ghc
-
-
Demo.hs
- contains Haskell code for the 32-second timer. -
icestick.pcf
- assigns names to Lattice iCE40 H1K pins on iCEStick board. -
icoboard.pcf
- assigns names to Lattice iCE40 H8K pins on IcoBoard.
While there will be Makefile, you might want to look through the build process step by step:
-
For simulation just compile it with
clash
as a Haskell program, and run:clash Demo.hs
-
For Verilog generation:
- run interpreter:
clash --interactive Demo.hs
- enter
:verilog
in the interpreter to generate.verilog
code
- run interpreter:
-
To compile Verilog into
.blif
netlist format:yosys -p "synth_ice40 -blif demo.blif" Verilog/Main/Demo_TopEntity.v
-
To route
.blif
netlist onto Lattice IceStick device:arachne-pnr -d 1k -p demo.pcf demo.blif -o demo.txt
-
To compile routed netlist into bitstream:
icepack demo.txt demo.bin
-
To upload bitstream onto the FPGA:
iceprog demo.bin
NOTE: If you forgot to add the relevant udev rule, you might need to use
sudo
here.
Or use Makefile
:
make test
make upload
It would be nice to wrap Ice40 PLL configuration as a custom block:
-
For Verilog code see: iCEStick PLLs
-
Wrapping of custom blocks in CλaSH code is described in this documentation.
-
Unfortunately making it work requires some change in the way CλaSH handles clock annotations.
Until then one needs to change Verilog code by themselves, asserting 1
for system1000_rstn