Lattice ICE40 in Arch Linux

Since second year of University, I have been wanting to use our VHDL and FPGA course for some FPGA projects at home. Until now, I have been held back by the prices of the Xilinx boards we used back then.

The FPGA I want to use in a design should be

  1. Cheap – to justify using it for smaller projects at home.

  2. Hand-solderable and simple-to-lay-out because I want to use the FPGA for my own PCBs in the future.

  3. Linux compatible.

I found a Lattice evaluation board with and iCE40 FPGA on it which seems to fit the bill for me. The board is the iCEblink40HX1K Evaluation Kit.

 

Lattice iCEblink40-HX1K Evaluation Board.

The software that supports the board is called iCEcube2. As it didn't quite work out-of-the-box for me, I wanted to share how I got the thing working with Arch Linux. For reference, here is some data on my setup:

  • Date: 2016-04-19

  • OS: Arch Linux, 4.4.5-1-ARCH

  • PC: Lenovo Thinkpad L530

  • iCEcube2 release: 2016.02.2781

  • HDL flavour: VHDL

This is not a specific tutorial, but should contain some hints to getting up and running. In case something is missing, please contact me, and I will help as best I can. The basics of using the iCEcube2 software (when it is working) is shown in the iCEcube2 Tutorial from Lattice. For the specific board, the Evaluation Board Datasheet also helped me.

Problem 1: Getting iCEcube2 Running

In order to obtain a license for the iCEcube2 software at the Lattice website, you must input the MAC address of your Ethernet card. Your Ethernet card must be named eth0 in order for the licensing to work correctly!.

Your Ethernet card name is found using the command ifconfig. To change the name, a udev rule must be added. Please refer to the Arch Wiki regarding this.

After this, the license file must be located at /usr/local/flexlm/licenses/license.dat. Now the iCEcube2 software starts just fine.

A new project is started by pressing the “Create new project” button :-)

 

Create new project.

Adding Files

In order to get started, I created a file, first.vhd , containing the following (a binary 1Hz counter):

first.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity bincounter is
    port(
            CLK_BOARD: in std_logic;
            LD: out std_logic_vector(3 downto 0)
        );
end bincounter;

architecture behavioral of bincounter is
    signal count : std_logic_vector(3 downto 0);
    signal prescaler : std_logic_vector(23 downto 0); -- clk divider
    signal clk_1hz : std_logic;
begin

    -- Clock divider
    process(CLK_BOARD)
    begin
        if (CLK_BOARD'event and CLK_BOARD='1') then
            if (prescaler=x"192D59") then -- Prescaler => 1 Hz counter
                prescaler <= (others => '0');
                clk_1hz <= not clk_1hz;
            else
                prescaler <= prescaler + "1";
            end if;
        end if;
    end process;

    -- Binary counter
    process(clk_1hz)
    begin
        if (clk_1hz'event and clk_1hz='1') then
            count <= count + "1";
        end if;
    end process;

    LD <= count; -- Show counter on LEDs
end behavioral;

Adding the VHDL file seems to work just fine. Now the synthesis should begin by pressing “Run Synplify Pro Synthesis”…

Problem 2: Synthesize

When I press the “Run Synplify Pro Synthesis” button, I get the following error:


Project Directory is /run/media/soren/hdd/Dropbox/Elektronik/lattice_first/first/first
"/opt/iCEcube2.2016.02/sbt_backend/bin/linux/opt/synpwrap/synpwrap"
        -prj "first_syn.prj"
        -log "/run/media/soren/hdd/Dropbox/Elektronik/lattice_first/first/first/
                first_Implmnt/first.srr"

****************************************************************

Error: platform linux_a_64 4.4.5-1-ARCH is not supported

****************************************************************

Copyright (C) 1992-2014 Lattice Semiconductor Corporation. All rights reserved.
Child process exit with 2.
Error of dumping file
/run/media/soren/hdd/Dropbox/Elektronik/lattice_first/first/first/
        first_Implmnt/first.srr, 'stdout.log' is instead.
Synthesis exit by 2.
Error : can not print out log file stdout.log
Synthesis failed.
Synthesis batch mode runtime 0 seconds

The problem occurs because the platform-check script is not updated for the Linux 4.0 kernel. The problem is solved by changing /opt/iCEcube2.2016.02/synpbase/bin/config/platform_check (substitute your own install path) to include the version 4 in its check, like so:

platform_check
case $PLATFORM in
    linux | linux_a_64 )
        case $VERSION in
            4.* | 3.* | 2.4.* | 2.6.*  )  # soren: Added 4.*
                PLATFORM_STATUS="ok";;
            *)
                PLATFORM_STATUS=`echo $PLATFORM $VERSION`;;
        esac;;
    *)
        PLATFORM_STATUS=`echo $PLATFORM $VERSION`
        ;;
esac

Now, the synthesis seems to pass.

Choosing the Pinout – Add a Constraint File

To constrain the place-and-route process to using specific pins for the VHDL signals, a constrain file (.pcf) is added. Simply create a file like the following and add it under the “Add P&R files” -> “Constraint Files”.

first.pcf
# Constraint file for iCEblink40HX1K
# Family & Device:    iCE40HX1K
# Package:            VQ100

set_io CLK_BOARD 13
set_io LD[0] 51
set_io LD[1] 53
set_io LD[2] 56
set_io LD[3] 59

Here, the signals and pin-numbers correspond to the first two buttons and the first LED on the evaluation board. The pin-numbers can be seen on the figure below.

 

FPGA pin numbers for the iCEblink40-HX1K Evaluation Kit [Lattice Semiconductor].

Place and Route

Now, the Place-and-Route is run by pressing “Run P&R”.

Transfer the Design to the Board

Apparently, the programming functionality of the iCEcube2 software only works on Windows. I know – why would anyone need to program the damn thing anyway…

Luckily, reactive-systems on Github has created the tool icedude, which makes it possible to program the board from the command line. To compile and use the program, first install ghc and cabal-install. After this, cabal install is used to install the rest of the dependencies listed on the Github page.

The binary created by iCEcube2 is, on my system, found in the following directory

/home/soren/Dropbox/Elektronik/lattice_first/first
        /first/first_Implmnt/sbt/outputs/bitmap/bincounter_bitmap.bin

In this directory, the board is flashed using the following command:

icedude
sudo icedude -d D362349 -e -U flash:w:bincounter_bitmap.bin -v

The D362349 part is found using the command sudo icedude -l.

Now the design is flashed to the board is working on Linux!

Clock Inaccuracy

I have noticed that the clock frequency varies a bit under use. When the clock is under light use, i can measure around 33.33MHz from the clock. However, for a more complex design, the clock frequency drops to around 30MHz.

I had a look at the datasheet for the Linear Technology 1799 oscillator which is used on the board. The recommended minimum value of the set resistor is 3k for a 5V supply and 5k for a 3V supply. On the board, a 3k resistor is installed but a 3.3V supply is used.

The following image shows the clock measured on an oscilloscope. It is clear, that the clock is not very stable.

 

Clock jitter.

I have chosen to change my oscillator frequency to 25MHz which is usable for driving a VGA screen. This is still a bit out of range but closer to the recommended 20MHz at 3V. To do so, the resistor should be

\[ R_{\text{set}} = \SI{10}{k\ohm}\frac{\SI{10}{MHz}}{\SI{25}{MHz}} = \SI{4}{k\ohm} \]

I chose to use a 3.9k resistor and now the jitter is gone. The frequency is around 25.5MHz but my VGA design seems to get a monitor running so I am happy :-)

 

No clock jitter with a 3.9k set resistor. The new frequency is around 25.5MHz.