Exercise - Simulation flow: Difference between revisions

From Antalya
Jump to: navigation, search
(Created page with "{{VLSInavbar}} ==Overview== In this exercise, we will explore the practical application of Verilator, a leading open-source tool for hardware simulation. Verilator converts Verilog code into an executable binary. Our focus will be on simulating a digital design and testbench written in SystemVerilog using Verilator’s relatively new support for timing constructs. We will learn: * how to translate a SystemVerilog design into an executable binary using Veril...")
 
No edit summary
Line 23: Line 23:
indicate such an option.
indicate such an option.


Throughout the exercise you will be asked to enter certain commands using the command-line1.
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
  sh> command to be entered on the Linux command line
<div class="alert alert-success" role="alert">
'' '''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.''
</div>


=== Getting Started ===  
=== Getting Started ===  
Line 38: Line 42:


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.
=== [[Croc|Croc SoC]] ===
{{VLSIfigure|croc_draw.jpg|Simplified Croc diagram|1}}
[[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.
* <code>croc_pkg.sv</code>: contains the parameters and definitions of the SoC
* <code>croc_soc.sv</code>: wraps our parameteric SentryCore system framework
* <code>croc_chip.sv</code>: 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.
<div class="card bg-light mb-3">
  <h5 class="card-header">Student Task</h5>
  <div class="card-body">
* 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 <code>.bender/git/</code> checkouts.
* Identify the instance path and name of the <code>bootrom</code> used in Croc.
  </div>
</div>
Bender can be used to create a file-list (flist) defining all the projects RTL files and their corresponding include directories and defines.
<div class="card bg-light mb-3">
  <h5 class="card-header">Student Task</h5>
  <div class="card-body">
* Create the <code>croc.f</code> flist file required by [[Verilator]] in a later stage by calling:
sh > make sim-all
  </div>
</div>
== 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.
<div class="card bg-light mb-3">
  <h5 class="card-header">Student Task</h5>
  <div class="card-body">
* 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 <code>test/tb_croc_soc.sv</code>. To understand the testbench, consider the <code>`ifndef VERILATOR</code> blocks and ignore the <code>‘else</code> block. What is the testbench doing?
* 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.
  </div>
</div>
== Running a Simulation and Selecting Signals of Interest ==
<div class="card bg-light mb-3">
  <h5 class="card-header">Student Task</h5>
  <div class="card-body">
* Run the simulation now by typing:
sh > ./obj_dir/Vtb_croc_soc
* What does the simulation output?
* Change a few values in the <code>jtag_test.svh</code> 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.
  </div>
</div>
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).
<div class="card bg-light mb-3">
  <h5 class="card-header">Student Task</h5>
  <div class="card-body">
* 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 <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?
  </div>
</div>
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 <code>-trace-depth 1</code> 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.
<div class="card bg-light mb-3">
  <h5 class="card-header">Student Task</h5>
  <div class="card-body">
* 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?
  </div>
</div>




{{VLSIfigure|ex2_openroad_controls.png|Important elements of an OpenROAD window|1}}





Revision as of 06:21, 16 August 2024


Overview

In this exercise, we will explore the practical application of Verilator, a leading open-source tool for hardware simulation. Verilator converts Verilog code into an executable binary. Our focus will be on simulating a digital design and testbench written in SystemVerilog using Verilator’s relatively new support for timing constructs. We will learn:

  • how to translate a SystemVerilog design into an executable binary using Verilator.
  • how to specify signals to track in the wave and how to run a simulation.
  • how to debug the simulation results using wave forms.

About the style

We will use a number of different styles to identify different types of actions as shown below:

Student Task
Parts of the text that have a gray background, like the current paragraph, indicate steps required to complete the exercise.

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

Getting Started

Student Task
  • 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 draw.jpg

Figure 1: Simplified Croc diagram

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 SoC
  • croc_soc.sv: wraps our parameteric SentryCore system framework
  • croc_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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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?






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.