-
Notifications
You must be signed in to change notification settings - Fork 12
Verilator Testbench
For examining internal signals it can be useful to debug the core in a simulated environment. The following sections describe how to setup a system where gdb can be used to communicate with a simulated version of the core. The setup is similar to the one shown in this diagram. However, instead of the TaPaSCo Application
forwarding the signals to the AXI interface of a live device, they are sent to the Verilator simulated core.
- Building Verilator in place
git clone https://github.com/verilator/verilator.git
cd verilator
export VERILATOR_ROOT=`pwd`
autoconf
./configure
make -j$(nprocs)
cd ..
- Add the compiled Verilator binaries to your PATH
export PATH=`pwd`/verilator/bin:$PATH
- Check the selected C++ standard in
verilator/include/verilated.mk
:- to build the testbench at least the C++17 standard is required -> modify
CFG_CXXFLAGS_STD_NEWEST
accordingly if an older standard is set, i.e. change-std=gnu++14
to-std=gnu++17
- to build the testbench at least the C++17 standard is required -> modify
- Build & install Verilator
- Install OpenOCD & C Cap'n Proto
- Set CAPN_PATH: i.e.
export CAPN_PATH=`pwd`/c-capnproto
- Compile Testbench
cd tapasco-riscv/debugging/logdbg
-
cd scr1_sim
orcd cva6_sim
make preparebuild
make sim
- Start testbench:
./sim_build/scr1_top_tb_axi_dmi/Vscr1_top_tb_axi_dmi -o
or./sim_build/ariane_custom_tb_top/Variane_custom_tb_top -o
- Connect with OpenOCD to the created socket
/tmp/riscv-debug.sock
- Start debugging with i.e. gdb
- When done: stop the testbench with CTRL+C
Option | Description |
---|---|
-o | Start socket /tmp/riscv-debug.sock for patched OpenOCD
|
-t <trace.vcd>
|
Create a gtkwave compatible .vcd trace of the debug session |
-v <N>
|
Set the verbosity level. Currently unused. |
-s <N>
|
Set count of cycles to execute before recording a trace or starting the socket for OpenOCD. Should not be required. |
The used Makefiles for the simulation is quite versatile and should be "easy" to adapt for other cores too. However, there are some pitfalls and naming conventions.
- To adapt the Makefile for a new core, specify the following settings as required:
SRC
,SRC_FILES
,SRC_PREFIX
,ADD_SRCS
,INCLUDE_DIR
,DEFAULT_TOP_MODULE
andV_FLAGS
. - Change the make target
preparebuild
to get the sources for the new core
By default the following folder structure is assumed:
-
debugging/logdbg/
: root of all core simulations, i.e. for CVA6 and SCR1 -
debugging/logdbg/common
: folder containing code that is required by all simulation, i.e. the openocd interface -
debugging/logdbg/*/
: core simulation folder, where*
is i.e.cva6_sim
Conventions within a core simulation folder, in the following cva6_sim
is used as example:
-
cva6_sim/Makefile
: location of the makefile, may not be changed else relative paths to thecommon
folder break -
cva6_sim/sim_src
: directory that contains the C++ verilator testbenches/simulations for different top modules -
cva6_sim/sim_src/sim_*.cpp
: C++ code for the simulation of a top module named*
- i.e. the file
sim_ariane_custom_tb_top.cpp
corresponds to the SystemVerilog top moduleariane_custom_tb_top
- if a simulation needs dedicated C++ files that are not shared, then they can be placed inside in the subdirectory named as the module itself: i.e for the top module
ariane_custom_tb_top
the foldercva6_sim/sim_src/ariane_custom_tb_top
should be used
- i.e. the file
-
cva6_sim/sim_build
: root build directory for the simulations, may be changed viaV_DIR
and ensures out of tree builds. Creates a subfolder for each simulation top module: i.e.cva6_sim/sim_build/ariane_custom_tb_top/
-
the make targets are named accordingly:
make sim_ariane_custom_tb_top
to run the simulation for the top moduleariane_custom_tb_top
. If only one top module is present you can also set it asDEFAULT_TOP_MODULE
in the Makefile (i.e.DEFAULT_TOP_MODULE := ariane_custom_tb_top
) and just callmake sim
.
General interface:
-
clk
: input clock signal -
rst_n
: low active reset signal
Debug module interface:
-
dmi_req
: issue request signal, high active -
dmi_wr
: signal to indicate whether the request is a write (set to high) or a read (set to low) request -
dmi_addr
: address port, for both read & write requests -
dmi_wdata
: write data port
Generally the order in which the source files are listed should not matter. However, this changes as soon as the SystemVerilog Interfaces are used. Verilator requires the definition of the interfaces before they are used in other sources. Hence, files with interfaces should be listed first to avoid compilation problems.
If you want to reuse i.e. the verilator simulation file cva6_sim/sim_src/sim_ariane_custom_tb_top.cpp
for another top module top_x
(not necessarily the same core), then consider the following:
- Ensure that the naming conventions & top module ports are met
- change
#define TOP_MODULE Variane_custom_tb_top
to#define TOP_MODULE Vtop_x
- change
#include "Variane_custom_tb_top.h"
to#include "Vtop_x.h"
- change
#include "Variane_custom_tb_top__Syms.h"
to#include "Vtop_x__Syms.h"