Programming Lattice FPGAs from Toradex ARM modules with Project Icestorm

Published:

The excellent Project Icestorm by Clifford Wolf (whom we had the pleasure to meet in Vienna and at ORCONF as a result of the AXIOM kickoff meeting earlier this year) and Mathias Lasser enables the programming of Lattice iCE40 FPGAs with an open-source, command-line toolchain that also manages to perform better than the ‘official’ tools in some contexts.

ICEstick with T30

One thing that such a toolchain enables as compared to proprietary, often GUI-driven and definitely x86-only toolchains is running it on embedded platform, for an all-embedded ARM+FPGA experience, without a PC in the loop, which gives you an ultimate dynamic “field-programmable” solution.

The Lattice ICEstick is an easily available and inexpensive platform that can be programmed with the Icestorm tools, and for the ARM part that will run the toolchain, work is currently under way to create a Raspberry Pi-based setup.

Here at Antmicro we decided that it could also be useful to provide an easy way to run the tooling on a more industrialized platform. Since we find ourselves working very much with embedded ARM SoMs from our friends at Toradex, we decided that their cheap and readily available Colibri modules are a good match for the ICEstick – it’s easy to lay your hands on both.

We also created an automated script to download and build all dependencies needed for the entire toolchain, so that you do not have to do it manually and can start working with your Toradex Colibri + Lattice ICEstick setup right away!

Preparing the build environment

First of all, create your working directory. Let’s assume it is ~/toradex-icestorm. In this guide we will call it $ROOT_DIR. Storing all files in this directory will make the compilation process faster and easier.

Download the icestorm-installer repository from our github:

mkdir ~/toradex-icestorm
cd ~/toradex-icestorm
git clone https://github.com/antmicro/icestorm-installer.git

At this point you will need to set your environment variables that would later be used by makefiles.

These variables are described and set in a configuration file called icestorm_build.cfg. If you follow the instructions in this guide you do not need to change anything in this file.

In the repository you will also find the build_icestorm.sh script – the name is self-explanatory. This script will do all the work for you: download and compile the dependencies and Icestorm Tools packages; and copy all the desired files to your output directory.

You need to download a cross compilation toolchain. In this example we used the arm-linux-gnueabihf Linaro toolchain in version 4.8. You can download it from https://launchpad.net/linaro-toolchain-binaries. If your compiler has a different prefix than the one mentioned above, make sure to change the CC_PREFIX variable in the configuration file. Remember to add the path to your toolchain’s binaries to the PATH environment variable.

Building the tools

Using the provided script, you can now build the Icestorm Tools. The script has the following dependencies:

  • git
  • wget
  • tar

Make sure those tools are available before proceeding. If the script executes without errors, output will be stored in $ROOT_DIR/icestorm_final_output/. This can be changed by setting the INSTALLATION_PATH variable in the configuration file.

In the icestorm-installer directory execute:

./build_icestorm.sh

This can take a few minutes.

Deploying files to a Toradex Colibri module

By default, the installer script copies all the needed files to the $ROOT_DIR/icestorm_final_output directory. The files can also be copied by calling:

export INSTALLATION_PATH=<some/path/where/to/store/output>

cd $ROOT_DIR
mkdir -p $INSTALLATION_PATH/bin $INSTALLATION_PATH/lib $INSTALLATION_PATH/share/yosys $INSTALLATION_PATH/share/arachne-pnr

cd $INSTALLATION_PATH/bin
cp $ROOT_DIR/icestorm-tools/icepack/icepack $ROOT_DIR/icestorm-tools/icemulti/icemulti $ROOT_DIR/icestorm-tools/iceprog/iceprog cp$ROOT_DIR/yosys/yosys-* $ROOT_DIR/yosys/yosys .
cp $ROOT_DIR/arachne-pnr/bin/arachne-pnr-arm ./arachne-pnr


cd $INSTALLATION_PATH/share/yosys
cp -r $ROOT_DIR/yosys/share/* .

cd $INSTALLATION_PATH/share/arachne-pnr
cp -r $ROOT_DIR/arachne-pnr/share/arachne-pnr/* .

cd $INSTALLATION_PATH/lib
cp $LIBUSB_INSTALL_PATH/lib/libusb* $LIBFTDI_INSTALL_PATH/lib/libftdi1* $LIBNCURSES_INSTALL_PATH/lib/lib* $LIBREADLINE_INSTALL_PATH/lib/lib* $LIBFFI_INSTALL_PATH/lib/lib* $LIBTCL_INSTALL_PATH/lib/lib* .

The $INSTALLATION_PATH directory now contains all files you need to move to the Toradex module.

The files can also be copied e.g. using SSH with the scp tool. This can be done as follows:

scp $INSTALLATION_PATH/* root@<your module's IP>:/

It requires a running SSH daemon on the module and a working network connection between your workstation and the module.

Additionally you can copy example files stored in the $ROOT_DIR/arachne-pnr/example/rot directory so you can test the tools. Again, using scp you can do it as follows:

scp -r $ROOT_DIR/arachne-pnr/example/rot root@<your module's IP>:/

You can now execute the following commands on the module:

cd rot
yosys -p "synth_ice40 -blif rot.blif" rot.v
arachne-pnr -d 1k -p rot.pcf rot.blif -o rot.txt
icepack rot.txt rot.bin
iceprog rot.bin

Note that the final command requires the ICEstick to be connected to the module (of course). Voila! You have just successfully compiled Verilog code on an ARM platform and run it on an FPGA.

Summary

Now that you can program the ICEstick from a Toradex Colibri ARM module, you could be tempted to automatically generate Verilog code, compile and run it without using a PC. Happy Hacking – and if you find any problems or have any great ideas worth sharing, don’t forget to contact us and contribute back to the Icestorm project.