Pavona 101: Getting Started

Welcome to the Pavona open-source silicon ecosystem! Pavona is vast, featuring dozens of high-quality IP blocks with tooling that can combine it in countless possible configurations. Pavona supports a wide variety of toolflows, from Verilator simulation to DV flows and tapeout-ready ASIC synthesis.

This guide helps new users download the Pavona repository, install system requirements, and run a basic test that shows all of Pavona’s components working together. For simplicity, this guide shows you just the steps you need to get a test running on your system. After this guide, you’ll be able to refer to other guides to modify the hardware, run on an FPGA, run DV tests, and more.

Basic system requirements

Check that your system meets the following system requirements:

  • Ubuntu 22.04, 24.04, or 26.04, or macOS 26 or 27 on Apple Silicon
  • At least 7 GiB RAM (32 GiB recommended)
  • At least 512 GiB of disk space

We recommend using Ubuntu. macOS support is experimental: everything in this guide works there, but the FPGA, DV, and formal flows in the later guides require Linux. Where the steps differ, this guide gives them for each platform.

Ubuntu

This guide describes instructions for Ubuntu 22.04 (“jammy”).

First, check that you are running a suitable Linux distribution.

cat /etc/os-release

which prints something like:

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
  ...

Ensure that you have the appropriate system dependencies to proceed to the next step.

sudo apt update
sudo apt upgrade

macOS

Install Homebrew, which also installs the Xcode Command Line Tools and with them Git.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

The installer ends by printing the commands that add brew to your PATH. For the default shell, zsh, they are:

echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Get Pavona

We recommend most people get a Pavona release from the Releases page.

More advanced users (developers and contributors) who are interested in working on bleeding-edge Pavona development should use Git to clone the Pavona repository.

The best way to get Pavona is to download a release from the Releases page of the Pavona repository. The latest release is https://github.com/pavona/pavona/releases/latest. Download the source code (available as a tarball or zip file) and decompress it.

If you downloaded a tarball (*.tar.gz), use:

tar -xzf [Pavona release name].tar.gz

If you downloaded a zip file (*.zip), use:

unzip [Pavona release name].zip

Advanced: Clone the Pavona repository

Developers and contributors interested in modifying Pavona can use Git to clone the repository. The Pavona Git repository contains the newest features and bugfixes, but it is considered experimental. For the best stability, use a Pavona release.

If you’d like to contribute code to Pavona, create your own fork in order to open pull requests (see the Github notes). You cannot push a branch directly to the Pavona Git repository.

On Ubuntu, install Git first:

sudo apt install -y git

Then clone the repository:

git clone https://github.com/pavona/pavona

which prints something like:

Cloning into 'pavona'...
   ...
Updating files: 100% (13468/13468), done.

Git clones the main branch by default; use git switch or git checkout to change to a release tag if desired. Release tags are named release/[YYYY].[MM].p[#]. See the available releases at the Pavona releases page.

Whether you used a Pavona release or cloned the Pavona repository, the following instructions assume the directory is named “pavona”.

Install system dependencies

Change into the pavona/ directory and you’ll find the following files:

cd pavona
ls

which prints something like:

BUILD.bazel        SUMMARY.md               quality
Brewfile           apt-requirements.txt     release
CLA-Corporate      bazelisk.sh              rfc
CLA-Individual     bench                    rules
CONTRIBUTING.md    book.toml                signing
CONTRIBUTORS       ci                       sw
LICENSE            compile_flags.txt        third_party
MODULE.bazel       doc                      toolchain
MODULE.bazel.lock  hw                       util
NOTICE             mypy.ini                 yum-requirements.txt
README.md          pyproject.toml
SECURITY.md        python-requirements.txt

The additional packages you’ll need in order to work with Pavona are listed in a file per platform.

Ubuntu

The file apt-requirements.txt contains a list of the additional Ubuntu packages you’ll need to install in order to work with Pavona. The following command processes this file and passes it to apt to install them:

sed '/^#/d' apt-requirements.txt | xargs sudo apt install -y

macOS

The file Brewfile contains a list of the Homebrew packages you’ll need. The following command installs them:

brew bundle install --file=Brewfile

Python

Anything you build or test with Bazel brings its own Python, so no Python setup is needed here. The few tools that run outside Bazel, such as util/dvsim/dvsim.py and util/regtool.py, do need one; see Python Environment Setup.

Build and run a test

Build a test with Bazel

Bazel is the tool used to build software that runs on Pavona. We’d like to build the “Hello, world!” application, which lives in the sw/device/examples/hello_world directory:

ls sw/device/examples/hello_world/

which prints something like:

BUILD  README.md  hello_world.c

If you examine hello_world.c, you’ll see that the main test code is located in _ottf_main(void), which contains the following C macro invocations:

void _ottf_main(void) {
  ...
  LOG_INFO("Hello World!");
  ...
  LOG_INFO("Built at: " __DATE__ ", " __TIME__);
  ...
}

To build this test, invoke Bazel through a script called bazelisk.sh, which fetches the correct version of Bazel for you, then builds the hello_world binary. Note that there is an extra colon (:) between the directory (sw/device/examples/hello_world) and the name of the target (hello_world).

./bazelisk.sh build sw/device/examples/hello_world:hello_world

which prints something like:

...
Target //sw/device/examples/hello_world:hello_world up-to-date:
  ...
  bazel-bin/sw/device/examples/hello_world/hello_world_sim_verilator.64.vmem
  bazel-bin/sw/device/examples/hello_world/hello_world_sim_verilator.elf
  bazel-bin/sw/device/examples/hello_world/hello_world_sim_verilator.dis
  bazel-bin/sw/device/examples/hello_world/hello_world_sim_verilator.map
  ...
INFO: Build completed successfully, 49 total actions

The output (with some trimming) shows the files that were built. You can examine the RISC-V (dis)assembly in the bazel-bin/sw/device/examples/hello_world/hello_world_sim_verilator.dis file.

[!TIP] By default, Verilator only uses a single core for simulation. Modern machines have many cores, and you can make use of them by using the --//hw:verilator_options flag. Create a file named .bazelrc-site containing a line like the following:

common --//hw:verilator_options=--threads,8

The above example would be appropriate for a machine with 8 cores (you can determine the number of cores in your CPU by running the nproc command, or sysctl -n hw.ncpu on macOS).

Run a test on Verilator

Run the “Hello, World!” binary by using Bazel:

./bazelisk.sh test sw/device/examples/hello_world:hello_world_sim_verilator --test_output=streamed

In the Pavona project, a specific run is assembled by concatenating the name of the binary (hello_world) with the name of an execution environment (sim_verilator). Bazel uses this to set up the correct environment by building the Verilator binary. This process takes about 10 minutes. After this, the test run begins. The simulated Pavona top-level will begin printing to the display because of the --test_output=streamed flag. The test itself takes about 60 seconds to run.

I00001 test_rom.c:193] kChipInfo: scm_revision=54697461
I00002 test_rom.c:270] Test ROM complete, jumping to flash (addr: 20000480)!
I00000 hello_world.c:37] Hello World!
I00001 hello_world.c:40] Built at: Mar 01 2026, 12:34:56
I00002 hello_world.c:44] PASS!
[... INFO  opentitantool::command::console] ExitSuccess("PASS!\r\n")
[... INFO  opentitantool] Command result: success.
[... INFO  opentitantool] Command result: success.
INFO: Found 1 test target...
Target //sw/device/examples/hello_world:hello_world_sim_verilator up-to-date:
  bazel-bin/sw/device/examples/hello_world/hello_world_sim_verilator.bash
INFO: Elapsed time: 59.108s, Critical Path: 58.46s
INFO: 2 processes: 12 action cache hit, 2 processwrapper-sandbox.
INFO: Build completed successfully, 2 total actions
//sw/device/examples/hello_world:hello_world_sim_verilator               PASSED in 58.2s

Executed 1 out of 1 test: 1 test passes.

Rerunning a test

If you’d like to run the test again, you’ll likely see:

./bazelisk.sh test sw/device/examples/hello_world:hello_world_sim_verilator

which prints something like:

...
INFO: Analyzed target //sw/device/examples/hello_world:hello_world_sim_verilator (0 packages loaded, 4 targets configured).
INFO: Found 1 test target...
Target //sw/device/examples/hello_world:hello_world_sim_verilator up-to-date:
  bazel-bin/sw/device/examples/hello_world/hello_world_sim_verilator.bash
INFO: Elapsed time: 0.612s, Critical Path: 0.22s
INFO: 1 process: 13 action cache hit, 1 internal.
INFO: Build completed successfully, 1 total action
//sw/device/examples/hello_world:hello_world_sim_verilator      (cached) PASSED in 58.2s

Executed 0 out of 1 test: 1 test passes.

This is because Bazel caches your test results, which is useful if you haven’t changed your code. To re-run a test, pass the additional flag --cache_test_results=false to your ./bazelisk.sh invocation.

Modify a test

Your first step to exploring the Pavona repository will be to get your hands dirty (just a little bit). Modify the hello_world.c file to say something other than “Hello World!”. Build and run the test with the above ./bazelisk.sh test invocation. (Bazel automatically rebuilds any modified tests.)

Next steps

Congratulations! You’ve just set up your system, downloaded the Pavona repository, and run a test on verilated hardware. There are many steps forward from here: