Note: the following instructions are for Linux (I'm using Ubuntu). Windows users can run the tutorial using WSL. It requires some adaptation, as explained here.
$ git clone https://github.com/BrunoLevy/learn-fpga.git
You can find precompiled toolchains for FOMU here. Alternatively, if you want a cutting-edge yosys/nextpnr, you can install them from the sources as follows:
Follow setup instructions from yosys website
TL;DR
Install prerequisites:
$ sudo apt-get install build-essential clang bison flex \
libreadline-dev gawk tcl-dev libffi-dev git \
graphviz xdot pkg-config python3 libboost-system-dev \
libboost-python-dev libboost-filesystem-dev zlib1g-dev
Get the sources:
$ git clone https://github.com/YosysHQ/yosys.git
Compile and install it:
$ cd yosys
$ make
$ sudo make install
Follow setup instructions from icestorm website
TL;DR
Install prerequisites:
$ 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 \
qt5-default python3-dev libboost-all-dev cmake libeigen3-dev
Get the sources:
$ git clone https://github.com/YosysHQ/icestorm.git
Compile and install it:
$ cd icestorm
$ make -j 4
$ sudo make install
Follow setup instructions from nextpnr website
TL;DR
Get the sources:
$ git clone https://github.com/YosysHQ/nextpnr.git
Compile and install it:
$ cd nextpnr
$ cmake -DARCH=ice40 -DCMAKE_INSTALL_PREFIX=/usr/local .
$ make -j 4
$ sudo make install
apt-get install iverilog verilator
We need to let normal users program the IceStick through USB. This
can be done by creating in /etc/udev/rules.d
a file 99-fomu.rules
with the following content:
SUBSYSTEM=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="5bf0", MODE="0664", GROUP="plugdev"
Install dfu-util:
$ sudo apt-get install dfu-util
Plug the FOMU and test it:
$ dfu-util -l
It should display something like:
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Found DFU: [1209:5bf0] ver=0101, devnum=20, cfg=1, intf=0, path="1-1", alt=0, name="Fomu PVT running DFU Bootloader v1.9.1", serial="UNKNOWN"
$ cd learn_fpga/Basic/FomuBlink
$ ./make_it.sh
The FOMU should nicely glow in blue while downloading the bitstream, then blinking in different colors. With the FOMU, you only have one LED to output something, but it is in colors !
Time to edit learn-fpga/FemtoRV/RTL/femtosoc_config.v
. This file lets you define what type
of RISC-V processor you will create, and which device drivers in the
associated system-on-chip. For now we activate the LEDs (for visual
debugging). We use 6144 bytes of RAM for now.
We configure FemtoRV/RTL/femtosoc_config.v
as follows (we keep unused options as commented-out lines):
/*
* Optional mapped IO devices
*/
`define NRV_IO_LEDS // Mapped IO, LEDs D1,D2,D3,D4 (D5 is used to display errors)
//`define NRV_IO_UART // Mapped IO, virtual UART (USB)
//`define NRV_IO_SSD1351 // Mapped IO, 128x128x64K OLed screen
//`define NRV_IO_MAX7219 // Mapped IO, 8x8 led matrix
//`define NRV_IO_SPI_FLASH // Mapped IO, SPI flash
//`define NRV_IO_SPI_SDCARD // Mapped IO, SPI SDCARD
//`define NRV_IO_BUTTONS // Mapped IO, buttons
`define NRV_FREQ 16 // Frequency in MHz.
// Quantity of RAM in bytes. Needs to be a multiple of 4.
// Can be decreased if running out of LUTs (address decoding consumes some LUTs).
// 6K max on the ICEstick
//`define NRV_RAM 393216 // bigger config for ULX3S
//`define NRV_RAM 262144 // default for ULX3S
`define NRV_RAM 6144 // default for IceStick (maximum)
//`define NRV_RAM 4096 // smaller for IceStick (to save LUTs)
//`define NRV_CSR // Uncomment if using something below (counters,...)
//`define NRV_COUNTERS // Uncomment for instr and cycle counters (won't fit on the ICEStick)
//`define NRV_COUNTERS_64 // ... and uncomment this one as well if you want 64-bit counters
//`define NRV_RV32M // Uncomment for hardware mul and div support (RV32M instructions)
/*
* For the small ALU (that is, when not using RV32M),
* comment-out if running out of LUTs (makes shifter faster,
* but uses 60-100 LUTs) (inspired by PICORV32).
*/
`define NRV_TWOSTAGE_SHIFTER
Now, edit FemtoRV/FIRMWARE/makefile.inc
. You have two things to do,
first indicate where the firmware sources are installed in the FIRMWARE_DIR
variable. Second, chose the architecture, ABI and optimization flags
as follows:
ARCH=rv32i
ABI=ilp32
OPTIMIZE=-Os
Then, compile a RISC-V blinky as follows:
$ cd FIRMWARE
$ ./make_firmware.sh ASM_EXAMPLES/blinker_loop.S
$ cd ..
$ make FOMU
Quite a convoluted way of obtaining more or less the same blinky as in step 3, but this blinky is much cooler: it is written in assembly, stored in BRAMs, and executed by a RISC-V core !
There are still things that I do not understand: at 24 MHz, it blinks slowlier than at 16 MHz, and at 20 MHz, it gets stuck. To be understood.
Now it would seem natural to activate the UART. However, the FOMU does not have the FTDI chip that implements
serial over USB, here you are on your own, and need to implement the gateware for the USB stack. It can be
done, here there is an implementation of the J1 processor
that has the UART-over-USB. It is a big things, with no less than
17 verilog files !.
Well, if somebody wants to interface it, you can put it in RTL/DEVICES/USB
and send me a PR once it works.
There is much more that we can do with the FOMU, it has ample room for more functionalities, it has hardware
mutlipliers (DSP blocs), and RV32IM works without needing any modification (activate it in RTL/femtosoc_config.v
).
It has ample quantities of RAM that we can use (single-ported RAM), using a special SB_SPRAM256KA
bloc, see
here.
I'd like also to wire a 8x8 led matrix. It requires soldering 3 wires to the pads, and two additional wires (gnd and vcc) on the other side.
To be continued