All of the buildings, all of those cars
were once just a dream
in somebody's head
Mercy Street - Peter Gabriel


8 minutes read

Pic 1

Taking a break from my series about the eZ80, “I don’t like Windows.” and “Why do you want to do/know that?”, I decided to take a look at FPGA’s to see if they could be used for my retro projects. More in particular in creating video.

A few weeks ago, pointed me to the iCE40HX1K-EVB dev board which is an incredibly cheap (15.95 Euro at the moment of writing) little FPGA board, including 512KB of SRAM. SRAM is a lot easier to interface with and write Verilog code for (for a first time user) than the typical SDRAM or DDR Ram that is found on almost all other FPGA dev boards.

Features of the iCE40HX1K-EVB

  • iCE40HX1K-VQ100 FPGA 1280 Logic cells, 64 K embedded RAM bits
  • 512KB SRAM organized as 256K x 16bit 10ns
  • 2MB Serial Flash
  • 2 user status LEDs
  • Programming successful status LED
  • 2 user buttons
  • Reset button
  • Power jack for 5V DC external power supply
  • PGM connector (all signals at PGM1 @ 3.3V DC)
  • 34 pin connector bus
  • 100 MHz oscillator
  • Power supply DC/DC regulators
  • Power supply status LED
  • Dimensions: 50 x 50mm ~ (2" x 2")

Installing the toolchain

The nice thing of the FPGA used on this board (iCE40HX1K), is that it is supported by the Yosys (Yosys Open SYnthesis Suite) open source toolchain.

The Olimex documentation refers to project IceStorm for programming this FPGA chip. But this project most recent update goes back to 2018. Therefore I decided to not use project IceStorm and directly use the latest binary release from Yosys which can be found here. Just choose the release that suits the OS you’re using. For Linux this is usually oss-cad-suite-linux-x64-YearMonthDay.tgz (releases are build every day).

Unzip the package to your preferred location and all required binaries (like iceprogduino, icepack, icetime, nextpnr-ice40, yosys, …) can be found in the bin subdirectory.

What remains to be done is adding this bin directory to your PATH environment variable so that the binaries can be found automatically. You can do so permanently but in this kind of experiments I usually prefer not to [yet]. In this case, I created a small file with this content:

# Use "." to set PATH variable once in your terminal.

export PATH='/home/koen/Documents/Projects/FPGA/oss-cad-suite/bin':$PATH

When you now execute . setup in your terminal, the PATH environment variable is extended with the path to the Yosys binaries but only in that terminal session. Of course, you will need to modify the above script to point to where you unpacked the Yosys release package.

Programming the iCE40HX1K-EVB

With the Yosys tools installed, we now need a way to program the FPGA.

Practically all FPGA boards have some kind of a USB to serial chip on board (typically from FDTI) for this purpose. This is not the case on this board (and helps explaining why this board is so cheap). Instead it does offer an UEXT connector which supports three kinds of serial communication interfaces - I2C, SPI and RS232. There is also 3.3V line and GND.

Olimex solution is to use an Arduino (Leonardo) for the USB to UEXT conversion, preferably using their own OLIMEXINO-32U4 (12.95 Euro at the time of writing) which conveniently also has a UEXT connector on board. Next to that, you need a 10-pin ribbon cable to connect the Arduino with the FPGA board like the CABLE-IDC10-15cm (2.00 Euro at the time of writing).

With the hardware sorted, it’s now time to program the Arduino so that it can be used to program the FPGA board. The OLIMEXINO-32U4 programmer sketch is part of the bigger iCE40HX1K-EVB repo on GitHub and can be found in the iCE40HX1K-EVB/programmer/olimexino-32u4 firmware/ path.

Unfortunately, the provided Arduino sketch has troubles with the more recent Arduino IDE (it insist that the iceprog.ino is inside a folder with the name iceprog). Instead of trying to fix this, I tried the platformio way of working first with the provided platformio.ini. and that worked without any problem for me.

Assuming you have the PlatformIO extension installing in VSCode, open PlatformIO:

PlatformIO welcome screen.

Click on Open Project and navigate to the olimexino-32u4 firmware folder inside the iCE40HX1K-EVB git repo:

Open `olimexino-32u4 firmware` project.

You then should see something like this:

Opened project.

We can now compile the project by clicking on the small check mark icon in the toolbar at the bottom:

Click on the `Check Mark` icon to compile the code.
Compilation succeeded.

The code should compile without any problems and we can now upload the code to the OLIMEXINO-32U4 board by clicking on the right arrow icon (next to the check mark build button):

Upload the code.
Code uploaded without problems.

Your OLIMEXINO-32U4 board is now ready to be used to program the FPGA. One thing we can already do is checking on which serial port your OLIMEXINO-32U4 board is connected. The default is /dev/ttyACM0 but /dev/ttyUSB0 is also possible.

Powering the OLIMEXINO-32U4 and iCE40HX1K-EVB

Both the OLIMEXINO-32U4 and iCE40HX1K-EVB have a power jack for an external power supply but there is a simpler way to provide power to them.

The OLIMEXINO-32U4 is self-powered by the miniUSB when it is connected to a USB port of your PC, which will be the case as long as you’re working on your code.

Warning: the OLIMEXINO-32U4 board can work on both 3.3V and 5V but the iCE40HX1K-EVB board can only work on 3.3V. E.g. 5V signals can destoy the FPGA chip. Be very sure that the jumper on the OLIMEXINO-32U4 is set to 3.3V!

Pin 1 of the UEXT connector on the OLIMEXINO-32U4 board can provide 3.3V that can be used to power the iCE40HX1K-EVB board. Pin 1 is controlled by pin D8 of the OLIMEXINO-32U4. The MCU can thus power on/off pin 1 of the UEXT bus. Luckily we don’t have to bother with this ourselves since the Arduino sketch which we just uploaded powers on pin 1 of the UEXT bus so that we can use this to power the iCE40HX1K-EVB board.

Some extra information from the FAQ of the OLIMEXINO-32U4 board:

There is no 3.3V on pin #1 of the UEXT connector. Why?

The power output at the UEXT is controlled by pin D8, also
called UEXT_PWR_E. This signal is connected to a FET. You
need to drive D8 to low level to enable 3.3V on the UEXT.
Use the following code:

// UEXT power enable --> PORTB4 --> D8
pinMode(8, OUTPUT);
digitalWrite(8, LOW);

We need to do a small modification on the iCE40HX1K-EVB board so that it can be powered via the UEXT bus. On the bottom side we see an open jumper, labelled 3.3V_E1. With a blob of solder we close this jumper so that the board can be powered via the UEXT bus. With this setup we don’t need any external power supplies, meaning less cables on the desk as well.

Open power jumper.
Closed power jumper.

Uploading a binary to the iCE40HX1K-EVB board

First thing we can do is check if we have a good connection to the iCE40HX1K-EVB board. We can do this with the iceprogduino command. Assuming you have installed the Yosys toolchain and its binaries can be found in your PATH.

This is the kind of output you will see when the OLIMEXINO-32U4 board is connected but not yet the iCE40HX1K-EVB board:

    [koen@manjaro-3900X ice40hx1k-evb]$ iceprogduino -tv

    Test mode
    Serial: /dev/ttyACM0: Success
    Manufacturer ID: 0x00 / Device ID: 0x0000

And now with the iCE40HX1K-EVB board connected to the UEXT bus of the OLIMEXINO-32U4 board as well:

    [koen@manjaro-3900X ice40hx1k-evb]$ iceprogduino -tv

    Test mode
    Serial: /dev/ttyACM0: Success
    Manufacturer ID: 0x1C / Device ID: 0x7015

Remark: On my PC, the OLIMEXINO-32U4 board is indeed found on the default /dev/ttyACM0 serial port. If this is not the case for you and the board appears on a different serial port, you can use the -I command line option to specify this:

    [koen@manjaro-3900X iCE40HX1K-EVB-demo]$ iceprogduino -h

    iceprog -- simple programming tool for Olinuxino Nano-based Lattice iCE programmers
            port to connect Arduino (default /dev/ttyACM0)

We’re now ready to upload our first binary. Luckily, there is already a pre-compiled binary in the git repository which can be found in .../demo/ice40-io-video/ as example.bin. Uploading it is as simple as:

    [koen@manjaro-3900X build]$ iceprogduino example.bin
    Serial: /dev/ttyACM0: Success
    file size: 32220
    erase 64kB sector at 0x000000..erased

    Manufacturer ID: 0x1C / Device ID: 0x7015
    prog 0x007D00 +0x0DC...

The provided example is intended to be used with the iCE40-IO board which I also have:

OLIMEXINO-32U4, iCE40HX1K-EVB and iCE40-IO. Everything powered via a single USB port.
The resulting output on a VGA monitor.

Compiling Verilog code

Next step is compiling the example ourselves so that we can create our own verilog code later.

Using the more recent Yosys toolchain has a small impact on the provided make file. Some executables got a different name (e.g. arachne-pnr became nextpnr-ice40) and some command line options are renamed as well.

Below you can find a reworked Makefile that compiles the example.v verilog code as it can be found in .../demo/ice40hx1k-evb. Note that a build directory is now created where the example.bin file will be stored:

    BUILDDIR  = ./build
    FPGA_TYPE = hx1k
    FPGA_PKG  = vq100
    PCF       = ice40hx1k-evb.pcf
    RMDIR     = rmdir

    # Targets
    example: $(BUILDDIR)/example.rpt $(BUILDDIR)/example.bin

    $(BUILDDIR)/%.json: %.v
      @mkdir -p $(@D)
      yosys -ql $(subst .json,,$@).log -p 'synth_ice40 -abc9 -device u -top top -json $@' $<

    %.asc: %.json
      nextpnr-ice40 --${FPGA_TYPE} --package ${FPGA_PKG} --json $< --pcf ${PCF} --asc $@

    %.bin: %.asc
      icepack $< $@

    %.rpt: %.asc
      icetime -d $(FPGA_TYPE) -mtr $@ $<

    all: example

      rm -f $(BUILDDIR)/*.asc $(BUILDDIR)/*.bin $(BUILDDIR)/*.rpt $(BUILDDIR)/*.log $(BUILDDIR)/*.json
      $(RMDIR) $(BUILDDIR)

    # Uncomment this line if you want to keep the intermediate .json and .asc files
    # .PRECIOUS: $(BUILDDIR)/%.json %.asc

    .PHONY: all prog clean example

For convenience, I made my own copy of the iCE40HX1K-EVB/demo folder with the adapted Makefiles and pre-build binaries which can be found here.

Now it’s your turn to start hacking on FPGA’s.

Recent posts

See more