An RV32IMF implementation w/ migen/LiteX
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kaqu 01818b44a4 Fixed zero operand problems (hopefully!) 9 months ago
.vscode Brushup for publication ... 10 months ago
debugger Brushup for publication ... 10 months ago
firmware More readme files ... 9 months ago
helpers More readme files ... 9 months ago
impress More readme files ... 9 months ago
libmodules Fixed zero operand problems (hopefully!) 9 months ago
litex Permit ROM/BIOS integration w/o CPU argument 11 months ago
prog Started w/ DRAM access tests ... 1 year ago
software Fixed zero operand problems (hopefully!) 9 months ago
.gitignore Debugger separated 1 year ago Project housekeeping ... 9 months ago
Risq5_Overview.png Brushup for publication ... 10 months ago 1st public release ... 9 months ago


Risq5 - one more clone to go ...

This project demonstrates the use of LiteX & migen to create a full blown RISC-V CPU (RV32IMF). It shows a usually poorly documented IEEE 754 FPU logic implementation.
The project requires a colorlight-5a-75b board (minimum).

(Hint: project has been tested on Linux Mint 20 only, but should run on other Linux versions as well ...)


1. Software

To use this project effectively, you will have to install LiteX, see for details (and project Trellis, NextPNR & YoSys requirements). Also, it is recommended to install the board support, see, as well as the the RISC-V tool chain (see To communicate with your board via network, install the wishbone tools, see

To use the automatic documentation feature, you will have to install sphinx, see Also its wavedrom extension has to be installed, see Some helpful links for RST docstring formats: &

The project assumes a local 'fpga' path within the home directory of the user, where all the above mentioned software packages are installed. Furthermore, the project assumes a virtual environment named 'fpga' where all project relevant python libs are registered (this is not strictly necessary ... maybe software/ has to be adjusted, as well as the python interpreter settings within VSC!). The actual 'Risq5' project may be installed anywhere, but local paths will have to be adjusted (firmware/main.c, software/ ... worx for me ;).

2. Hardware

A JTAG programmer will be required for successful device programming. Thanx to Wolfgang, I'm using the Versaloon (s/w for blue-pill STM32), see To use this device, you also will have to install openocd via 'apt install openocd'. See for details, on how to connect the JTAG adapter.

For board specific details see Other helpful links to board data:

3. Functional description ☯ ...💡!

3.1 General

The RISC-V ISA specification can be downloaded here: Vol. 1 & Vol. 2 (it'll probably help, to have these readily available ...).

The core consists of an L1 cache for program code loading (or L0 is it 🤔 ?), a 'data' load unit (LU) & the corresponding store unit (SU), the base & FPU decoders as well as the data flow control logic (disturbingly called ALU - 🗣 respect the historical context!). The data flow is controllable via the Wishbone system bus (even remotely!). All units are implemented w/ migen's finite state machines (FSMs).
The L1 cache loads itself upon boot (RISC-V: from address 0) and signals 'ready' to the data flow unit, which in turn loads the 1st opcode (by pure coincidence the program counter (PC) starts from this location as well 🎉 !). If run is enabled in the cpu mode control word, the decoder processes (executes) the opcode.
The opcode dictates the PC modification when finishing (+4 bytes = next opcode, others by jumps/branches or interrupts). L1 cache (re-)loads are triggered as necessary ...

Main Decoder

Graphic shows the base ('I') decoder together w/ the 'M' extension (integer multiply/divide). The FPU decoder is triggered via the base decoder (not shown here) which then simply waits for termination of the individual processing chains.

3.2 Program structure:

  1. - this is the main FPGA building source
  2. libmodules subdir - all RISC-V sources, DRAM DMA loader helper & system time support
  3. helpers subdir - contains python helpers for load & flash etc.
  4. debugger - contains the sources for the Risq5 'visual debugger'
  5. firmware subdir - contains some modified BIOS files (& the originals), not used currently
  6. software subdir - contains a separate build, load & flash logic for RV32IMF application code
  7. litex subdir - contains modified LiteX sources (& originals)
  8. impress subdir - impress graphics to improve understanding (the rest is of minor importance currently ...)

3.3 Quickstart

After installation of the relevant toolchains:

  1. Open the project in VSC (or use your favourite IDE & maybe adjust some settings ;), adjust local paths if nec. ...
  2. Connect your JTAG adapter as described in Wolfgang's documentation @
  3. Run with these options (you may omit the --doc option if there is no Sphinx installed): --build --load --revision=7.0 --uart-name=crossover --with-etherbone --ip-address= --csr-csv=build/csr.csv --isa-extension-m --isa-extension-f --doc to create & load the project to on-board SRAM via the USB/JTAG-Adapter (this takes it's time ...)

3.4 Test assembly code

  1. This time, open up a terminal & cd to the project local 'software' subdirectory
  2. You can load an application to absolute location 0x40190000 (you may have to adjust local paths!):
    ./ fputest
  3. Run the debugger: with the same options as above (for
  4. You're now able to verify correct operations of the cpu (well, hopefully 😎!)

Some references concerning the implementation of IEEE 754 FPU logic:

And for 'M' extension multiply/divide logic:


This is a best effort project (& not even finished entirely!), no guarantees given. Things may or may not work ... so don't blame me if somethin's screwed up! Relax 🧘 ! Improve 🏆 !