Pulpissimo is a RISC-V microcontroller designed specifically for low-power applications. It is a 32-bit, single-issue, 4-stage pipelined chip, that supports custom instructions and SIMD.

Quick links:

Architecture

Pulpissimo relies on three main modules, written in SystemVerilog.

Any IO tasks are handled with the padframe, which is a generic wrapper for any kind of IO ports. Each IO pad requires 5 signals.

The start-up sequence is stored in the ROM. The stack is stored in the L2 cache.

Installation

This is as of July 2024. Pulpissimo evolves rather quickly, so this process will likely change. I did this on a fresh installation of Ubuntu 24.04 LTS. This doesn’t work on Windows.

In order of what we need to do:

  • GNU toolchain and fix Python problems and install Questa (concurrently)
  • Install Pulpissimo
  • Install Pulp runtime

GNU toolchain

We first need to build the RISC-V GNU toolchain (GCC, GDB, etc.), specially modified for the PULP platform. All the repositories we clone will also require several pre-requisite packages that we must install beforehand.

# get pre-req packages
sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
# clone repository
git clone --recursive https://github.com/pulp-platform/riscv-gnu-toolchain.git

This process will take several minutes to clone locally. Then, to match the recommended build settings, we need to do the following:

# mkdir and change owner, else build may break
sudo mkdir /opt/riscv
sudo chown -R $USER:$USER /opt/riscv

We can then compile. This will take several hours, depending on the performance of your machine. What we’re interested in are the files riscv32-unknown-elf-gcc, which are used later in the build process.

cd riscv-gnu-toolchain
./configure --prefix=/opt/riscv --with-arch=rv32imfcxpulpv3 --with-abi=ilp32 --enable-multilib
make

When this is done, we want to add environment variables to our path. To add persistent environment variables, Bash requires that we add them to ~/.bashrc. Otherwise, it’ll persist only for the duration of the terminal session (which is not very helpful). Any time we add env variables to our path, assume it’s to ~/.bashrc.

export RISCV=/opt/riscv
export PULP_RISCV_GCC_TOOLCHAIN=$RISCV
export PATH=$PATH:$RISCV/bin

Python problems

While we wait, I’ll note that Python 3.12 is not supported, and will in fact break the build process for many scripts. This is because certain dependencies (imp, Artifactory) do not support Python 3.12. Fortunately Python 3.10 and Python 3.11 still work — but note that an active conda environment won’t stop Pulp’s build tools from using the system Python anyways.

We’ll downgrade here, but note that this method will break many parts of your system (including the stock Terminal; I recommend Alacritty or GhosTTY if it ever releases publicly). We’ll be updating the specific symbolic link. It’s possible that update-alternatives (an Ubuntu utility) may work as well here, but I’ve not tested this.

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3.11

This installs to /usr/bin. We can also check installed versions of Python with ls /usr/bin/python*.

Questa

Officially, the Intel/Altera version of ModelSim and Questa aren’t supported by Pulpissimo. ModelSim probably won’t work, because of its line restrictions, but several people have previously gotten Questa to work. We’ll use the Questa Intel FPGA starter edition.

Install the latest version of Quartus Prime Lite from the Intel website. While Pulpissimo doesn’t support Altera FPGAs, Quartus does play a specific role in helping us get Questa (generating the network ID if we can’t find it in the system). Run through the installer and ensure that Questa is installed alongside Quartus.

From here, you can follow the steps outlined here by Intel to generate a license. This is free, but does require some steps. Make sure the license file path is saved in the LM_LICENSE_FILE env variable. After this is done, we must also add vsim to our path.

Pulpissimo

There’s a pre-compiled release of Pulpissimo available from the GitHub repository, but this is several (hundred) commits out of date. I recommend building from source, with the most up-to-date version of the code.

git clone https://github.com/pulp-platform/pulpissimo.git

To build the RTL simulation platform (what the runtime/SDK uses), we now compile.

make checkout
make build

With this, we can simulate the results of C programs with the simple runtime or the SDK.

Pulp runtime

The simple runtime is included as a sub-module of the Pulpissimo repository.

git submodule update --init --recursive

Crucially, any time we compile a program, we must do the following steps. In the sw/pulp-runtime directory, we need to source the configuration for the core we’re trying to simulate.

source configs/pulpissimo_cv32.sh

Then, we can cd into our target program directory, and compile.

make clean all run gui=0

gui=1 will open Questa’s waveform viewer. Without it, the simulation will run in the terminal (which may be preferred).

Vivado

The FPGA flow primarily works on Xilinx development boards via Vivado. One problem with Vivado installations is that projects often wholly break version-to-version. One version verified to work is 2022.1 (in fact this is recommended for Digilent boards), but it’s possible newer versions work as well.

Vivado requires at least 140 GB of storage space for newer versions. There is no getting around this.

Once Vivado’s installed, we add this to our ~/.bashrc:

source /tools/Xilinx/Vivado/2022.1/settings64.sh

This ensures we can access Vivado from anywhere on the command line with vivado.

From here, we have to source the board files for our development platform:

  • For Digilent boards, we can follow the steps here.

We also need to create a larger swap file on our system. There’s good odds that Vivado will overflow the existing swap file during compilation, and the process will be killed in the middle of generation:

sudo fallocate -l 16G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon --show
sudo free -h

FPGA bitstream generation

Generating the Pulpissimo bitstream is done with Makefiles, depending on the board. As of May 2024, some directories have moved around, so some things may have broken.

The Xilinx clock generation IP is not pre-generated, so we have to compile this ourselves.

cd target/fpga
cd pulpissimo-nexys_video # replace this with your board of choice
cd ips/xilinx_clk_mngr
make
cd ../xilinx_slow_clk_mngr
make

Then, we cd into target/fpga and:

make nexys_video # or your board of choice

This process will take a while, and if it terminates without issue, the fpga directory should have a .bit and .bin bitstream and binary configuration file. Solid!