This article is part of a series documenting my first foray into FPGA programming. You might find it helpful to read the summary article1 first.

Introduction

Olimex make a development board for the HX1K2. The board’s design is entirely open: it’s on GitHub3.

Unlike the boards from Lattice, it does not contain a programmer: rather Olimex suggest using one of their Arduino clones to do the task. There’s also no USB connection for a computer: it seems much more a standalone product.

Walkthrough

Two steps are common to all the boards:

  1. Install the iCE40 toolchain4.
  2. Clone the repo:
$ git clone https://github.com/mjoldfield/ice40-blinky.git

Next you will need to acquire an FPGA programmer. Olimex suggest programming an Arduino: this is documented below5. Having configured the Arduino, connect it to the FPGA board:

Now we must attend to the power. There isn’t a USB port on this board, so you can”t directly power it from a computer. Instead you have to choose between:

The latter is most convenient, but you need to bridge an open solder-bridge on the bottom of the PCB to enable it.

Now you can build the relevant demo, and flash it to the board:

$ cd olimex-hx1k/
$ make flash

Finally, enjoy the blinkenlights6!

Testing

If you have a frequency counter to hand, measure the frequency on pin 34 of the IDC connector. You should see a 6.25MHz square wave.

Hardware Notes

The board’s design is entirely open: it’s on GitHub7.

FPGA

The FPGA is a iCE40HX-1K in a 100-pin flatpack.

Clock and PLL

A 100MHz oscillator module drives pin 15.

In this package the HX1K has no PLL.

LEDs

Two red LEDs are provided on pins 40 and 51.

Test point

As befits the name breakout board, many spare IO pins exist, and we use pin 24 as a test point.

Software Notes

Please remember that you can download all of this from GitHub8.

There are only three files: the verilog, the pin definitions, and a Makefile.

The main source code

The code is very simple: there are just two LEDs and they flash at 1Hz.

/*
 * Top module for Olimex iCE40HX1K-EVB blinky
 *
 * Bounce LEDs
 *
 * Generate test signal: 6.25MHz
 */

module top(input CLK
       , output LED1
       , output LED2
       , output TSTA
       );

   // No PLL, so use 100MHz external clock
   wire sysclk;
   assign sysclk = CLK;

   // We want to do a 2-cycle pattern in 1s, i.e. tick at
   // 2Hz. log_2 (100M / 2) = 25.6. so use a 26-bit counter
   localparam ANIM_PERIOD    = 100000000 / 2;
   localparam SYS_CNTR_WIDTH = 26;

   reg [SYS_CNTR_WIDTH-1:0] syscounter;
   reg                 led_strobe;

   always @(posedge sysclk)
     if (syscounter < ANIM_PERIOD-1)
       begin
      syscounter <= syscounter + 1;
      led_strobe <= 0;
       end
     else
       begin
      syscounter <= 0;
      led_strobe <= 1;
       end

   reg             ledState;
   always @(posedge sysclk)
     if (led_strobe)
       ledState <= !ledState;

   assign LED1 =  ledState;
   assign LED2 = !ledState;

   // test signal: 100MHz / 2^4 = 6.25MHz
   assign TSTA = syscounter[3];

endmodule

Makefile

Most of the rules are shared across different dev. boards: we need only to specify the FPGA and the programming software:

ARACHNE_DEVICE = 1k
PACKAGE      = vq100

ICETIME_DEVICE   = hx1k

PROG_DEV     = $(wildcard /dev/cu.usbmodem*)
PROG_BIN     = iceprogduino -I$(PROG_DEV)

include ../std.mk

Pin summary

Finally, we need to tell the software which pins are associated with the signals:

$ cat pins.pcf
set_io LED1 40
set_io LED2 51
set_io CLK  15
set_io TSTA 24

The Arduino FPGA programmer

Olimex recommend using their Olimexino-32U49 board for this. I think it’s roughly the same as an Arduino Leonardo, but it comes with a UEXT header which has precisely the right pin out for the programming header on the Olimex FPGA board.

If you try to use a different Arduino, make sure it uses 3.3V signals, rather than 5V.

The sketch for the board is in the FPGA board’s GitHub repo10, but you also need a particular SPIFlash library. More explicit details can be found on the Olimex website11.

Having flashed the hardware, we now need to install software on the Mac to drive it. That too is from GitHub12:

$ make
$ make install

On the Mac, the Arduino appears as a usbmodem device in /dev:

$ ls /dev/*usbmodem*
/dev/cu.usbmodem14431  /dev/tty.usbmodem14431

Of these, you need the cu.usbmodem version. The number in the device name reflects its place on the USB buses, and so changes if you plug it in to a different socket. If you just have one such device though, you can use a wildcard, and program the FPGA thus:

$ iceprogduino -I/dev/cu.usbmodem* foo.bin