.. Embecosm Application Note "Howto: Bringing up ExecuTorch on a Bare Metal
   Microcontroller". Setting up

   Copyright (C) 2026 Embecosm Limited
   Contributor: Jeremy Bennett
   Contributor: Pietra Ferreira
   Contributor: William Jones
   Contributor: Shane Slattery

   SPDX-License-Identifier: CC-BY-SA-4.0

.. _setting_up:

******************************
Setting up to run the examples
******************************

.. index:: ! ExecuTorch; setting up

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

Prerequisites
=============

.. index::
   single: ExecuTorch; prerequisites

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

.. code-block:: bash

   sudo apt install build-essential

For speed we use the :term:`Ninja` build system.

.. code-block:: bash

   sudo apt install ninja-build

.. index::
   single: Verilator

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

.. code-block:: bash

   sudo apt install verilator

It is quite likely that the version of :term:`Verilator` will not be new
enough.  This is a tool which is easy to build from source.  Follow the
instructions on the `Veripool website <https://www.veripool.org/verilator/>`_
to download and build from source.  Version 5.042 was used in preparing this
workshop.

.. index::
   single: CV32E40Pv2; tool chain
   single: CV32E40Pv2; GCC
   single: CV32E40Pv2; Clang/LLVM

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

We have used :term:`GCC` for the examples here.  Prebuilt binaries are
available for a wide range of platforms from the `Embecosm website
<https://embecosm.com/downloads/tool-chain-downloads/#core-v-top-of-tree-compilers>`_.

.. important::

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

   .. code-block:: bash

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

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

* `CORE-V GCC <https://github.com/openhwgroup/corev-gcc>`_.
* `CORE-V LLVM <https://github.com/openhwgroup/corev-llvm-project>`_.
* `CORE-V binutils <https://github.com/openhwgroup/corev-binutils-gdb>`_.
* The generic :term:`Newlib` repository is available via its `project home
  page <https://sourceware.org/newlib/>`_.

.. _setup_file_hierarchy:

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
  :term:`CORE-V` CV32E series of processors, including the :term:`CV32E40Pv2`.
* ``examples``: The example models used in :ref:`appendix_neural_networks`.
* ``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.

The Python virtual environment
==============================

.. index::
   single: Python; virtual environment

We will need to install various Python tools in order to work with
:term:`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 :ref:`setup_file_hierarchy`).

.. code-block:: bash

   python3 -m venv .venv

Then activate the virtual environment

.. code-block:: bash

   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

.. code-block:: bash

   pip install --upgrade pip

You can leave the Python virtual environment using

.. code-block:: bash

   deactivate

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

Python package prerequisites
----------------------------

The Verilator model needs the Python YAML package.

.. code-block:: bash

   pip install pyyaml

Getting the source code
=======================

.. index:: ! repositories

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

.. code-block:: bash

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

For SSH users:

.. code-block:: bash

   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:

.. code-block:: bash

   cd tooling
   ./clone-all.sh

For SSH users (less entering of passwords):

.. code-block:: bash

   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 :term:`ExecuTorch` repository includes many submodules.  The
   ``clone-all.sh`` script will recursively clone and update these
   automatically, which takes some time.

Building and running the target model
=====================================

.. index::
   single: CV32E40Pv2; on FPGA
   single: CV32E40Pv2; Verilator model

It is possible to run the target on physical hardware, using an FPGA board.
However for this application note, we will use :term:`Verilator` to create a
cycle accurate model of the processor.  This is a very simple model, with just
the :term:`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.

.. image:: images/cv32e40pv2-overview.png
   :align: center

.. index::
   CV32E40Pv2; Verilator model; build script

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

.. code-block:: bash

   cd tooling
   ./build-model.sh

.. index::
   single: CV32E40Pv2; board support package
   single: CV32E40Pv2; BSP

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

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

--clean
   Remove any previously built model and :term:`BSP`

.. index::
   single: CV32E40Pv2; Verilator model; VCD trace

--trace
   Enable :term:`VCD` tracing in the model (which will run *much* slower as a
   consequence).

--no-pulp
   Disable the :term:`PULP` :term:`ISA` extensions

-h, --help
   Print a help message about the available options.

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

.. code-block:: bash

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

.. index::
   single: CV32E40Pv2; binary format (hexdump)

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

.. code-block:: bash

   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
:ref:`Creating a hexdump image for Verilator
<runtime_creating_hexdump_model>`).
