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.
The generic Newlib repository is available via its project home page.
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 toolsinstall: The installation directory for toolslogs: 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.
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
- -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).