Electronics: Gate Array Workshop Notes (Lattice iCE40)

Tags: #<Tag:0x00007fa48e5c3318> #<Tag:0x00007fa48e5c3188> #<Tag:0x00007fa48e5c3020>

Gate Array Workshop with the iCE40

from @jonathanjo 2017-02-01

Introduction

We had a getting-started workshop 2017-02-01 for those interested in Field Programmable Gate Arrays. The easiest way is to use the Lattice iCE40 on the “Icestick” USB evaluation board, programming it in Verilog.

To build a bridge you need a thread across the valley, and getting it there is often the hardest part of the endeavour.

There are many other boards available, many other FPGAs, many other tools. This workshop is to get you going so you have a working toolchain and a a lit-up FPGA running something you’ve written. Once the thread is there, you can pull a string to pull a rope to pull a chain to pull some bricks to build the bridge however you please.

Prerequisites: you probably won’t get much out of this unless you know some boolean logic, a bit of digital design. The practical portion assumes you can follow along Unix command line. It’s probably helpful if you’ve done some programming in C or assembler. The general presentation is top down: What is is and how we use it before how to install the software etc.

The iCE40 comes in many varieties and sizes. The particular one we’re using is the iCE40HX1K.

  • Is big enough to be interesting (1 K cells)
  • Is small enough to be cheap (£4/unit)
  • Has easy-to-get demo boards which are cheap (£20-ish))
  • Can program in Verilog, looks a little like Pascal
  • Has excellent open source tools from Clifford Wolf
  • I know how to do it just well enough to write Hello World (LED blinking)

Thus excellent for people to get started with. I have personal experience of trying to learn anything at all with FPGAs and getting absolutely nowhere with conventional industrial evaluation kits. This is a big subject and a big industry: most of the manufacturers have very large development tools (some of which are excellent) but which are very difficult to get started with; many of them are very much in the proprietary-lock-in mould of software.

I make no claim for expertise in this subject, but I went to the workshop with Clifford in 2015 and am passing on the knowledge, as I hope you will. Clifford said

awesome! maybe some of the people in your workshops will start doing
workshops on their own, and so forth. a pyramid scheme for FPGA know-how! :slight_smile:

The practical portion of these notes assume you can use the command line in Unix, edit files and so on. They were tested on Ubuntu 16.04 LTS Server on both 32-bit Intel and Raspberry Pi 3; also Ubuntu 15.10 64-bit on a laptop.

Images for talk

This is the set of sketches I use to explain how FPGAs work.

1


2

3

4

5

6

7

8

9

10

11

12

How to make a program

It’s just like writing in C (or similar) except of course you have to think it’s very spatial (everything takes space) rather than temporal, where everything takes time.

  • With a text editor, write a program in Verilog called perhaps thing.v
  • With a text editor, we define the names for some signals in a companion “constraints” file thing.pcf
  • Compile it (with yosys to make thing.blif
  • Assemble it (with arachne-pnr) to make thing.txt
  • Pack it (with icepack) to make thing.bin
  • Put program on the hardware (with iceprog)
  • In practice, compilation/assembly/packing is done with make

Simplest example

The simplest example which will actually run on an Icestick lights one of the LEDs.

We define a IO signal called D1 to be on hardware pin 99 – we looked this up on the circuit diagram or manual for the hardware – which on the Icestick is connected to an LED.

# tiny.pcf
# hardware definitions for icestick
# jcl/othinking/2017-01-31

# 12 MHz clock input
set_io clk 21

# green led
set_io green 95

# red leds
set_io x0 99
set_io x1 98
set_io x2 97
set_io x3 96

# end
// tiny.v
// fpga demo for icepick lattice ice40hx1k
// jcl/othinking/2017-02-10

module top(input clk,
    output x0,
    output x1,
    output x2,
    output x3,
    output green);
    reg [23:0] counter;
   
    always @(posedge clk) begin
        counter <= counter + 1;
    end
   
    assign x3 = counter[23];
    assign x2 = counter[22];
    assign x1 = counter[21];
    assign x0 = counter[20];
    assign green = 1;
endmodule

// end

The typical Makefile would be

# Makefile
include ice40.mk
all: tiny.bin
        @echo done

Your process is therefore:

  1. Edit tiny.pcf
  2. Edit tiny.v
  3. Build with
    make
  4. If errors, go to 1 or 2
  5. Run on hardware with
    iceprog tiny.bin
  6. Observe behaviour
  7. Curse
  8. Go to 1 or 2

Although we’re using Yosys just for compiling the Verilog, it’s a very large program which can do all kinds of things like simulation and (connectivity) graph drawing.

You can look at the layout of exactly which cells are connected to which using a viewer such as “iceview”, which shows a one of the blocks like the following: (C+D means a LUT4 has been configured to add up two of its inputs):

The Icepick hardware

From left-to-right the chips are:

For the .pcf files you nee the “hardware pin numbers”, ie, giving names to the signals which are on particular physical pins, which are as follows:

Clock
Name Signal Pin
clk 12MHz 21
LEDs
Name Signal Pin
LED1 PIO1_14 99 (Red)
LED2 PIO1_13 98 (Red)
LED3 PIO1_12 97 (Red)
LED4 PIO1_11 96 (Red)
LED5 PIO1_10 95 (Green)
J1 (IO Bank 0)
Name Signal Pin
1 3.3 V
2 GND
3 PIO0_02 112
4 PIO0_03 113
5 PIO0_04 114
6 PIO0_05 115
7 PIO0_06 116
8 PIO0_07 117
9 PIO0_08 118
10 PIO0_09 119
J3(IO Bank 2)
Name Signal Pin
1 3.3 V
2 GND
3 PIO2_17 51
4 PIO2_16 50
5 PIO2_15 49
6 PIO2_14 48
7 PIO2_13 47
8 PIO2_12 46
9 PIO2_11 45
10 PIO2_10 44
J2 is two Digilength PMOD 1x6 connectors
Name Signal Pin
1 PIO1_02 78
2 PIO1_03 79
3 PIO1_04 80
4 PIO1_05 81
5 GND
6 3.3 V
Name Signal Pin
7 PIO1_06 87
8 PIO1_07 88
9 PIO1_08 90
10 PIO1_09 91
11 GND
12 3.3 V
IRDA pins (Vishay TFDU4101)
Name Signal Pin
RXD PIO1_19 106
TXD PIO1_18 105
SD PIO1_20 107
SPI
unknown

Q+A

For anybody starting with FPGAs:

  1. Why use iCE40 FPGA?
    It’s cheap and the software uses it
  2. Why use the Icestick as opposed to anything else
    It’s ubiquitous and there is endless material on the web
  3. Why use yosys/icepack/etc
    It’s open source and you’re protected against lock-in and knock-on operating system problems. No money outlay while you find out what you’re doing and if you’re interested.
  4. Why use Verilog (design language) instead of VHDL or whatever
    The software supports it and it’s a good way to do things. I’m not qualified to comment about whether it’s the best way to do things but It will get you going and thus you’ll be on your way.
  5. What versions of Verilog are there?
    This one is what I understand to be the most common Verilog 2005, which is standardised by ISO as 1364-2005 a minor change from Verilog 2001 ISO 1364-2001

Terminology

  • BLIF Berkeley Logic Interface Format, a textual description of gates etc, a little like assembler
  • Core a big library implementing something like a CPU in a gate array
  • FPGA field programmable gata array
  • HDL Hardware description language, a type of “programming” language
  • IP “intellectual property”, by which they mean a “library” or “lump of ready-made code”, sometimes with payment for use
  • LUT Lookup Table, an all-purse kind of gate LUT4 means with four inputs.
  • PNR Place and Route, the process of deciding exactly which gates/cells should be used, and the routing of the wires between them
  • VHDL “Very (high-speed IC) hardware description language”, an alternative to Verilog

Makefile

In order to hide all the dependencies of which file depends on which other, it’s usual to use make to take care of that. Make already knows rules for C programs and many others, but not Verilog files. So we need some new rules.

The recommended simplest way is have a straightforwared ice40.mk file and include it in your own makefiles: if you put ice40.mk in /usr/local/include then you have a single place for it and it won’t clutter up all your project directories. But if you don’t want to put it there, just have it in your own directory or paste its contents into your Makefile. (Or indeed, run yosys and arachne-pnr and icepack yourself: but why?)

# include/ice40.mk
# for verilog
# jcl/othinking/2017-01-31

# keep intermediates
#
.PRECIOUS: %.blif %.txt
.SUFFIXES: .v .blif .txt .bin .ex
%.blif: %.v
	yosys -q -p "synth_ice40 -blif $*.blif" $*.v
%.txt: %.blif %.pcf
	arachne-pnr -p $*.pcf $*.blif -o $*.txt
%.bin: %.txt
	icepack $*.txt $*.bin
%.ex: %.txt
	icebox_explain $*.txt > $*.ex

# end

Build notes for tools

The tools were mostly made by Clifford Wolf and presented in 2015: I went to a workshop and learnt how to do this from him. It has to be said this is just the most basic use of those tools.

The following was tested on fresh installs of Ubuntu 16.04 LTS Server on i386 and Raspberry Pi3 and behaves identically. (You can certainly make this work on lots of Unix-type operating systems.)

Get all the dependencies:

sudo apt-get install \
  build-essential clang bison flex libreadline-dev \
  gawk tcl-dev libffi-dev git mercurial graphviz \
  xdot pkg-config python python3 libftdi-dev

Get all the source:

mkdir src
cd src
git clone https://github.com/cliffordwolf/icestorm.git
git clone https://github.com/cseed/arachne-pnr.git
git clone https://github.com/cliffordwolf/yosys.git

Make them all:

(cd icestorm && make && sudo make install)
(cd arachne-pnr/ && make && sudo make install)
(cd yosys/ && make && sudo make install)

Most of these steps are seconds but making yosys is 2 hours on a small computer.

Test it on example comes with arachne:

cd
cp -Rp src/arachne-pnr/examples/rot .
cd rot
sed -i.bak 's|\.\./\.\./bin/||' Makefile  # remove bad path in Makefile
make
sudo iceprog rot.bin

Recommendations:

The program to put a bin file onto the Icestick hardware usually needs root permission, so good to give it that with setuid bit:

sudo chmod u+s `which iceprog`

It’s a good idea to put ice40.mk file (above) in /usr/local/include so it’s found easily in once place.

Materials


6 Likes