Simulate

This project supports simulation with Verilator, Synopsys VCS, Siemens Questasim and Cadence Xcelium. We use FuseSoC for all the EDA tools we use. The fusesoc commands are used in the targets in the Makefile. Below the different EDA examples commands.

Simulating with Verilator

To simulate your application with Verilator, first build the Verilator model:

make verilator-build

Then, you can run the compiled application with:

make verilator-run

Alternatively, you can run the application manually by going to your target system build folder

cd ./build/openhwgroup.org_systems_core-v-mini-mcu_<version>/sim-verilator

and type to run your compiled application:

./Vtestharness +firmware=../../../sw/build/main.hex

Finally, you can check the output by running:

cat uart0.log

You can directly compile the app and run all of the previous steps with:

make verilator-run-app

Warning

The verilator-run-app target calls the app target, so the application will be recompiled with default parameters unless you add specific ones like make verilator-run-app PROJECT=hello_world.

If you have gtkwave installed, you can view the waveform generated by the last Verilator simulation with:

make verilator-waves

Simulating with VCS

To simulate your application with VCS, first compile the HDL:

make vcs-build

then, go to your target system built folder

cd ./build/openhwgroup.org_systems_core-v-mini-mcu_<version>/sim-vcs

and type to run your compiled software:

./openhwgroup.org_systems_core-v-mini-mcu_<version> +firmware=../../../sw/build/main.hex

Waveforms can be viewed with Verdi. Make sure you have the env variable VERDI_HOME set to your Verdi install folder, then run your compiled software as above, but with the -gui flag:

./openhwgroup.org_systems_core-v-mini-mcu_<version> +firmware=../../../sw/build/main.hex -gui

An Analog / Mixed-Signal simulation of X-HEEP, combining both the RTL system verilog files for the digital part and a SPICE file connected through a control.init file for the analog / mixed-signal part, can be ran by typing

make vcs-ams-build

then going to the target system built folder

cd ./build/openhwgroup.org_systems_core-v-mini-mcu_<version>/sim-vcs

and running the same executable as for the digital simulation. Note that with Verdi you can view both the digital and the analog waveforms.

Additional instructions on how to run an analog / mixed-signal simulation of X-HEEP can be found here. To try out the simulation, we provide an example SPICE netlist of a simple 1-bit ADC created by us and exported from xschem and which uses the PTM 65nm bulk CMOS model from https://ptm.asu.edu.

Simulating with Questasim

To simulate your application with Questasim, first set the env variable MODEL_TECH to your Questasim bin folder, then compile the HDL:

make questasim-build

Then, you can run the compiled application with:

make questasim-run

Alternatively, you can run the application manually by going to your target system build folder

cd ./build/openhwgroup.org_systems_core-v-mini-mcu_<version>/sim-modelsim/

and type to run your compiled software:

make run PLUSARGS="c firmware=../../../sw/build/main.hex"

You can directly compile the app and run all of the previous steps with:

make questasim-run-app

You can also use vopt for HDL optimized compilation:

make questasim-build-opt

Then, you can run the compiled application with:

make questasim-run-opt

Alternatively, go to

cd ./build/openhwgroup.org_systems_core-v-mini-mcu_<version>/sim-modelsim/

and

make run RUN_OPT=1 PLUSARGS="c firmware=../../../sw/build/main.hex"

You can directly compile the app and run all of the previous steps with:

make questasim-run-opt-app

You can also compile with the UPF power domain description as:

make questasim-build-opt-upf FUSESOC_PARAM="--USE_UPF"

then, go to your target system built folder

cd ./build/openhwgroup.org_systems_core-v-mini-mcu_<version>/sim-modelsim/

and then execute software as:

make run RUN_OPT=1 RUN_UPF=1 PLUSARGS="c firmware=../../../sw/build/main.hex"

Questasim version must be >= Questasim 2020.4

Simulating with Xcelium

To simulate your application with Xcelium, first compile the HDL:

make xcelium-build

then, go to your target system built folder

cd ./build/openhwgroup.org_systems_core-v-mini-mcu_<version>/sim-xcelium/

and type to run your compiled software:

make run PLUSARGS="c firmware=../../../sw/build/main.hex"

Simulation parameters

You may pass additional simulation parameters to the generated simulation executable, in the form of plusargs: +<parameter>=<value>.

  • +firmware=<path>: Loads the hex file specified in <path> into memory. This allows you to run a compiled executable directly, as if it were already written in memory since the beginning of the simulation. For example, ./Vtestharness +firmware=../../../sw/build/main.hex will launch the Verilator simulation and instruct it to load the compiled application executable into memory and run it.

    When launching the simulation through the dedicated make target, like make verilator-run, the +firmware parameter is automatically propagated to the simulation executable.

  • +boot_sel=<val>: Runs the simulation booting from testbench/jtag (val=0) or loading the firmware from the external flash (val=1). When 0 (by default), you can run a compiled executable directly, as if it were already written in memory since the beginning of the simulation. While if it is 1, the code is loaded from the external flash via SPI. For example, ./Vtestharness +firmware=../../../sw/build/main.hex +boot_sel=1 will launch the Verilator simulation and instruct the bootrom to copy the firmware from the external flash to the main memory, then, the CPU will jump to SRAM and execute the code.

    When launching the simulation through the dedicated make target, like make verilator-run, the +boot_sel parameter can be be passed to the simulation executable via the SIM_ARGS command-line argument, e.g. make verilator-run SIM_ARGS="+boot_sel=1".

  • +max_sim_time=<time>: Runs the simulation for a maximum of <time> clock cycles. This is useful in case your application gets stuck in a certain point and never finishes; this parameter will force the simulation to terminate after a certain time so that you can later analyze the generated waveform.fst (or waveform.vcd if using QuestaSim) file. In that case, the simulation executable will exit with a return code of 2, indicating premature termination. If this parameter is not provided, the simulation will run until the program finishes (the main() function ends).

    Alternatively, you may add a time suffix (s, ms, us, ns, ps) to run the simulation until the specified simulation time has been reached (1 clock cycle = 10ns). This is, +max_sim_time=750us is the same as +max_sim_time=75000. (Note that there’s no space between the number and the unit, and that fractional values are not supported.)

    If you’re launching the Verilator simulation via make, you may pass this parameter via the MAX_SIM_TIME= command-line argument, e.g. make verilator-run MAX_SIM_TIME=750us.

Simulating the UART DPI

To simulate the UART, we use the LowRISC OpenTitan UART DPI. Read how to interact with it in the Section “Running Software on a Verilator Simulation with Bazel” here. The output of the UART DPI module is printed in the uart0.log file in the simulation folder. The content of this file is automatically printed on the console once the simulation successfully completes.