---
title: "Simulate and test"
---

# Simulate and test

Testbenches in the Testing view on Icarus Verilog, Verilator, GHDL and NVC, cocotb and VUnit tests, and the vendor simulators (XSim, Questa, Riviera-PRO, Xcelium, VCS) with compiled vendor libraries.

Simulation on the open simulators is **verified on Linux** with the versions given. Vendor simulators are **kit shipped** (Vivado, Quartus) or **modelled** (Libero, Radiant): not yet run against them. Nothing is verified on Windows. Waveforms are on [Waveforms](https://neuralinverse.com/docs/modules/hdl/waveforms/); formal proofs on [Formal proofs and equivalence](https://neuralinverse.com/docs/modules/hdl/formal/).

## Run testbenches

Each testbench of `hdl.json` appears in the Testing view, under **HDL Testbenches**, at the line that declares its top unit. Run it there.

```json
"testbenches": [
  { "name": "adc_monitor_tb", "top": "adc_monitor_tb", "sources": ["tb/adc_monitor_tb.v"], "simulator": "icarus", "timeout": 120 }
]
```

- **Simulator:** the one the testbench names (`verilator`, `icarus`, `ghdl` or `nvc`); otherwise GHDL for VHDL, and Icarus Verilog (or Verilator when Icarus is not installed) for Verilog. VHDL testbenches also run on NVC, by default when GHDL is missing.
- **Pass and fail:** a testbench passes when it finishes with exit code 0 within its `timeout`. It fails on `$fatal`, `$error` or a VHDL assertion of severity error or failure, with the message and source location. Output goes to the test's output.
- **Working folder:** the project folder, so the testbench's relative paths resolve as they do by hand.
- **Waveforms:** a VCD or FST the run writes is linked from the result. GHDL and NVC write an FST of every signal (`neuralInverse.hdl.simulation.ghdlWaveform`, `neuralInverse.hdl.simulation.nvcWaveform`, both on by default).
- **Testbench macros:** a testbench's `defines` adds Verilog macros for it alone.

Extra arguments: `neuralInverse.hdl.simulation.icarusArguments`, `simulation.verilatorArguments`, `simulation.ghdlArguments`, `simulation.nvcArguments`.

State: **verified (Linux)** with Icarus Verilog, Verilator, GHDL and NVC 1.23.

## cocotb

A testbench with a `cocotb` test module runs with cocotb 2 on Icarus Verilog, GHDL, Verilator (5.036 or later) or NVC (through its VHPI library), loaded as cocotb's own runner does.

```json
{ "name": "safety_monitor_cocotb", "top": "safety_monitor", "simulator": "icarus", "cocotb": "tests/test_safety_monitor.py" }
```

- Each `@cocotb.test` shows under its testbench at its function and runs alone or with the others; tests the module makes at run time are added as their results come in.
- A failure shows at the line that raised it, with its message and traceback. The variants of a parametrised test are reported together.
- The Python is `neuralInverse.hdl.cocotb.python`, else the project's `.venv` or `venv`, else `python3`.
- `neuralInverse.hdl.cocotb.waveform` (default on) writes a waveform of the design under test, linked from the result.

![Testbenches, VUnit test cases and cocotb tests passing in the Testing view](https://neuralinverse.com/docs-images/modules/hdl/testing-view.webp)

State: **verified (Linux)** with cocotb 2 on Icarus, GHDL, Verilator and NVC.

## VUnit

A testbench entry can name a VUnit run script instead:

```json
{ "name": "crc16_vunit_ghdl", "vunit": "sim/run.py", "sources": ["vhdl/crc16_ccitt.vhd", "sim/tb_crc16_ccitt.vhd"], "simulator": "ghdl" }
```

- The Testing view lists each test case of its testbenches at its `run` line (from `run.py --export-json`).
- Selected cases run on GHDL or NVC; each case's result, output and failures come from VUnit's JUnit XML. A failure the simulator does not locate is placed at the testbench line with its message.
- On GHDL, each test's waveform is linked from its output (VUnit has NVC write waves only in its GUI mode).
- Install VUnit with `pip install vunit_hdl`. Settings: `neuralInverse.hdl.vunit.python`, `vunit.arguments` (for example `-p 4` or `--fail-fast`), `vunit.waveform`.

![VUnit test cases at their run lines, one failing check with the values it compared](https://neuralinverse.com/docs-images/modules/hdl/vunit-failed-check.webp)

State: **verified (Linux)** with VUnit 4.7.1 and 5.0.0.dev14 on GHDL 4.1.0 and NVC 1.23.0.

## Vendor simulation

Simulation sets imported from a Vivado `.xpr` (`sim_1`) and test benches from a Quartus `.qsf` become items in the Testing view, next to the open-simulator testbenches. Each runs in the vendor simulator with the vendor libraries resolved from your install; the testbench decides pass or fail. A testbench's `vendor` block in `hdl.json` names the target, simulator, stage, timing, run time, simulation set, wave configuration and extra arguments.

| Vendor | Simulators and stages | State |
|---|---|---|
| Vivado | XSim behavioural, post-synthesis and post-implementation, functional or timing, with the netlist and SDF written by Vivado; Questa against `compile_simlib` libraries with a generated `modelsim.ini`; Riviera-PRO, Xcelium and VCS (behavioural) through `export_simulation` | **Kit shipped**; Riviera, Xcelium and VCS logs not checked on real output |
| Quartus | Questa-Intel FPGA Edition with the simulation scripts IP generation writes (`qsys-generate --simulation`, `ip-make-simscript`, `msim_setup.tcl`) | **Kit shipped**; Altera atom library names not checked on a real install |
| Libero | QuestaSim or ModelSim Microchip edition with the Microchip precompiled libraries, behavioural and post-synthesis | **Modelled**; the library path not checked on a real install |
| Radiant | Questa with Radiant's precompiled family library and `pmi_work`, behavioural and post-synthesis | **Modelled**; library folders not checked on a real install |

XSim waves open in the Editor's waveform viewer, laid out from the project's `.wcfg`: the `.wdb` database is proprietary, so the run also writes a VCD, and the Editor says so. See [Waveforms](https://neuralinverse.com/docs/modules/hdl/waveforms/#vivado-wave-configurations).

### Compile simulation libraries

**Compile Simulation Libraries** builds the vendor libraries for a simulator: `compile_simlib` for Questa, Riviera-PRO, Xcelium and VCS from Vivado, or `quartus_sh --simlib_comp` from Quartus. `neuralInverse.hdl.simulation.compiledLibraries` names the folders of compiled libraries by simulator (`questa`, `riviera`, `xcelium`, `vcs`), often a shared folder your company keeps per tool release. A vendor testbench whose libraries are not compiled fails with a message saying so.

State: **kit shipped**. Every generated command line, project and script line is tested, and the parsers on real `xsim`, `xelab` and `vsim` logs and real `.wcfg` files; no vendor simulator has been run.
