3. Setting up to run the examples

The examples used in this application note have been tested on a laptop running Ubuntu 24.04. The application note is based on ExecuTorch 1.3.1.

3.1. Prerequisites

The guidelines here are for Ubuntu 24.04, but should be similar for other systems. First we need the general build tools.

sudo apt install build-essential

For speed we use the Ninja build system.

sudo apt install ninja-build

Our target will be modeled using the Verilator modeling tool. This can be installed as follows.

sudo apt install verilator

It is quite likely that the version of Verilator will not be new enough. This is a tool which is easy to build from source. Follow the instructions on the Veripool website to download and build from source. Version 5.042 was used in preparing this workshop.

Finally we will need a compiler tool chain, so we can compile code for the CV32E40Pv2. It is possible to use upstream tool chains (either GCC or LLVM), but these currently lack full support for all the PULP ISA extensions, which are used in this application note. However there is a downstream fork of both GCC and LLVM for CORE-V with full support for the extensions.

We have used GCC for the examples here. Prebuilt binaries are available for a wide range of platforms from the Embecosm website.

Important

Once you have installed the compiler tool chain, you need to ensure it is on your path. For example under Linux using the bash shell, you would use.

export PATH=<toolchain install location>/bin:${PATH}

If you prefer you can build either GCC or LLVM tool chains for CORE-V from source. Alongside the compiler, you will need the low level utilities (binutils) and a bare metal library, such as Newlib. The repositories needed are as follows.

3.2. File hierarchy

The file hierarchy is as follows. At the top level we have four repositories.

  • core-v-verif: The upstream CORE-V verification framework for the CORE-V CV32E series of processors, including the CV32E40Pv2.

  • examples: The example models used in Appendix: An introduction to neural networks with PyTorch.

  • executorch: A fork of ExecuTorch 1.3.1 (and associated submodules), extended with the changes described in this application note. Git tags are used to identify the code changes associated with each chapter.

  • tooling: The scripts and configuration files used in this application note.

In addition, the following directories are created at the top level when building and running the code.

  • build: The build directory for tools

  • install: The installation directory for tools

  • logs: The location of build and execution logs.

It is usual to run all this inside one top directory, to allow the work to remain grouped.

3.3. The Python virtual environment

We will need to install various Python tools in order to work with ExecuTorch. In order to avoid conflicts with system installations, we recommend working with a Python virtual environment. First create the virtual environment, in a local hidden directory (.venv in this example). This is usually done in the top level directory (see File hierarchy).

python3 -m venv .venv

Then activate the virtual environment

source .venv/bin/activate

From this point any Python installations will be kept in the .venv directory, rather than conflicting with the system. The first time the virtual environment is activated, ensure its version of pip is up to date

pip install --upgrade pip

You can leave the Python virtual environment using

deactivate

To re-enter the Python virtual environment, just use source .venv/bin/activate again.

3.3.1. Python package prerequisites

The Verilator model needs the Python YAML package.

pip install pyyaml

3.4. Getting the source code

The four key repositories were described earlier (see File hierarchy). The initial step is to clone the tooling repository, selecting the branch for this application note. For HTTPS users:

git clone -b ean16-1.0 https://github.com/embecosm/ean16-tooling.git tooling

For SSH users:

git clone -b ean16-1.0 git@github.com:embecosm/ean16-tooling.git tooling

Inside the tooling repository is a script to clone the other two repositories. For HTTPS users:

cd tooling
./clone-all.sh

For SSH users (less entering of passwords):

cd tooling
./clone-all.sh --ssh

Warning

The repositories are cloned as peers of the tooling repository. It is for this reason we suggest working in a dedicated top level directory, rather than just the users’ home directory.

Note

The ExecuTorch repository includes many submodules. The clone-all.sh script will recursively clone and update these automatically, which takes some time.

3.5. Building and running the target model

It is possible to run the target on physical hardware, using an FPGA board. However for this application note, we will use Verilator to create a cycle accurate model of the processor. This is a very simple model, with just the CV32E40Pv2 processor core, 4MB of RAM and a pseudo peripheral to allow characters written to a specific location to be output to the console. The overall design is shown in the following diagram.

_images/cv32e40pv2-overview.png

The tooling repository has a script to build a C++ cycle accurate model using Verilator.

cd tooling
./build-model.sh

The model will be created and compiled in place. The script will also create a small Board Support Package (BSP), which must be linked in when building any program to be run on the model. It provides C runtime startup code (crt0.o) and a library to provide access to standard output via the pseudo peripheral. The BSP library replaces the libgloss functionality of Newlib.

There are a number of options to the build-model.sh script.

--clean

Remove any previously built model and BSP

--trace

Enable VCD tracing in the model (which will run much slower as a consequence).

--no-pulp

Disable the PULP ISA extensions

-h, --help

Print a help message about the available options.

Any program once linked with the BSP can then be run on the term:Verilator model using the following command.

../core-v-verif/cv32e40p/sim/core/cobj_dir/Vtb_top_verilator \
 +firmware=<binary as hex>

The binary has to be in Verilog hexdump format. This can be created from a standard ELF object using the objcopy command from binutils as follows.

riscv32-corev-elf-objcopy -O verilog <ELF binary file> <Hex binary file>

We will see these techniques in use later in this application note (see Creating a hexdump image for Verilator).