<commit_before>---
title: Verilator Setup
aliases:
    - /doc/ug/getting_started_verilator
---

_Before following this guide, make sure you've followed the [dependency installation and software build instructions]({{< relref "getting_started" >}})._

## About Verilator

Verilator is a cycle-accurate simulation tool.
It translates synthesizable Verilog code into a simulation program in C++, which is then compiled and executed.

### Install Verilator

Even though Verilator is packaged for most Linux distributions these versions tend to be too old to be usable.
We recommend compiling Verilator from source, as outlined here.

Fetch, build and install Verilator itself (this should be done outside the `$REPO_TOP` directory).

```console
export VERILATOR_VERSION={{< tool_version "verilator" >}}

git clone https://github.com/verilator/verilator.git
cd verilator
git checkout v$VERILATOR_VERSION

autoconf
./configure --prefix=/tools/verilator/$VERILATOR_VERSION
make
make install
```

After installation you need to add `/tools/verilator/$VERILATOR_VERSION/bin` to your `PATH` environment variable.
Also add it to your `~/.bashrc` or equivalent so that it's on the `PATH` in the future, like this:
```console
export PATH=/tools/verilator/$VERILATOR_VERSION/bin:$PATH
```

Check your installation by running:
```console
$ verilator --version
Verilator 4.210 2021-07-07 rev v4.210 (mod)
```

#### Troubleshooting

If you need to install to a different location than `/tools/verilator/...`, you can pass a different directory to `./configure --prefix` above and add `your/install/location/bin` to `PATH` instead.

## Running Software on a Verilator Simulation with Bazel

First the RTL must be built into a simulator binary.
This is done by running fusesoc, which collects up RTL code and passes it to Verilator to generate and then compile a C++ model.
Next software must be built to run on the simulated hardware.
There are 4 memory types on OpenTitan hardware: ROM, Flash, OTP, and SRAM.
Software images need to be provided for ROM, Flash, and OTP (SRAM is populated at runtime).
By default, the system will first execute out of ROM and then jump to Flash.
The OTP image does not contain executable code, rather it contains root secrets, runtime configuration data, and life cycle state.
(By default, the life cycle state is set to RMA, which enables debugging features such as the JTAG interface for the main processor.)
Lastly, the Verilator simulation binary must be run with the correct arguments.

Thankfully, Bazel (and `opentitantool`) simplify this process by providing a single interface for performing all of the above steps.<commit_msg>[doc] Add compiler notes for Verilator build<commit_after>---
title: Verilator Setup
aliases:
    - /doc/ug/getting_started_verilator
---

_Before following this guide, make sure you've followed the [dependency installation and software build instructions]({{< relref "getting_started" >}})._

## About Verilator

Verilator is a cycle-accurate simulation tool.
It translates synthesizable Verilog code into a simulation program in C++, which is then compiled and executed.

### Install Verilator

Even though Verilator is packaged for most Linux distributions these versions tend to be too old to be usable.
We recommend compiling Verilator from source, as outlined here.

Fetch, build and install Verilator itself (this should be done outside the `$REPO_TOP` directory).
Note that Verilator 4.210 will not build with GCC 12.0 or later, so it will need to be built with an older toolchain.
The example below assumes gcc-11 and g++-11 are installed on the system.

```console
export VERILATOR_VERSION={{< tool_version "verilator" >}}

git clone https://github.com/verilator/verilator.git
cd verilator
git checkout v$VERILATOR_VERSION

autoconf
CC=gcc-11 CXX=g++-11 ./configure --prefix=/tools/verilator/$VERILATOR_VERSION
CC=gcc-11 CXX=g++-11 make
CC=gcc-11 CXX=g++-11 make install
```

After installation you need to add `/tools/verilator/$VERILATOR_VERSION/bin` to your `PATH` environment variable.
Also add it to your `~/.bashrc` or equivalent so that it's on the `PATH` in the future, like this:
```console
export PATH=/tools/verilator/$VERILATOR_VERSION/bin:$PATH
```

Check your installation by running:
```console
$ verilator --version
Verilator 4.210 2021-07-07 rev v4.210 (mod)
```

#### Troubleshooting

If you need to install to a different location than `/tools/verilator/...`, you can pass a different directory to `./configure --prefix` above and add `your/install/location/bin` to `PATH` instead.

## Running Software on a Verilator Simulation with Bazel

First the RTL must be built into a simulator binary.
This is done by running fusesoc, which collects up RTL code and passes it to Verilator to generate and then compile a C++ model.
Next software must be built to run on the simulated hardware.
There are 4 memory types on OpenTitan hardware: ROM, Flash, OTP, and SRAM.
Software images need to be provided for ROM, Flash, and OTP (SRAM is populated at runtime).
By default, the system will first execute out of ROM and then jump to Flash.
The OTP image does not contain executable code, rather it contains root secrets, runtime configuration data, and life cycle state.
(By default, the life cycle state is set to RMA, which enables debugging features such as the JTAG interface for the main processor.)
Lastly, the Verilator simulation binary must be run with the correct arguments.

Thankfully, Bazel (and `opentitantool`) simplify this process by providing a single interface for performing all of the above steps.
{'fraction_non_alphanumeric': 0.07571147306246644, 'fraction_numerical': 0.010202255235367818, 'mean_word_length': 4.702040816326531, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1352102', 'n_tokens_mistral': 1634, 'n_tokens_neox': 1512, 'n_words': 762}