Simulation

Parallel Simulations

Validate and benchmark every configuration of an example design in parallel, using a simulator such as Verilator or GHDL.

In this tutorial, you will run simulations for every configuration of a Cordic example design. This design has two parameters: iterations and width. Each parameter has several values, which combine into several configurations. Odatix will run a simulation for each configuration, in parallel. This example has two identical implementations, one in SystemVerilog and one in VHDL.

Prerequisites

For this tutorial, you need at least one of the following tools installed and available in your PATH:

Make sure you have Odatix installed and available in your PATH. For example, if you installed Odatix in a virtual environment, activate it first:

Terminal
source odatix_venv/bin/activate

Steps

Step 1 — Initialize an example workspace

Create a new directory for the demonstration and move into it. For example:

Terminal
mkdir ~/odatix_examples && cd ~/odatix_examples

Create a new Odatix workspace and copy the built-in examples into it:

Terminal
odatix init --examples

 ██████╗  ██████╗   █████╗ ████████╗ ██╗ ██╗  ██╗
██╔═══██╗ ██╔══██╗ ██╔══██╗╚══██╔══╝ ██║ ╚██╗██╔╝
██║   ██║ ██║  ██║ ███████║   ██║    ██║  ╚███╔╝ 
██║   ██║ ██║  ██║ ██╔══██║   ██║    ██║  ██╔██╗ 
╚██████╔╝ ██████╔╝ ██║  ██║   ██║    ██║ ██╔╝ ██╗
 ╚═════╝  ╚═════╝  ╚═╝  ╚═╝   ╚═╝    ╚═╝ ╚═╝  ╚═╝

[settings.py] Your directory can now be used by Odatix!
[settings.py] Run odatix -h to get a list of useful commands

Step 2 — Choose what to simulate

Open odatix_userconfig/simulations_settings.yml. Each entry maps a simulation to the list of architectures to run it on:

odatix_userconfig/simulations_settings.yml
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
simulations:
  - TB_Example_Cordic_Verilator:
    - Example_Cordic_sv + iterations/* + width/*
 
  - TB_Example_Cordic_GHDL:
    - Example_Cordic_vhdl + iterations/* + width/*

  - TB_Example_Cordic_QuestaSim:
    - Example_Cordic_sv + iterations/* + width/*
    - Example_Cordic_vhdl + iterations/* + width/*

  - TB_Example_Cordic_Vivado:
    - Example_Cordic_sv + iterations/* + width/*
    - Example_Cordic_vhdl + iterations/* + width/*

  # - TB_Example_Counter_GHDL:
  #   - Example_Counter_vhdl/*

  # - TB_Example_Counter_Verilator:
  #   - Example_Counter_sv/*

To disable a confiuguration and/or simulation, comment it out with # or simply remove the line.

Note

The * wildcard selects all configurations in the architecture’s directory. You can replace it with a specific configuration name, or use multiple lines to select several configurations. Here + iterations/* + width/* means “all combinations of the iterations and width parameters”.

Step 3 — Run

Simulations are run with the odatix sim command:

Terminal
odatix sim

 ██████╗  ██████╗   █████╗ ████████╗ ██╗ ██╗  ██╗
██╔═══██╗ ██╔══██╗ ██╔══██╗╚══██╔══╝ ██║ ╚██╗██╔╝
██║   ██║ ██║  ██║ ███████║   ██║    ██║  ╚███╔╝ 
██║   ██║ ██║  ██║ ██╔══██║   ██║    ██║  ██╔██╗ 
╚██████╔╝ ██████╔╝ ██║  ██║   ██║    ██║ ██╔╝ ██╗
 ╚═════╝  ╚═════╝  ╚═╝  ╚═╝   ╚═╝    ╚═╝ ╚═╝  ╚═╝


New simulations:
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:4]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:8]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:12]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:4]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:8]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:12]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:4]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:8]
  - TB_Example_Cordic_Verilator: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:12]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:4]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:8]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:12]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:4]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:8]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:12]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:4]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:8]
  - TB_Example_Cordic_GHDL: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:12]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:4]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:8]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:12]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:4]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:8]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:12]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:4]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:8]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:12]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:4]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:8]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:12]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:4]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:8]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:12]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:4]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:8]
  - TB_Example_Cordic_QuestaSim: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:12]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:4]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:8]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:12, width:12]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:4]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:8]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:16, width:12]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:4]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:8]
  - TB_Example_Cordic_Vivado: Example_Cordic_sv/Example_Cordic_sv [iterations:24, width:12]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:4]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:8]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:12, width:12]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:4]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:8]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:16, width:12]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:4]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:8]
  - TB_Example_Cordic_Vivado: Example_Cordic_vhdl/Example_Cordic_vhdl [iterations:24, width:12]

Total: 54
Continue? (Y/n)

Note

Like every run command, sim enqueues jobs in the daemon and attaches the Job Monitor, so you see progress and logs for each configuration live.

Step 4 — Monitor the jobs

The job monitor shows the status of each job, and the log of the currently selected job. You can detach and re-attach to the monitor at any time. More information is available in Sessions & Job Monitor documentation page.

Tip

Use PageUp and PageDown keys to change jobs and the Up and Down keys to scroll logs. The mouse can also be used to scroll and select jobs.
Use d to detach and let the job run in the background, and run odatix monitor to re-attach.
Use q to quit when all jobs are complete.

Step 5 — Explore the results

What each simulation exports is declared in its _metrics.yml; results land in results/results_simulation.yml as jobs finish. Re-export at any time — for instance after editing a metric — then open the dashboard:

Terminal
odatix-explorer

Going further

Because simulation metrics live next to synthesis metrics, you can answer questions that need both — such as which configuration has the best benchmark score per watt/usage/area. Computing a value from both, such as a runtime, is what derived metrics are for.

For validation pipelines with several steps, dependencies or non-HDL tools, use workflows instead of sim.