Systemverilog Advanced Verification Using Uvm: Engineer Explorer Series
Systemverilog Advanced Verification Using Uvm: Engineer Explorer Series
Systemverilog Advanced Verification Using Uvm: Engineer Explorer Series
Using UVM
Engineer Explorer Series
Version 1.0
Lab Manual May 23, 2011
1990-2011 Cadence Design Systems, Inc. All rights reserved.
Printed in the United States of America.
Cadence Design Systems, Inc., 2655 Seely Avenue, San Jose, CA 95134, USA
Cadence Trademarks
Trademarks and service marks of Cadence Design Systems, Inc. (Cadence) contained in this document are attributed to Cadence with the appropriate symbol. For
queries regarding Cadence trademarks, contact the corporate legal department at the address above or call 800.862.4522.
Other Trademarks
Open SystemC, Open SystemC Initiative, OSCI, SystemC, and SystemC Initiative are trademarks or registered trademarks of Open SystemC Initiative, Inc. in the
United States and other countries and are used with permission.
All other trademarks are the property of their respective holders.
Confidentiality Notice
No part of this publication may be reproduced in whole or in part by any means (including photocopying or storage in an information storage/retrieval system) or
transmitted in any form or by any means without prior written permission from Cadence Design Systems, Inc. (Cadence).
Information in this document is subject to change without notice and does not represent a commitment on the part of Cadence. The information contained herein is
the proprietary and confidential information of Cadence or its licensors, and is supplied subject to, and may be used only by Cadence customers in accordance
with a written agreement between Cadence and its customers. Except as may be explicitly set forth in such agreement, Cadence does not make, and expressly
disclaims, any representations or warranties as to the completeness, accuracy or usefulness of the information contained in this document. Cadence does not
warrant that use of such information will not infringe any third party rights, nor does Cadence assume any liability for damages or costs of any kind that may
result from use of such information.
RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the Rights
in Technical Data and Computer Software clause at DFARS 252.227-7013.
UNPUBLISHED This document contains unpublished confidential information and is not to be disclosed or used except as authorized by written contract with
Cadence. Rights reserved under the copyright laws of the United States.
Lab 9C Further Work with TLM Connections (Optional) .................................. 40
Software Releases
These exercises and code examples have been tested on the following releases:
Project Overview
Throughout this training you will be developing a verification environment for a YAPP router
design. These exercises will guide you through building the verification components required to
verify the router design.
The project builds the environment from scratch so you will experience the full process
You will be building one UVC component. The others will be provided for you later in the project.
The packet router accepts data packets on a single input port, in_data, and routes the packets to
one of three output channels: channel0, channel1 or channel2. The input and output ports
have slightly different signal protocols. The router also has a host interface for programming
registers that are described in the next section.
data_0 [7:0]
in_suspend
registers data_1 [7:0]
reset data_vld_1
clock suspend_1
MAXPKT_SIZE
data_2 [7:0]
ROUTER EN
hdata [7:0] data_vld_2
haddr [7:0] suspend_2
Host HBUS I/F
hen
hwr_rd error
A packet is a sequence of bytes with the first byte containing a header, the next variable set of bytes
containing payload, and the last byte containing parity.
The header consists of a 2-bit address field and a 6-bit length field. The address field is used to
determine which output channel the packet should be routed to, with the address 3 being illegal. The
length field specifies the number of data bytes (payload).
A packet can have a minimum payload size of 1 byte and a maximum size of 63 bytes.
The parity should be a byte of even, bitwise parity, calculated over the header and payload bytes of
the packet.
7 6 5 4 3 2 1 0
payload[0] byte 1
payload[1]
Payload
payload[N-1] byte N
All input signals are active high and are to be driven on the falling edge of the clock. The
in_data_vld signal must be asserted on the same clock when the first byte of a packet (the
header byte), is driven onto the in_data bus. As the header byte contains the address, this tells the
router to which output channel the packet needs to be routed. Each subsequent byte of data needs to
be driven on the data bus with each new falling clock.
After the last payload byte has been driven, on the next falling clock, the in_data_vld signal
must be de-asserted, and the packet parity byte needs to be driven. The input data cannot change
while in_suspend signal is active (indicating FIFO full). The error signal asserts when a packet
with bad parity is detected, within 1 to 10 cycles.
Input Protocol
clock
delay
in_data_vld
in_data H D D D P H D D D P
in_suspend
All output signals are active high and are to be sampled on the falling edge of the clock. Each
output port is internally buffered by a FIFO of depth 16 and a width of 1 byte. The router asserts the
data_vld_x signal when valid data appears on the data_x output bus. The suspend_x input
signal must then be de-asserted on the falling clock edge in which data is read from the data_x
bus. As long the suspend_x signal remains inactive, the data_x bus drives a new valid packet
byte on each rising clock edge.
Output Protocol
clock
input in_data_vld
port
in_data H D D D P H D D D P
data_vld_0
channel0
output Response
port suspend_0
delay
data_0 H D D D P
The packet router contains two internal registers that hold configuration information. These registers
are accessed through the host interface port as follows:
The ROUTER_EN register provides control of disabling the routing feature. Enabling or disabling
the router during packet transmission will yield to unpredictable behavior.
7 6 5 4 3 2 1 0
Registers
MAXPKTSIZE 0
length address
ROUTER_EN 1
All input signals are active high and are to be driven on the falling edge of the clock. The host port
provides synchronous read/write access to program the router.
hwr_rd and hen must be 1. Data on hdata is then clocked on next rising clock edge in
to the register based on haddr decode.
hwr_rd must be 0 and hen must be 1. In the first clock cycle, haddr is sampled and
hdata is driven by the design under test (DUT) in the second clock cycle.
hen is then driver low after cycle 2 ends. This will cause the DUT to tri-state the hdata
bus.
HBUS Protocol
clock
hen
hwr_rd
haddr A A
hdata D D
The UVM training lab database includes the following directories and files:
uvm_training_xx/uvm Top-level directory for the training
labxx/ Lab directories where you will be working
hbus HBUS UVC and associated files
channel Output channel UVC and associated files
yapp YAPP input port UVC and associated files
router Router module UVC and associated files
router_rtl RTL Files for the YAPP Router DUT
test_install Simple example to check your UVM installation
uvm1.0xx UVM 1.0 library files
Accessing UVM
UVM 1.0 is supported by IUS versions IES 10.2s11 or later and IES 9.2s35 or later.
UVM 1.0 may not be provided with the simulator, depending on the release version. Your instructor
will tell you whether UVM is provided with your simulator release.
For simulator releases not including UVM, there are two options for accessing the UVM library:
For simulator releases which include UVM, the library can be accessed via the irun command line
option –uvm.
1. Set an environmental variable to the UVM install path which contains the src, docs
and examples directories: e.g. for the UVM library provided with the lab files
setenv UVMHOME <lab path>/uvm_fund_1.0/uvm/uvm10-cdns
.
8 SystemVerilog Advanced Verification Using UVM 5/22/11
Introduction
3. There are two options for compiling the test, depending if your simulator includes or does
not include a compiled copy of UVM 1.0. Make sure you use the right script for your
version of IUS. Ask your instructor if you are unsure.
4. Check the version number of the UVM library. You should see:
-------------------------------------------------------
UVM-1.0p2...
If you are using the UVM library provided with the lab files, you may wish to bookmark the
following file in a web browser to give convenient access to the UVM HTML documentation
$UVMHOME/docs/html/index.html
Additional Notes
File names, component names, and instance names are suggested for many of the labs. You are not
required to use these names but if you do not, you may need to edit code provided later in the week
to match your path and instance names.
These labs do not include step-by-step instructions, and do not tell you exactly what you need to
type.
Objective: To use the UVM class library to create the YAPP packet data item and
explore the automation provided.
1. Review the YAPP packet data specification on pages 1-4 and create your packet data
class (yapp_packet) in a file yapp_packet.sv. Name your class properties to
match the specification.
a. Declare the length, address and payload properties as rand. Do not use a
rand property for parity.
c. Declare an enumeration type, parity_t, outside the yapp_packet class, with the
values GOOD_PARITY and BAD_PARITY. Create a property parity_type as an
abstract control “knob” for controlling parity and declare this property as rand.
e. Add constraints for valid address and payload length (see packet description).
f. Add a constraint for parity_type with a distribution of 5:1 in favor of good parity
h. Create another rand control “knob” (packet_delay) of type int, to insert a delay
when transmitting a packet. Constrain the delay to be inside the range 0 to 20.
c. Using a loop, generate five random packets and use the UVM print() method to
display the results. Try printing using both the table printer and the tree printer
options.
d. Edit the run file run.f, in the tb directory, to use either the embedded or supplied
UVM library depending on your simulator version.
f. Compile and simulate your code using the following command (IUS9.2).
% irun –f run.f
Ask your trainer for the compilation command if using other tools or versions.
5. (Optional) Edit the top.sv file to explore the UVM built-in automation: copy(),
clone() and compare().
Objective: To create a simple UVM Verification Component (UVC, aka env) and
print the topology.
You will be creating a simple driver, sequencer, monitor, agent and env for the YAPP input port of
the router. You will focus on the transmit (TX) agent for this lab.
Note: Remember to add the UVM component constructor new() to each class definition.
Work in the lab02/sv directory. Use the training slides for suggestions on implementing these
components.
1. First - copy your yapp_packet.sv definition from lab01/sv into the lab02/sv
directory.
Also copy your run.f file from lab01/tb into the lab02/tb directory.
a. Use uvm_driver as the base class for the driver and use the
`uvm_component_utils macro. Using type parameters will make your UVC
easier to develop.
b. Add a run_phase() task. Use a forever loop to get and send packets, using the
seq_item_port prefix to access the communication methods
(get_next_item(), item_done() )..
c. Add a send_to_dut() task. For the moment, this task should just print the packet.
Use an `uvm_info macro with a verbosity of UVM_LOW. Use the following code in
the string portion of the macro (where pkt is the handle name for your YAPP
packet):
$sformatf("Packet is \n", pkt.sprint())
Note: sprint() is a sub-method of print(), which creates a print string, but does not
write it to the output. We use sprint() in a report macro, rather than print()
directly, to allow us to control the printing of the packet with verbosity settings.
a. Use uvm_sequencer as the base class for the sequencer. Remember to use a type
parameter if you used one for the driver.
a. Use uvm_monitor as the base class for the monitor and add the
`uvm_component_utils macro.
b. Add a simple run_phase() task which prints an uvm_info message that you are
in the monitor.
a. Use uvm_agent as the base class for the agent and use the
`uvm_component_utils macro.
c. The agent will contain an is_active flag to control whether the agent is active or
passive. Initialize this to active:
uvm_active_passive_enum is_active = UVM_ACTIVE;
b. Construct the agent in a build_phase() method for the env. Remember to call
super.build_phase(phase) first.
c. Implement a run_phase() task which prints the env (just call print()) ..
Include all of the files you created for this lab, together with the yapp_packet.sv
from Lab01, and the supplied file yapp_tx_seqs.sv, as follows:
`include "yapp_packet.sv"
`include "yapp_tx_monitor.sv"
`include "yapp_tx_sequencer.sv"
`include "yapp_tx_seqs.sv"
`include "yapp_tx_driver.sv"
`include "yapp_tx_agent.sv"
`include "yapp_env.sv"
This file will be included in the top-level test (top.sv).
Don't forget to include the supplied file yapp_tx_seqs.sv. This file contains a
sequence to help you verify your UVC. We will discuss sequences in detail later in the
class.
8. Work in lab02/tb directory. Create a simple test to check the UVC hierarchy as
follows:.
e. In a separate initial block, call a task run_test() without any arguments. This
built-in method will run a default test (details described later).
a. Look for the printed hierarchy. Does the hierarchy match your expectations?
b. Use the printed hierarchy to work out the full hierarchical pathname to your
sequencer (e.g. env.agent.sequencer) and write it below.
Sequencer pathname: _________________________________________________
c. Use your printed hierarchy to find the value of the yapp_tx_agent is_active
property.
What is the value of the is_active variable when you printed the hierarchy?
10. Your top-level module, top.sv, contains the following commented code:
uvm_config_wrapper::set(null, "<path>.run_phase",
"default_sequence",
yapp_5_packets::type_id::get());
This code sets the default sequence of the run_phase to the sequence
yapp_5_packets defined in the yapp_tx_seq_lib.sv file.
a. Un-comment this code and move it into your initial block containing
run_test(). Place the code in front of the run_test() call.
b. Edit the code to replace <path> with the hierarchical pathname to your sequencer
as recorded above.
c. Check your initial block looks like this (although your pathname may be different):
initial begin
uvm_config_wrapper::set(null, "env.agent.sequencer.run_phase",
"default_sequence",
yapp_5_packets::type_id::get());
run_test()
end
Note: In UVM 1.0, a UVC will not create any stimulus without an explicit sequence. In this
Lab you will use a pre-supplied sequence to allow your UVC to generate YAPP
packets. In UVM 1.0 we must use a configuration database set call to define the
sequence to be executed.
Both sequences and configurations are covered in later modules of this course.
12. Explore the verbosity options. Verbosity can be changed by adding the following option
to the irun command line or compile file:
+UVM_VERBOSITY=UVM_LOW
If you have use the correct syntax and verbosity for `uvm_info, you will see different
amounts of data printed when using different verbosity options. Try UVM_NONE and
UVM_FULL. You should also note that the testbench is not re-compiled when you change
verbosity.
13. Edit your run.f file to add the following compilation option:
+SVSEED=random
This sets a random value for the initial randomization seed of the simulation. Run the
simulation again and you should see different packet data created for each run. The
simulation reports the actual seed used for each simulation in the irun.log file.
Objective: To use a test class to verify the simple YAPP UVC and to explore the
built-in phases of uvm_component.
Create and work in lab03/sv and lab03/tb directory. For this lab, you will construct the YAPP
UVC in a test class instead of in the top module.
1. First – copy your files from lab02/ into lab03/ , e.g. from the uvm directory, type:
% cp –R lab02/* lab03/
2. In the lab03/sv/ directory, edit the yapp_env.sv file and delete the
run_phase() task containing the print() method call.
a. Delete the yapp_env handle and constructor, as the environment is now created in
the test class component.
8. (Optional) In the test library file yapp_test_lib.sv, create a second test named
test2.
Extend your test2 class from base_test. What is the minimum amount of code for
test2, given that we are inheriting from base_test?
Use your printed hierarchy to make sure the correct test is being executed.
Objective: To create verification components and data using factory methods, and
to implement test classes using configurations.
Create and work in lab04/sv and lab04/tb directories. For this lab, you will modify your
existing files to use factory methods, and explore the benefits of configurations.
Note: Remember to include the UVM component constructor new() in each new class
component definition.
1. First – copy your YAPP files from lab03/ into lab04/, e.g. from the uvm directory,
type:
% cp –R lab03/* lab04/sv
Note: You will be making many changes to files in this lab – so PLEASE copy the sv and
tb directories from lab03 to lab04 to keep a working copy available!
The first step is to use the factory methods to allow configuration and test control from above
without changing the sub-components.
2. Replace the new() constructor calls in the build_phase() methods by calls to the
factory method create(). You will need to modify the following files:
tb/test_lib.sv
sv/yapp_env.sv
sv/yapp_tx_agent.sv
3. Run your original test (base_test) to make sure the changes are working.
Create and work in lab05/sv and lab05/tb directories. For this lab, you will explore sequence
writing and the objection mechanism for coordinating simulation time.
Creating Sequences
1. First – copy your yapp files from lab04/ into lab05/, e.g. from the uvm directory,
type:
% cp –R lab04/* lab05/
Note: You will be making many changes to files in this lab – so PLEASE copy the sv and
tb directories from lab04 to lab05 to keep a working copy around!
2. In the lab05/sv director, edit the sequences file, yapp_tx_seqs.sv, to add the
following sequences.
For every sequence:
b. At the start of every sequence body(), add an `uvm_info call to print the
sequence name. Use a verbosity of UVM_LOW.
3. Create two new packet sequences with different constraints in the body.
yapp_012_seq – three packets with incrementing addresses
(do_with addr ==0; do_with addr==1; do_with addr==2)
yapp_1_seq – single packet to address 1
(do_with addr==1)
9. Create a new test in the file yapp_test_lib.sv from the lab05/tb directory:
e. Run the test and verify the results. Setting verbosity to UVM_FULL will allow you to
see which sequence is executed in the run_phase().
10. Create a new file in the lab05/tb directory called yapp_seq_lib.sv. Edit the file
as follows:
a. Create the library class with the name yapp_seq_lib and inherit from
uvm_sequence_library. Type parameterize the class for yapp_packet,
b. In the constructor, use separate add_sequence calls to add your sequences to the
library. For example:
add_sequence(yapp_repeat_addr_seq::get_type());
b. Add a handle for the yapp_seq_lib library and create the instance in the test
constructor.
13. Run a simulation using the GUI. The simulation will now be stopped on a constraint
violation and the constraints manager tool opened. This tool allows complex constraint
violations to be more easily debugged.
14. Fix your code to make the simulation run without constraint violations.
It is important that you fix the violation before moving on to the next lab.
Objective: To connect the YAPP UVC to the input port of the DUT.
Work in the lab06/sv and lab06/tb directories. For this lab, you will connect your YAPP
UVC to the RTL router Design Under Test (DUT) using interfaces, virtual interfaces, and
(optionally) a DUT wrapper.
The RTL model of the router DUT is located in the router_rtl directory.
With a few lines of extra code, the router DUT will operate correctly without connecting anything to
the HBUS interface signals or the channel outputs. This will allow you to test your YAPP UVC
(yapp_env) connection to the DUT without having to use the HBUS or channel UVCs.
2. Check the YAPP interface to the DUT, yapp_if.sv, which is supplied in the
lab6/sv directory.
Note that the interface has two input ports (clock, reset) and three DUT signals,
in_data, in_data_vld and in_suspend.
3. Connecting the YAPP interface via the configuration database will be easier if you
declare a typedef for the uvm_config_db with a yapp_if type parameter. This
declaration has to be visible to your monitor, driver, and top-level module.
Add the following declaration to yapp.svh, before the include statements:
typedef uvm_config_db#(virtual yapp_if) yapp_vif_config;
a. You will to need to use a collect_packets() method to capture the packet data.
The methods and some of the declarations for the monitor are provided in the file
monitor_example.sv. Check you understand the code.
Use the supplied code to update your monitor.
b. Make sure you update the get_and_drive() method to pull down packets from
the sequencer (see comments in code).
Adding a Testbench
c. Add a run_phase() method to base_test which sets a drain time for the
objection mechanism as follows:
phase.phase_done.set_drain_time(this, 200ns);
The drain time will allow enough time for the packets to pass through the router
design before the simulation ends.
a. Use set to write the YAPP interface instance into the configuration database (Hint:
Use your typedef from step 3). Use wildcards in the pathname to affect both
monitor and driver with a single statement. Remember for a top module set, the
context is null.
b. Add a `include for your YAPP UVC, YAPP sequence library, router testbench,
and renamed router test library files.
a. Run a test to verify that things are working correctly before connecting to the DUT.
Remember the interface file yapp_if.sv must be compiled on the command line
alongside top_no_dut.sv.
b. Examine the simulation output carefully to check that the monitor is capturing correct
packets according to the sequence being used.
A test class which uses a configuration set to define the sequence will make the
output easier to interpret.
a. Instantiate the yapp_router in the module and connect the ports to the yapp_if
interface signals via named mapping. For example:
.in_data(in0.indata),
c. Set the suspend_0, suspend_1 and suspend_2 router input signals to 1’b0
via assign statements or port mapping to allow packets to pass through the device.
11. Run a test to make sure the router is correctly connected.. Remember to compile the
yapp_router.v file from the router_rtl directory. You may need the following
irun timescale option to avoid timescale errors:
-timescale 1ns/100ps
12. Use SimVision to display signals from the yapp_router and the yapp_if. If you
have transaction recording in the monitor or driver, you can also view the transactions.
Ask your trainer for guidance.
A wrapper is a module which instantiates the router DUT. The wrapper has interface ports for the
YAPP, HBUS, and channel connections and maps the interface signals to the individual ports of the
router DUT. This makes instantiation and connection of the router DUT in the top module much
easier.
c. Add the yapp_if, the HBUS and three channel_if interface ports. The
channel_if.sv file can be found in the channel/sv directory.
The hbus_if.sv file can be found in the hbus/sv directory
e. Modify your top_dut.sv file to instantiate all five interfaces and the wrapper
instead of the router. Connect up the wrapper and simulate your design to check for
correct connection. Remember to drive the channel interface suspend signals to
1'b0.
Objective: To connect and configure the HBUS UVC and three output channel
UVCs with the input port UVC and the YAPP_router design.
For this lab, you will connect the HBUS and Channel UVCs to the router DUT.
The HBUS UVC is provided. This will need to be connected to the HBUS port.
The Channel UVC is also provided. This is almost identical to the YAPP input UVC, except the
Channel UVC must properly set/reset the in_suspend signal.
These are the directories we will be using for this and subsequent labs:
hbus/sv HBUS UVC files
channel/sv Channel UVC files
yapp/sv YAPP input UVC (your files from lab06)
router_rtl Router DUT
lab07/tb Your working directory for this lab
1. First – Your YAPP UVC is now complete enough to stand by itself. Copy your YAPP
files from lab06/sv into yapp/sv.
Note: PLEASE copy the sv directory from lab06 to yapp to keep a working copy
around!
2. We will still be working on the testbench, testclass, and top files. Copy these files from
lab06/tb into lab07/tb.
Note: PLEASE copy the tb directory from lab06 to lab07 to keep a working copy
around!
Work in the lab07/tb directory.
a. Add three handles of the Channel UVC (channel_env) and create the instances in
the build_phase() method using factory calls.
b. The Channel UVC has both transmit and receive agents. For the router testing, we
only need the Receive agent. Use a set_config_int method to set the has_tx
property of each Channel instance to 0.
a. Add a handle of the HBUS UVC (hbus_env) and create the instance in the
build_phase() method using a factory call.
b. The HBUS UVC has both master and slave agents. For the router testing, we only
need the Master agent. Use set_config_int methods to set the num_masters
property of the HBUS env to 1, and the num_slaves property to 0.
Test Library
c. (Optional) Now might be a good time to clean up the test library and remove the older
tests. Delete all the other test classes besides base_test and simple_test.
Top Module
6. Update your top-level module to add interface instantiations for the Channel and HBUS
interfaces if you do not already have these:
c. Add the include files for the Channel and HBUS UVCs. These can be found in the sv
directory of each UVC.
d. Set the HBUS and Channel UVC virtual interfaces to the correct interface (Hint: Use
typedef where possible – check the UVC header files for existing typedefs.).
Use wildcards in the pathname to update all UVC components with a single
statement. Remember for a top module set, the context is null.
Running a Test
b. Packets are passed correctly through the router and collected at the right channel.
b. Set the YAPP UVC to run your new YAPP sequence defined above.
10. (Optional) Run a simulation and check the results to see that the three channels are
properly addressed, that there is an error signal when parity is wrong, and that packets are
dropped if bigger than MAXPKTSIZE.
How many packets are dropped per channel?
Are there any packets dropped due to bad address (=3)?
For this lab, you will build and connect a virtual sequencer for the router, and create virtual
sequences to co-ordinate the activity of the three router UVCs.
1. We will be working on the testbench, testclass and top files from lab07. Copy these files
from lab07/tb into lab08/tb.
Note: You will be making many changes to files in this lab, so PLEASE copy the tb
directory from lab07 to lab08 to keep a working copy around!
Work in the lab08/tb directory.
b. Add the references for the HBUS and YAPP UVC sequencer classes. You could also
add a reference to the Channel sequencer class, but since there is only one sequence
for that sequencer, the handle can be omitted.
c. Using the sequences defined in the YAPP and HBUS UVC sequence libraries (and
optionally also the Channel), create a virtual sequence to:
Raise an objection on starting_phase.
Set the router to accept small packets (payload length < 21) and enable it.
Read the router MAXPKTSIZE register to make sure it has been correctly set.
Send six consecutive packets to address 0, 1, 2, cycling the address.
Set the router to accept large packets (payload length < 64).
Read the router MAXPKTSIZE register to make sure it has been correctly set.
Send a random sequence of six packets.
Drop the objection on starting_phase.
4. Modify the router_tb.sv testbench to instantiate, build, and connect the virtual
sequencer.
d. Do not set a default sequence for the YAPP or HBUS sequencer. Control is now
solely from the virtual sequencer.
6. Add include statements to your top module to reference the new files.
7. Run a test and check your results. If you open the irun.log file in an editor, you
should be able to track packets through the router and see the HBUS read and write
transactions.
If necessary, you can insert extra delays between the YAPP and HBUS sequences in the
virtual sequence to clearly separate transactions on the different interfaces.
For this lab, you will build and connect a scoreboard for the router, and create TLM analysis port
connections to hook up the scoreboard to the UVCs.
The router Module UVC is a complex design, so this lab has been deliberately broken down into
separate steps to build the UVC progressively.
First step is to implement the scoreboard component itself and connect it up to the YAPP and
Channel UVCs. For this part of the lab we assume all packets are sent to legal addresses with legal
payload length, i.e. the router does not drop any packets.
testbench
Channel0 port
UVC
Chan0 imp
Scoreboard Mon
YAPP
UVC
Chan1
1. We will be working with the testbench, testclass and top files from lab08. Copy these
files from lab08/tb into lab09a/tb. Work in the lab09a/tb directory.
2. A TLM analysis port has already been implemented in the Channel UVC monitors.
Check this to make sure you understand how it is written.
Note that the Channel UVC has a common monitor, channel_monitor.sv, for both
the TX and RX agents. The Channel monitor analysis port for collected YAPP packets is
named item_collected_port.
a. Define four analysis imp objects (for the YAPP and three Channels) using
`uvm_analysis_imp_decl macros and uvm_analysis_imp_* objects.
c. Use the YAPP write()implementation to clone the packet and then push the
packet to a queue. Hint: Use a queue for each address.
e. Add counters for the number of packets received, wrong packets (compare failed) and
matched packets (compare passed).
Objective: To create a module UVC for the router using the scoreboard
In reality, the scoreboard will only be one part of a larger router module UVC. For example the
router UVC may also contain reference models and coverage. All these components will be enclosed
in an env class.
In our example, we need to know the MAXPKTSIZE and ENABLE router settings so we know which
packets are dropped. We can implement this in a separate router reference model component.
The router reference connects to the YAPP and HBUS UVC analysis ports and selectively passes on
YAPP input packets to the scoreboard depending on the HBUS settings. An env wrapper will
instantiate both reference and scoreboard into a single router module UVC, as shown.
port
Chan0
imp
YAPP YAPP Scoreboard
Reference lid Chan1
HBUS
Chan2
1. We will be working with the files from lab09a. Copy these files from lab09a into
lab09b. Work in the lab09b directory
2. A TLM analysis port has already been implemented in the HBUS UVC monitor.
Note that the HBUS UVC has a common monitor, hbus_monitor.sv, for both the
master and slave agents. The HBUS monitor analysis port for collected
hbus_transaction's is named item_collected_port.
Check this to make sure you understand how it is written.
b. Define two analysis imp objects for the YAPP and HBUS monitor analysis ports,
using `uvm_analysis_imp_decl macros and uvm_analysis_imp_*
objects. (Copy declarations from your scoreboard.) These are for input data to the
reference.
c. Define one analysis port object for the valid YAPP packets. This is for output data to
the scoreboard.
d. Define variables to mirror the MAXPKTSIZE and ENABLE registers of the router and
update these in the HBUS write() implementation.
e. In your YAPP write() implementation, forward the YAPP packets onto the
scoreboard only if the packet is valid (router enabled; MAXPKTSIZE not exceeded;
address valid). Keep a separate count of invalid packets dropped due to size, enable
and address violations.
Note in a real-world example, we would have to explore race conditions when the
HBUS changes packet size during the processing of a packet. However there is a
REGMEM UVM feature specifically for handling and verifying registers in a design.
REGMEM is covered in the advanced UVM training.
b. Connect the “valid YAPP” analysis port of the reference model to the YAPP analysis
imp of the scoreboard model.
a. Replace the scoreboard declaration and build with the router module.
b. Modify the TLM connections for the YAPP and Channel analysis ports to allow for
the router_env layer.
6. Create a router.svh file containing includes for all the router module UVC files, and
reference this in your top module.
a. Use the same multichannel sequences to test your scoreboard and system monitor
implementation.
b. Check the simulation results are correct and the scoreboard and monitor report the
right number of packets.
7. The router module can now be used as a standalone UVC. Copy your router module UVC
files to the router directory.
Objective: To use export TLM connections with the router module UVC
A module UVC does not have such a clearly defined architecture as an interface UVC. With an
interface UVC, TLM analysis port objects are always defined in the monitor components. We
know where to look in order to find these. With a module UVC, it can be more difficult to find
declarations for the TLM analysis imp objects.
One technique is to extract all the TLM objects used in the module UVC to the top level
environment. These top-level objects are then connected internally to the correct sub-component.
Chan0
export
YAPP YAPP Scoreboard
Reference lid Chan1
HBUS
Chan2
1. Modify your router module UVC to present the external TLM connections as top-level
objects of the router module env. Note the following:
You will need to declare export objects in the Router Module environment for the
imp objects of the monitor and scoreboard.
You must connect all the export objects to imp objects in the Router Module
connect method.
The internal YAPP valid connection between monitor and scoreboard does not need
to be routed to the Router Module environment.
The testbench connections to the Router Module UVC will need to be modified.
To achieve this objective, use the yapp environment to create directed random tests.
1. Create a set of sequences that configures the device once, and sends packets with good
and bad parity and bad size.
Bad size is related to max_packet_size.
2. Change the max_packet_size on the fly and have the bad size sequence adjust
dynamically.
3. Send 20-30 packets to the device and disable the DUT by writing to the enable register.
5. Verify using the waveform viewer that the device is operating properly.
Writing a Test
9. From the run_phase() method of a test, call a series of write_hif and read_hif
to test this simplified interface.
Would this mechanism work for engineers who want to do directed testing or for
designers that want a simple test writer interface?
To achieve this objective, you need to create a coverage model for the input packet traffic to collect
the following info:
REQ1: Ensure all lengths of packets are sent into dut. Create buckets to detect MIN,
MAX, BABY, TEENY, GROWNUP packets.
REQ4 (optional): Ensure that packets of different lengths are transmitted to all addresses
with zero delay between transmissions.
Remember the syntax for a covergroup instantiated inside a class is different than one
instantiated in a module. In a class, a covergroup instance is created by calling new() on
the covergroup name. A separate covergroup variable is not required:
function new (...);
super.new(...);
covergroup_name = new();
endfunction: new;
3. Create a coverpoint for REQ1 to sample the length field and create bins to reflect the
following ranges:
MIN = 1
MAX = 63
BABY in [2..10]
TEENY in [11..40]
GROWNUP in [41..62]
4. Run a simulation.
You’ll have to modify your irun file to enable functional coverage collection inside the
simulator. Use the coverage options as described in the appendix and online tool
documents.
a. You can load this file in iccr by launching iccr -gui and loading the functional
coverage file from the file menu.
b. Select the Functional tab and see the distribution of packets observed.
6. Create a coverpoint for REQ2 and REQ3. Create a coverpoint inside the covergroup
created in step 1 for sampling address for REQ2 as follows:
a. Create a legal address bin to verify that all addresses were sampled.
If address 2 wasn’t generated, then it needs to be reflected in this coverpoint.
b. Create an illegal address bin that reflects how many packets were sent to address 3.
7. Create a cross inside the covergroup created in step 1 for coding REQ3 by creating a
cross with the appropriate fields.
How can you work around the limitation that we cannot have ignores in the cross?
a. Use a cross to model a transition, because the simulator currently doesn’t support
transitions on coverpoint.
Tip: You will have to keep track of the previous packet.
b. To implement back-to-back tracking you’ll have to make sure that the delay is
captured in the monitor.
Tip: You can use guard expression to control sampling of a cross.
10. Run multiple simulations with random svseed and analyze coverage results in ICCR.
Objective: Log in to Cadence Online Support (COS) and search for information
about a specific issue.
You can only complete this lab if you have access to the internet and a Cadence Online Support
account. If you do not, your instructor might be able to perform a demo of this lab for the class.
3. In the Support Home page, make sure the following options are selected:
All Document Types
All Products
5. From the search results, select any of the matches. This will open a window providing the
information in the match title..
Objective: Set preferences so you can improve search results and receive email
notification.
You can set product and other preferences for improved search results and email notification.
d. Select the document types your are interested in and the frequency of delivery.
e. Click Save.
b. Click Save.