Exercise - Simulation flow: Difference between revisions
No edit summary |
No edit summary |
||
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{VLSInavbar}} | {{VLSInavbar}} | ||
==Overview== | ==Overview== | ||
Verification is one of the most critical aspects of IC Design. Typical verification flows would compare an implementation of your circuit, either as HDL source code in SystemVerilog or a mapped gate-level netlist in Verilog (which we will cover in [[Exercise - Synthesis| a later exercise]] against a golden-model which represents the ''correct'' behavior of the circuit. The verification would take stimuli vectors (that represent inputs), apply them to the circuit under test and collect the corresponding outputs. These will be compared to the expected responses from the golden model, and any discrepancies will be noted in a report. | |||
While developing testbenches is not directly part of this lecture series, we will make use of existing verification setups extensively. Our example SoC [[Croc]] comes with a testbench that allows you to verify the basic functionality, and we will make use of this testbench to see if the changes we make to the SoC affect its base functionality. Of course, these testbenches will have to be adapted to cover the added functionality to the SoC. | |||
We will use a | In the initial stages, the design will be described in an RTL model in SystemVerilog. We will use [[Verilator]], a leading open-source tool for RTL simulation. | ||
There are some advanced use cases, that so far we were not able to map successfully to open source tools. For gate-level simulations that contain back-annotated delays that reflect the parasitic effects of individual connections due to the physical design will be simulated using a commercial tool Questa by Mentor/Siemens. | |||
===Goals of this exercise=== | |||
* Get practical experience in running the RTL simulation flow using [[Verilator]] | |||
* Learn the testbench template we will be using throughout the exercise | |||
* | |||
* Get familiar with post-layout simulation using back-annotation and understand the additional steps required as well as learn the additional constraints. | |||
* Experience tracing simulation errors to their sources | |||
* You should be able to re-run existing testbenches for given projects to ensure that any changes to the SoC did not introduce bugs. | |||
{{VLSItaskstyleinfo}} | |||
=== Getting Started === | === Getting Started === | ||
{{VLSItaskhead|1}} | |||
* Start by copying the example files into your directory by issuing the command | * Start by copying the example files into your directory by issuing the command | ||
sh > source /home/efcl_004fs24/ex03_simulation/install.sh | sh > source /home/efcl_004fs24/ex03_simulation/install.sh | ||
sh > cd ex03_simulation/croc-soc | sh > cd ex03_simulation/croc-soc | ||
{{VLSItaskfoot}} | |||
Starting from this exercise, we are using a small microcontroller design based around the Ibex RISC-V core (CV32E20). This simpler design still captures most of the complexity of Basilisk while cutting down tool runtime to an acceptable level. | Starting from this exercise, we are using a small microcontroller design based around the Ibex RISC-V core (CV32E20). This simpler design still captures most of the complexity of Basilisk while cutting down tool runtime to an acceptable level. | ||
Line 58: | Line 44: | ||
As you can see, the bulk of the code is currently not present and needs to be fetched using Bender. | As you can see, the bulk of the code is currently not present and needs to be fetched using Bender. | ||
{{VLSItaskhead|2}} | |||
* Prepare the RTL code by typing: | * Prepare the RTL code by typing: | ||
sh > make hw-all | sh > make hw-all | ||
Line 70: | Line 54: | ||
{{VLSItaskfoot}} | |||
Bender can be used to create a file-list (flist) defining all the projects RTL files and their corresponding include directories and defines. | Bender can be used to create a file-list (flist) defining all the projects RTL files and their corresponding include directories and defines. | ||
{{VLSItaskhead|3}} | |||
* Create the <code>croc.f</code> flist file required by [[Verilator]] in a later stage by calling: | * Create the <code>croc.f</code> flist file required by [[Verilator]] in a later stage by calling: | ||
sh > make sim-all | sh > make sim-all | ||
{{VLSItaskfoot}} | |||
== Verilog Compilation == | == Verilog Compilation == | ||
Line 87: | Line 67: | ||
Simulating a design with [[Verilator]] happens in three stages: the design is first translated to either SystemC or C++, it is then compiled to an executable binary on the host PC, and finally the binary is run. | Simulating a design with [[Verilator]] happens in three stages: the design is first translated to either SystemC or C++, it is then compiled to an executable binary on the host PC, and finally the binary is run. | ||
{{VLSItaskhead|4}} | |||
* Verilate and compile the testbench and the [[Croc]] SoC to a binary by running: | * Verilate and compile the testbench and the [[Croc]] SoC to a binary by running: | ||
sh > make sim-all | sh > make sim-all | ||
Line 98: | Line 76: | ||
* Now have a look at the <code>‘else</code> block. [[Verilator]] unfortunately does not understand our JTAG driver yet. For this exercise today, we have run the testbench using a commercial simulator and dumped the required JTGA stimuli and expected responses in a file. Verilator only applies these stimuli and checks the responses. | * Now have a look at the <code>‘else</code> block. [[Verilator]] unfortunately does not understand our JTAG driver yet. For this exercise today, we have run the testbench using a commercial simulator and dumped the required JTGA stimuli and expected responses in a file. Verilator only applies these stimuli and checks the responses. | ||
{{VLSItaskfoot}} | |||
== Running a Simulation and Selecting Signals of Interest == | == Running a Simulation and Selecting Signals of Interest == | ||
{{VLSItaskhead|5}} | |||
* Run the simulation now by typing: | * Run the simulation now by typing: | ||
sh > ./obj_dir/Vtb_croc_soc | sh > ./obj_dir/Vtb_croc_soc | ||
Line 118: | Line 93: | ||
{{VLSItaskfoot}} | |||
Without specifying anything else, [[Verilator]] only prints calls to stdout present in the RTL. This is great to get a pass/fail result from the simulation, but it is not sufficient to judge how or why a test is failing. | Without specifying anything else, [[Verilator]] only prints calls to stdout present in the RTL. This is great to get a pass/fail result from the simulation, but it is not sufficient to judge how or why a test is failing. | ||
If we want to understand why a circuit is misbehaving, we need to look at the waves (how the signals in our design behave over time). | If we want to understand why a circuit is misbehaving, we need to look at the waves (how the signals in our design behave over time). | ||
{{VLSItaskhead|6}} | |||
* We now have to enable tracing support in our Verilator model by adding the following arguments to the Verilator call. | * We now have to enable tracing support in our Verilator model by adding the following arguments to the Verilator call. | ||
--trace --trace-structs | --trace --trace-structs | ||
* Uncomment the tracing-related code in the testbench. This code specifies the trace file location, the module or signals to trace, and ensures the file is properly written at the end of the simulation. | * Uncomment the tracing-related code in the testbench. This code specifies the trace file location, the module or signals to trace, and ensures the file is properly written at the end of the simulation. | ||
Rerun the simulation. A file called <code>croc.vcd</code> should have appeared. How large is the file? Have a look at it’s content, can you understand how the information is stored? | * Rerun the simulation. A file called <code>croc.vcd</code> should have appeared. How large is the file? Have a look at it’s content, can you understand how the information is stored? | ||
{{VLSItaskfoot}} | |||
Simulation traces can be stored in human-readable value change dump (VCD) files. These files store the initial state of every simulation value traced and the time and state of their changes. Long simulations of large designs can lead to very large VCD files (order of 100 GiB). | Simulation traces can be stored in human-readable value change dump (VCD) files. These files store the initial state of every simulation value traced and the time and state of their changes. Long simulations of large designs can lead to very large VCD files (order of 100 GiB). | ||
Line 144: | Line 115: | ||
GTKWave is a hand tool to visualize many trace files, among them VCD files. We use it now to explore the simulation trace of the [[Croc]] SoC. | GTKWave is a hand tool to visualize many trace files, among them VCD files. We use it now to explore the simulation trace of the [[Croc]] SoC. | ||
{{VLSItaskhead|6}} | |||
* Open the VCD file using GTKWave | * Open the VCD file using GTKWave | ||
sh > gtkwave croc.vcd | sh > gtkwave croc.vcd | ||
Line 158: | Line 127: | ||
{{VLSItaskfoot}} | |||
Line 168: | Line 133: | ||
You are done with this Exercise. | You are done with this Exercise. | ||
Discuss your experience with assistants and collegues or continue to explore [[ | Discuss your experience with assistants and collegues or continue to explore [[Verilator]] and the provided design on your own. | ||
</div> | </div> | ||
{{VLSIfooter}} | {{VLSIfooter}} |
Latest revision as of 07:49, 18 October 2024
Overview
Verification is one of the most critical aspects of IC Design. Typical verification flows would compare an implementation of your circuit, either as HDL source code in SystemVerilog or a mapped gate-level netlist in Verilog (which we will cover in a later exercise against a golden-model which represents the correct behavior of the circuit. The verification would take stimuli vectors (that represent inputs), apply them to the circuit under test and collect the corresponding outputs. These will be compared to the expected responses from the golden model, and any discrepancies will be noted in a report.
While developing testbenches is not directly part of this lecture series, we will make use of existing verification setups extensively. Our example SoC Croc comes with a testbench that allows you to verify the basic functionality, and we will make use of this testbench to see if the changes we make to the SoC affect its base functionality. Of course, these testbenches will have to be adapted to cover the added functionality to the SoC.
In the initial stages, the design will be described in an RTL model in SystemVerilog. We will use Verilator, a leading open-source tool for RTL simulation.
There are some advanced use cases, that so far we were not able to map successfully to open source tools. For gate-level simulations that contain back-annotated delays that reflect the parasitic effects of individual connections due to the physical design will be simulated using a commercial tool Questa by Mentor/Siemens.
Goals of this exercise
- Get practical experience in running the RTL simulation flow using Verilator
- Learn the testbench template we will be using throughout the exercise
- Get familiar with post-layout simulation using back-annotation and understand the additional steps required as well as learn the additional constraints.
- Experience tracing simulation errors to their sources
- You should be able to re-run existing testbenches for given projects to ensure that any changes to the SoC did not introduce bugs.
About the style
We will use a number of different styles to identify different types of actions as shown below:
Student Task
Actions that require you to select a specific menu will be shown like the following: menu → sub-menu → sub-sub-menu
Whenever there is an option or a tab that can be found in the current view/menu we will use a BUTTON to indicate such an option.
Throughout the exercise you will be asked to enter certain commands using the command-line.
sh> command to be entered on the Linux command line
Note: there are many reasons for using a command-line. Some functionality can not not be accessed through GUI commands, and in some cases, using the command-line will be much faster. Most importantly, things you enter on the command-line can be converted into a script and executed repeatedly.
Getting Started
Student Task 1
- Start by copying the example files into your directory by issuing the command
sh > source /home/efcl_004fs24/ex03_simulation/install.sh sh > cd ex03_simulation/croc-soc
Starting from this exercise, we are using a small microcontroller design based around the Ibex RISC-V core (CV32E20). This simpler design still captures most of the complexity of Basilisk while cutting down tool runtime to an acceptable level.
Croc SoC
Croc SoC is designed as a streamlined, efficient microcontroller system based on the RISC-V architecture, utilizing a parameterizable SystemVerilog codebase. Unlike Basilisk, our Linux-capable AXI-4-based systems previously explored, Croc focuses on simplicity and reduced overhead by using the OBI (Open Bus Interface) protocol for on-chip interconnect. This choice of interconnect facilitates easier understanding and modification for educational purposes, while still supporting essential microcontroller functionalities.
The system includes two banks of SRAM, dividing instruction and data memory. This separation enhances performance by allowing simultaneous access to instructions and data, reducing bottlenecks. Croc SoC supports programming and on-chip debugging over a standard JTAG interface, enabled by the RISC-V debug module.
We heavily rely on a source and dependency management tool called Bender. The Croc SoC only consists of three simple RTL files.
croc_pkg.sv
: contains the parameters and definitions of the SoCcroc_soc.sv
: wraps our parameteric SentryCore system frameworkcroc_chip.sv
: defines the chip-level design including the ASIC pads.
As you can see, the bulk of the code is currently not present and needs to be fetched using Bender.
Student Task 2
- Prepare the RTL code by typing:
sh > make hw-all
- Have a look at the checked-out project, try to identify the instantiation of the SRAM banks. How many words does each SRAM hold? Hint: most of the source code is stored in
.bender/git/
checkouts.
- Identify the instance path and name of the
bootrom
used in Croc.
Bender can be used to create a file-list (flist) defining all the projects RTL files and their corresponding include directories and defines.
Student Task 3
- Create the
croc.f
flist file required by Verilator in a later stage by calling:
sh > make sim-all
Verilog Compilation
Simulating a design with Verilator happens in three stages: the design is first translated to either SystemC or C++, it is then compiled to an executable binary on the host PC, and finally the binary is run.
Student Task 4
- Verilate and compile the testbench and the Croc SoC to a binary by running:
sh > make sim-all sh > verilator-5.020 verilator -f croc.f --top tb_croc_soc -Wno-fatal --binary --timing --autoflush
- While the design is being translated, have a look at the testbench located in
test/tb_croc_soc.sv
. To understand the testbench, consider the`ifndef VERILATOR
blocks and ignore the‘else
block. What is the testbench doing?
- Now have a look at the
‘else
block. Verilator unfortunately does not understand our JTAG driver yet. For this exercise today, we have run the testbench using a commercial simulator and dumped the required JTGA stimuli and expected responses in a file. Verilator only applies these stimuli and checks the responses.
Running a Simulation and Selecting Signals of Interest
Student Task 5
- Run the simulation now by typing:
sh > ./obj_dir/Vtb_croc_soc
- What does the simulation output?
- Change a few values in the
jtag_test.svh
file after line 17 and rerun the simulation. Does the output change?
- Change the values back to their original state for the next part of the simulation to work.
Without specifying anything else, Verilator only prints calls to stdout present in the RTL. This is great to get a pass/fail result from the simulation, but it is not sufficient to judge how or why a test is failing.
If we want to understand why a circuit is misbehaving, we need to look at the waves (how the signals in our design behave over time).
Student Task 6
- We now have to enable tracing support in our Verilator model by adding the following arguments to the Verilator call.
--trace --trace-structs
- Uncomment the tracing-related code in the testbench. This code specifies the trace file location, the module or signals to trace, and ensures the file is properly written at the end of the simulation.
- Rerun the simulation. A file called
croc.vcd
should have appeared. How large is the file? Have a look at it’s content, can you understand how the information is stored?
Simulation traces can be stored in human-readable value change dump (VCD) files. These files store the initial state of every simulation value traced and the time and state of their changes. Long simulations of large designs can lead to very large VCD files (order of 100 GiB).
Verilator has multiple options to trade off VCD file space and simulation visibility. The -trace-depth 1
option for example can be reduced to limit the tracing to the top-level signals.
GTKWave
GTKWave is a hand tool to visualize many trace files, among them VCD files. We use it now to explore the simulation trace of the Croc SoC.
Student Task 6
- Open the VCD file using GTKWave
sh > gtkwave croc.vcd
- Locate the instance of the bootrom and add its signals to the wave view.
- At which time is the bootrom accessed?
- Which address is being read? Which value is returned?
You are done with this Exercise.
Discuss your experience with assistants and collegues or continue to explore Verilator and the provided design on your own.
The VLSI pages are part of the open source VLSI design course offered by the Integrated Systems Laboratory of ETH Zürich, by Luca Benini and Frank K. Gürkaynak. See full list of contributors.