CVA6 - Verilator model and VCD generation
Introduction
CVA6 is a processor from the OpenHW Group: 64-bit, Linux-capable and written in SystemVerilog.
Requirements
In order to generate a CVA6 model with export, Verilator must be installed from sources as the Makefile requires a C++ file https://github.com/pcotret/cva6/blob/vcd_patch/Makefile#L551. For this tutorial, Verilator 4.110 was chosen as it is used in the official CI flow.
|
|
Verilator binaries are generated in <verilator_cloned_repo/bin>
and must be added to PATH
.
Environment variables
export VERILATOR_ROOT=<verilator_cloned_repo>
: path for C++ files required to generate a VCD-capable model.export CVA6_REPO_DIR=<cva6_cloned_repo>
: CVA6 repository.export RISCV=<riscv_toolchain>
: RISC-V toolchain.export PATH=<verilator_cloned_repo>/bin:$PATH
: Verilator binaries added toPATH
.
Verilator model
It is assumed you have cloned the CVA6 repository and its submodules.
|
|
The model is generated at: work-ver/Variane_testharness
. Please note that make verilate
will generate a model without VCD if needed.
Default simulation
|
|
Simulation and VCD exploitation
|
|
-v
specifies the name of the VCD file.
Binaries support
Bare metal binaries generated from https://github.com/riscv-software-src/riscv-tests should work without modifications.
Example of CVA6 and GTKWave on a simple test
|
|
Let’s say we want to analyze/check the tests 3 and 4 of rv64ui-p-add
.
In GTKWave, we will watch:
- The instruction address.
- The instruction value.
- Register addresses (
rs1
,rs2
andrd
as we check a R-type instruction). - Result of the ALU.
Reading the dump of the test, we will look at this part:
|
|
|
|
Signals observed in GTKWave
Note: sometimes, it’s helpful to have the Vivado project opened. Much easier to explore the CPU hierarchy
TOP.ariane_testharness.i_ariane.i_cva6.id_stage_i.fetch_entry_i.address[63:0]
TOP.ariane_testharness.i_ariane.i_cva6.id_stage_i.fetch_entry_i.instruction[31:0]
TOP.ariane_testharness.i_ariane.i_cva6.id_stage_i.decoder_i.instr.rtype.rs1[19:15]
TOP.ariane_testharness.i_ariane.i_cva6.id_stage_i.decoder_i.instr.rtype.rs2[24:20]
TOP.ariane_testharness.i_ariane.i_cva6.id_stage_i.decoder_i.instr.rtype.rd[11:7]
TOP.ariane_testharness.i_ariane.i_cva6.ex_stage_i.alu_i.result_o[63:0]
RISC-V register values can be found at: https://en.wikichip.org/wiki/risc-v/registers
Test 3 1+1=2
- reg(@1)+reg(@2)=reg(@E)
- Values: 1 + 1 = 2
- 895 ps :
rs1
operand - 897 ps : it should be
rs2
operand. However, as it’s equal tors1
, nothing is generated - 899 ps :
rd
operand
Test 4 3+7=0xA
- reg(@1)+reg(@2)=reg(@E)
- Values: 3 + 7 = 0xA
- 917 ps :
rs1
operand - 919 ps :
rs2
operand - 921 ps :
rd
operand