SystemVerilogVerificationUVM1 1LabGuide

Download as pdf or txt
Download as pdf or txt
You are on page 1of 102

CUSTOMER EDUCATI ON SERVI CES

SystemVerilog Verification
UVM 1.1 Workshop
Lab Guide
40-I-054-SLG-003 2011.12

Synopsys Customer Education Services


700 East Middlefield Road
Mountain View, California 94043

Workshop Registration: 1-800-793-3448

www.synopsys.com
Copyright Notice and Proprietary Information
Copyright © 2012 Synopsys, Inc. All rights reserved. This software and documentation contain confidential and
proprietary information that is the property of Synopsys, Inc. The software and documentation are furnished under a
license agreement and may be used or copied only in accordance with the terms of the license agreement. No part of the
software and documentation may be reproduced, transmitted, or translated, in any form or by any means, electronic,
mechanical, manual, optical, or otherwise, without prior written permission of Synopsys, Inc., or as expressly provided by
the license agreement.

Destination Control Statement


All technical data contained in this publication is subject to the export control laws of the United States of America.
Disclosure to nationals of other countries contrary to United States law is prohibited. It is the reader’s responsibility to
determine the applicable regulations and to comply with them.

Disclaimer
SYNOPSYS, INC., AND ITS LICENSORS MAKE NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

Registered Trademarks (®)


Synopsys, AMPS, Cadabra, CATS, CRITIC, CSim, Design Compiler, DesignPower, DesignWare, EPIC, Formality, HSIM,
HSPICE, iN-Phase, in-Sync, Leda, MAST, ModelTools, NanoSim, OpenVera, PathMill, Photolynx, Physical Compiler,
PrimeTime, SiVL, SNUG, SolvNet, System Compiler, TetraMAX, VCS, Vera, and YIELDirector are registered trademarks
of Synopsys, Inc.

Trademarks (™)
AFGen, Apollo, Astro, Astro-Rail, Astro-Xtalk, Aurora, AvanWaves, Columbia,Columbia-CE, Cosmos, CosmosEnterprise,
CosmosLE, CosmosScope, CosmosSE, DC Expert, DC Professional, DC Ultra, Design Analyzer, Design Vision,
DesignerHDL, Direct Silicon Access, Discovery, Encore, Galaxy, HANEX, HDL Compiler, Hercules, Hierarchical
Optimization Technology, HSIMplus, HSPICE-Link, iN-Tandem, i-Virtual Stepper, Jupiter, Jupiter-DP, JupiterXT,
JupiterXT-ASIC, Liberty, Libra-Passport,Library Compiler, Magellan, Mars, Mars-Rail, Milkyway, ModelSource, Module
Compiler, Planet, Planet-PL, Polaris, Power Compiler, Raphael, Raphael-NES,Saturn, Scirocco, Scirocco-i, StarRC, Star-
SimXT, Taurus, TSUPREM-4, VCS Express, VCSi, VHDL Compiler, VirSim, and VMC are trademarks of Synopsys, Inc.

Service Marks (SM)


MAP-in, SVP Cafe, and TAP-in are service marks of Synopsys, Inc.

SystemC is a trademark of the Open SystemC Initiative and is used under license. ARM.and AM BA are registered
trademarks of ARM Limited. Saber is a registered tradem ark of SabreMark Limited Partnership and is used under license.
All other product or company names may be trademarks of their respective owners.

Document Order Number: 40-I-054-SLG-003


SystemVerilog Verification UVM 1.1 Lab Guide

Synopsys Customer Education Services


UVM Environment

After completing this lab, you should be able to:


• Create a simple UVM test environment
• Embed report messages
• Compile the test environment
• Run simulation and observe results
• Add data, sequencer and driver classes to the
environment
• Compile and simulate the environment to observe
behavior

Lab Duration
45 minutes

UVM Verification Environment Lab 1-1


Synopsys 40-I-054-LG-003
UVM consists of a set of coding guidelines with a set of base classes and macros.
The set of base classes and macros assist you in developing testbenches that are
consistent in look and feel. The set of coding guidelines enable you to develop
testbench components which are robust and highly re-usable. As a result, you will
spend less time modifying, maintaining the verification infrastructure and more time
verifying your designs.

In this first lab, you will start the process of build a UVM verification environment
using the UVM base classes and macros following the UVM coding guidelines:

program automatic test;


// class definitions
initial begin
run__test () ;
end
endprogram

Figure 1. Lab 1 Testbench Architecture


Lab

Lab Overview

After you log in, you will see three directories: labs, solutions and rtl.

Figure 2. Lab Directory Structure

For each individual lab, you will work in the specified lab directory. Should you
have a question during the lab and want to know what the potential solution is, you
can reference the sample solution provided in the solutions directory.

The work flow for this lab is illustrated as follows:

Figure 3. Lab 1 Flow Diagram

UVM Verification-Environment Lab 1-3


SystemVerilog UVM Workshop
Building a UVM Testbench

Task 1. Create a Simple Test

For this first task, you will create a simple test and a program block to execute this
simple test. Use the lecture material as your reference.

1. Go into labl directory:


> cd labs/labl

2. Open the existing test_collection.sv file with an editor, and look for
the comment that start with: “/ / Lab 1: task 1, step 2”.
• Enter the class declaration as described in the comment
3. Look for the “// Lab 1: task 1. Step 3” comment.
• Register the class with the factory
4. Look for “// Lab 1: task 1. Step 4” comment.
• Enter the constructor code as described in the comments
Note: You will be asked to enter the following statement at the beginning
of each method. This is to help you during debugging. With this
statement embedded in every method, you can easily see how
things are being executed sequentially by setting the report
verbosity to UVM_HIGH. Within the statement, %mis a format
specifier that prints the current hierarchical path.

' u v m _ in f o ( " T R A C E " , $ s f o r m a t f {" %m") , U V M _ H IG H ) ;

5. Near the bottom of the file, look for “// Lab 1: task 1, step 5”
comment in start_of_simulation_phase () method.
• Enter the helpful debugging code as described in the comments
6. Save and close the file.
7. Open a new file, call it t e s t .sv. Enter the following test code:

import uvm_pkg::*;

initial begin
$timeformat(-9, 1, "ns", 10);
run_test();
end

8. Save and close the file


Lab 1-4 UVM Verification Environment
SystemVerilog UVM Workshop
9. Compile and simulate this simple UVM testbench:
> vcs -sverilog -ntb_opts u v m - 1 .1 t e s t .sv
> simv +UVM_TESTNAME=test_base

At the end of simulation, you should see something like the following:

Note: The compilation switch to enable UVM is -ntb_opts. There are


several flavors of UVM switches: uvm, uvm -1.0, uvm -1.1 (in the
future there will be uvm -1.2, uvm-2 .0 etc.). Be careful and
make sure that you are using the proper version for your project.

Task 2. Create a Simple Environment_______________

In this task, you will build a simple environment that includes sequence_item
(packet), sequence (packet_sequence), sequencer (sequencer), driver
(driver) agent (input_agent) and environment (router_env). With very
little effort, you can start to generate stimulus and see interactions between the
sequencer and the driver.

1. Open the packet.sv file with an editor, and look for the comments that
start with: “/ / Lab 1” and enter the following: (If necessary, look in the
slides for the exact syntax)
• The class declaration
• The sa, da, and payload properties packet

• And, the constructor


Note: There is a major difference between data class constructor and
component class constructor. In the data class constructor, there is
no parent component handle in the argument.

To create the supporting methods (print, copy, compare, etc.) for properties in
a UVM class, you should use ' uvm_f ield_* macros embedded within the
' uvm__ob ject_utils_begin/end macros (to be covered in the next
unit). These are already done in the file for you, along with a constraint.
2. Save and close the file.

UVM Verification Environment Lab 1-5


SystemVerilog UVM Workshop
Lab

3. Open the packet_sequence .sv file with an editor, and look for the
comments that start with: “/ / Lab 1”.Enter the following:
• The class declaration packet_sequence
• And the body() method (see comments) ' packet
4. Save and close the file.
5. Open the driver.sv file with an editor, and look for the comments that
start with: “// Lab 1”.Enter the following: .... __.. ........... t
,
• The class declaration 5 i
i
• Print the request (req) sequence item {
in the run_phase () method ..-™, ........................

For now, the driver just gets a packet (req) from the sequencer via the
built-in seq_item_port and displays the content on the console. In future
labs, more functionality will be added.
6. Save and close the file.
7. Open the input_agent . sv file with an editor, and look for the comments
that start with: “/ / Lab 1”. Enter the following:
• Use typedef to create a packet_sequencer class for packet
• Declare an input_agent class
• Create an instance of packet_sequencer and driver
• Create these in the build phase
• Connect the driver’s and sequencer’s TLM ports in the connect phase

Lab 1-6 UVM Verification Environment


SystemVerilog UVM Workshop
9. Open the router_env.sv file with an editor, and look for the comments
that start with: “/ / Lab 1”.Enter the following:
• Declare a router_env class
• Create an instance of input_agent
• Construct it in the build phase
• Set the agent’s sequencer to execute packet_sequence as the
default sequence in the sequencer's main phase
router env
router_agent

10. Save and close the file.


11. Open the test_collection .sv file with an editor and look for the
comments that start with with: “/ / Lab 1, task 2, step 11”.
Enter the following:
• Include the environment file
• Create an instance of the environment
• Construct the environment object
• Print the test topology
router env
12. Save and close the file.

UVM Verification Environment Lab 1-7


SystemVerilog UVM Workshop
Lab

Task 3. Run Test____________

1. Use make to compile and run simulation.


> make
You should see that ten packets were printed.
2. Take a look at the simulation result:
> less simv.log

You should see something like the following:

UVM_INFO @ 0: reporter [RNTST] Running test test_base...


UVMJNFO @ 0: reporter [UVMTOP] UVM testbench topology:

Name Size ffliliSMK;

uvm_test_top test__base IIBIII1S1 0460


env router_env l;l!J|lllll @46 9
input_agent llllll:!:!!;il ll ll f i
driver |5i|i|l||||| @599
rsp_port uvm__ana lysis _„port llllllfi 0614
sgr_pull__port uvm_seq_item_pull_port lllllllll 0606
seqr uvm_sequencer liitlllllll @490
rsp„_export uvm__analysis__export liHllll 049 7
seq„item„export uvm„ seq„i tem_pu 1l__imp j!ll!!l!!!l|ll @591
arbitration_queue array 0 1!1I!I!I!I!||
lock__queue array 0 liilillljllllli:
nirm_last_reqs integral 32 1dl
num_last_rsps integral 32 fdl

Test topology printed in table format.


You can display the content in tree format with:
#### Factory Configuration (*) uvm_top.print_topology(uvm_default_tree_printer);
TSIo instance or type overrides are registered with this factory

All types registered with the factory: 42 total


{types without type names will not be printed)

Type Name
factory.print() result.
All class type registered in the factory
driver 4 —
via thevuvm_component_utils() and the
input__agent
'uvm_obj ect_utils() macro are printed.
packet
packet__sequence
router_env
If you name your tests properly, you
test__base
can easily identify all of your tests here.

Lab 1-8 UVM Verification Environment


SystemVerilog UVM Workshop
Lab

Task 4. Run Testbench with Different Log Verbosity

In the previous task, you may have noticed that none of the embedded uvm_info
messages were printed. This is because the default display verbosity of the UVM
reporting mechanism filters out all levels below UVM_MEDIUM. In the
router_env, each of the ' uvm._i.nfo message were set to the verbosity level
UVM_HIGH. The verbosity being filtered out are: UVM_HIGH, UVM_FULL and
UVM_DEBUG. The recommended way to treat these verbosity levels is to use:

• UVM_HIGH for tracing messages


• UVM_FULL for general debugging messages
• UVM_DEBUG for more detailed debugging messages
1. Turn on the trace messages:
> make verbosity=UVM_HIGH

You should now see the embedded tracing messages.


2. Turn on debugging messages at the most verbose level:
> make verbosity=UVM_DEBUG

3. If you have free time, look through the source files in


$VCS_HOME / etc/uvm. You will find that reading through each of the
source code will give you a lot of insights into how each class and macro
works.

You are done with Lab 1!

UVM Verification Environment Lab 1-9


SystemVerilog UVM Workshop
Lab 1 A nsw ers / Solutions

Answers / Solutions
test.sv Solution:

program automatic test;


import uvm__pkg ::* ;
"include "test_collection .sv"
initial begin
$timetormat(-9,'1, "ns", 10);
run_test () ;
end
endprogram

test__collection.sv Solution:
class test_base extends uvm_test:;
suvm__component„utils (test_base) ;
router__env env; :
function new(string .name, uvm_component parent);
super .new (name, parent ):;
'uvm_inf o ("TRACE1’, $sf ormatf ("%m" ), UVM__HIGH) ;
endfunction: new
virtual function void build__phase (uvm__phase phase) ;
super .build__phase (phase);
'uvm__info ("TRACE" , $sf ormatf ("%im" ), UVM_HIGH) ;
env = router_env::type_id ::create ("env" , this) ;
endf unction: build__phase
virtual function void start„of__simulat ion__phase (uvm__phase phase) ;
super .start__of_simulation_phase (phase);
'uvm_inf o ("TRACE" , $sf ormatf ("%m" ), UVM_HIGH) ;
uvm_top .print___topology () ;
factory.print();
endfunction: start__of„simulation__phase
endclass: test_base
d r iv e r . sv Solution:

class driver extends uvm__driver # (packet);


suvm__component__utils (driver)
function new (string name, uvm_component parent);
super.new(name, parent);
'uvm_info ("TRACE" , $sformatf ("%m'!) , UVMJ1IGH) ;
endfunction: new
virtual task run_phase(uvm_phase phase);
'uvm__info( "TRACE", $sf ormatf ("%m!f), UVMJiIGH) ;
forever begin
seq__.item__port.get_next__item (req) ;
req.print();
seq__item_port.item_done () ;
end
endtask: runjphase
endclass: driver

Lab 1-10 UVM Verification Environment


SystemVerilog UVM Workshop
Answers / Solutions Lab

packet,. sv Solution:

class packet-/extends uvm_sequenceJtem; :


rand bit [3:0] sa, da;
rand bit [7:0] payload[$]:;■■
suvm_obj.ect__utils_jDeg.in (packet)
Nuvm__field__int (sa, UVM__ALL_ON + UVMJNf0COMPARE)
'uvm_field_int (da, UVM_ALL__ON)
"uvm_f ield_queue__int (payload, UVM__ALL__ON)
Nuvm_ob ject„„utils„_end
constraint valid {
payload.size inside {[1:10] };
' }
function new(string name = "packet");
super.new (name) ;:::
suvm__info ("TRACE" , $sf ormatf ("%m") , UVMJKIGH) ;
endfunction:/new
endclass: packet
input___agent:. sv Solution:

typedef uvm_sequencer # (packet) packet_sequencer;

class input_agent extends uvm__agent;


packet.__sequencer seqr;
driver drv;

'uvm__component_utils (input_agent)

function n ew(string name, uvm_component parent);


super,new(name, parent);
'uvm_inf o ("TRACE11, $sf ormatf ("%m" ), UVM_HIGH) ;
endfunction: new

virtual function void build„phase (uvm__phase phase) ;


super .build_phase (phase) ;
suvm__inf o ("TRACE11, $sformatf (ff%m" ), UVM_HIGH) ;
seqr = packet_sequencer ::type__id ::create ("seqr ", this) ;
drv = driver: :type__id: :create ("drv" , this) ;
endfunction: build„phase

virtual function void connect_phase(uvm_phase phase);


super.connect_phase(phase);
suvm__inf o ("TRACE" , $sf ormatf ("%m" ), UVM__HIGH) ;
drv.seq__item_port.connect (seqr .seq_item_export);
endfunction: connect_phase

endclass: input_agent

UVM Verification Environment Lab 1-11


SystemVerilog UVM Workshop
Answers / Solutions

router_env. sv Solution:

class ro:ut;e:
r_env extends uvnrwenv; :.
input__age:nt ,i_agent:';

'uvm_component__utils (router___env)

function n ew(string name, uvm_component parent);


super.new(name, parent);
vuvm__info("TRACE"r $sformatf("%m" ) , UVM_HIGH) ;
endfunction: new

virtual function void build__phase (uvm__phase phase) ;


super .bulld__phase (phase);
suvm_info ("TRACE", $sformatf ("%m" ) , UVM__HIGH) ;
i__agent =. input_agent::type_id::create (Ifi_agent % this) ;
uvirr_config_db # (uvm_object_wrapper) :.;set (this , "i_agent .seqr .main__phase,rf
"def ault_sequence ", packet__sequence ::get__type () );
endfunction: build__phase

endclass : ^roiiter__env
packet__s@qu©nce. sv Solution:

class packet__sequence extends uvm_sequence # (packet);


Nuvm_object__ut.ils (packet_sequence)

function new(string name = "packet_sequence");


super.new(name);
'uvm„info ("TRACE11, $sformatf ("%m" ), UVM_HIGH) ;
endfunction: new

task body();
Nuvm_info("TRACE", $sformatf("%m"), UVM_HIGH) ;
if (starting_phase != null)
starting__phase .raise_objection (this) ;
repeat(1 0 ) begin
'uvm_do(req);
end
if (start ing__jphase != null)
starting__phase .drop__object ion (this);
endtask: body

endclass: packet_sequence

Lab 1-12 UVM Verification Environment


SystemVerilog UVM Workshop
Modify Constraints in
Test

After completing this lab, you should be able to:


• Modify the existing packet constraint by creating an
extension of the class
• Create a test to use this modified packet class
• Compile, simulate and check results

Lab Duration
15 minutes

Set Constraint in Test Lab 2-1


Synopsys 40-I-054-LG-003
Getting Started

In Lab I, you built a UVM testbench environment class with a packet class that
fully randomized the source address and the destination address. In this lab, you
will create a modified packet class to set specific set of address of interest and
develop a test to execute it.

Constrainable Many runs,


Random Stimulus different seeds |
Generation
Directed
Add/Change (i Testcase Functional
constraints I _________ Coverage
—«
/
n _____ y
Minimal e__ X Identify ||
Modifications /I holes |

program automatic test;


// class definitions
initial begin
run_test();
end
endprogram

b u ild
Environment class

connect

end of elaboration Agent

s t a r t o f /.simulation

run

extract
Scoreboard Monitor
check
TBD 1 1 1 !!

. . 'f in a l v

DUT

Figure 1. Lab 2 Testbench Architecture


Lab 2-2 Set Constraint in Test
SystemVerilog UVM Workshop
Lab Overview

The work flow for this lab is illustrated as follows:

Figure 2. Lab 2 Flow Diagram

Set Constraint in Test Lab 2-3


SystemVerilog UVM Workshop
Lab 2

Implement Constrained Test

What does it mean to write a test? Often time, it just means to change constraints
within stimulus classes. In this lab, you will create a directed test to exercise only
source address 3 port of the DUT.

Task 1. Go into Iab2 Working Directory____________

1. CD into the lab2 directory


> cd ../Iab2

Task 2. Create a Modified Packet Class_____________

In this task, create a simple contraint which constrains the destination address to 3.

1. Open the packet_da_3 .sv file in an editor


2. Look for the ToDo comments and write a constraint to set destination address
(da) to 3
3. Save and close the file

Task 3. Create a Test to Use the Modified Packet Class

1. Open test_collection.sv file in an editor


2. Bring in the new packet definition by including the packet_da_3 . sv file
3. Inside the test_da_3_inst class, use instance override to configure the
sequence to use packet_da_3 instead of packet definition
4. Save and close the file

Task 4. Compile And Simulate with New Test_______

1. Compile and simulate the testbench


> make test=test_da_3_inst
2. Check to see that the destination address for thes packets are all 3
3. Check to see that the Factory Configuration report displays the Instance
Overrides correctly
4. Constrast it with running the fully randomized test:
> make

Lab 2-4 Set Constraint in Test


SystemVerilog UVM Workshop
Lab

The goal of testbench methodology is to simplify development of individual tests.


Can you see that writing new tests are easy to do once the environment is set up
properly?

Constrainable Many runs,


Random Stimulus different seeds
Generation

Task 5. Optional: Configure with Type Override______

If you have time, try writing one more test to override all instances of packet with
packet_da_3. Call this test test_da_3_type. Compile and simulation to
make sure it works properly.

Congratuations, you have completed Lab 2!

Set Constraint in Test Lab 2-5


SystemVerilog UVM Workshop
Lab 2 A n sw ers / Solutions

A n s w e r s / S o lu t io n s

test_collection. sv Solution:
class test_Joase extends uvm_test;

Ninclude "packet_da_3 .sv"

class test__da_3__inst extends test_base;


suvm__component___ut ils (test_da__3_inst)
function new (string name, uvm__component parent) ;:
super.new(name, parent);
vuvm__info ("TRACE", $sf ormatf ("%m") , UVM_HIGH) ;
;endfunction

virtual function void build^hase (uvnr__phase phase) ; V


super.build_phase(phase);
Nuvm__info ("TRACE", $sformatf ("%m" ), UVMJIIGH) ;
set_inst_override_by__type ("env.i__agent * .seqr .*",
packet::get_type () , packet_da_3 ::get_type () ) ;
endfunction
endclass

class test_da_3_type extends test__base;


suvm_component__utils (test_da_3_type)
function new(string name, uvm_component parent);
super.new(name, parent);
'uvm__info ("TRACE", $sformatf (11%m" ), UVM_HIGH) ;
endfunction

virtual function void build_phase(uvm__phase phase);


super.build„phase(phase);
suvm„info("TRACE", $sformatf ("%m" ), UVMJIGH) ;
se t_type_over ride_by_type (packet::get_type () , packet_da_3 ::get_type () )
endfunction
endclass

packet_da_3.sv Solution:

class packet__da.__3 extends packet;


vuvm_ob ject_uti 1s (packet_da_3)

constraint da___3 {
da == 3;

function new (string name = "packet_da_3ff) ;


super.new(name);
"uvm__inf o ("TRACE", $sf ormatf ("%m" ), UVMLHIGH) ;
endfunction
endclass

Lab 2-6 Set Constraint in Test


SystemVerilog UVM Workshop
Configure Sequences

After completing this lab, you should be able to:


• Add configuration fields to packet_sequence
• Develop a test to set the packet_sequence’s
configuration fields.
• Create a reset sequence
• Develop a test to execute the reset sequence in the reset
phase and packet_sequence in the main phase
• Compile and simulate

Lab Duration
30 minutes

Configure Sequences Lab 3-1


Synopsys 40-I-054-LG-003
develop a test to constrain the packet’s destination address. In this lab, you will add
configuration fields to packet_sequence to bring even more flexibility into the
testbench.

Many runs,

Add/Change ^ T e s t c a s e Functional
constraints I

Modifications / 1 holes

p ro g ra m automatic test;
// class definitions
initial begin
runjtest ();
end
endprogram

Environment class

Agent Agent

Monitor Scoreboard Monitor

TBD TBD

DUT

•.... ————

Figure 1. Lab 3 T estbench Architecture


Lab 3-2 Configure Sequences
SystemVerilog UVM Workshop
Lab Overview

The work flow for this lab is illustrated as follows:

Figure 2. Lab 3 Flow Diagram

Configure Sequences Lab 3-


SystemVerilog UVM Workshop
,ab 3

Implement Configurable Sequences

Modifying stimulus constraints through OOP inheritance is useful. But, by itself,


can be limited in capability. In this lab, you will add configuration field to
packet_sequence to bring more flexibility into the test development.

Task 1. Go into Iab3 Working Directory____________

1. CD into the lab3 directory


> cd ../lab3

Task 2. Add Configuration Fields to Packet Sequence

Sequences are where stimulus are created. The ability to manage what happens
within sequences is important in the development of individual tests. In this task,
you will add configuration fields to constrain the source address and the destination
address in each packet object. You will also add a field to control how many
packets objects to generate per execution of the sequence’s body () task.

1. Open the packet_sequence .sv file in an editor


2. Create the following fields:
• int item_count = 10; //number ofitems to create
• in t p o r t_ id = - 1 ; / / input port (source address)
•bit [15:0] da_enable = '1; //destination address enable
• int valid_da[$]; //used to constrain da
3. In body () task do the following:
• Modify the repeat () statement to repeat for item_count number of
times
• Change ' uvm_do () statement to constrain packet's sa and da
(see comments in file for explanation)
4. Save and close the file

Task 3. Compile and Simulate___________________


1. Compile and simulate the testbench to verify that simulation still runs the
same with default configurations
> make

Lab 3-4 Configure Sequences


SystemVerilog UVM Workshop
Task 4. Configure the Sequence in Test

In lab 2, you used OOP inheritance to set the packet’s da to 3. With the updated
packet_sequence, you can do the same thing by setting the sequence configuration.

1. Open test_collection.sv file in an editor


2. Create a test class extended from test_base, call it test_da_3_seq
3. Add the required uvm_component_utils macro and the constructor method
4. Create a build phase to:
• Set the packet_sequence’s da_enable to 16' h0008
• Set the packet_sequence’s item_count to 20
5. Save and close the file

Task 5. Compile And Simulate with New Test________

1. Compile and simulate the testbench


> make test=test_da_3_seq
2. Check to see that 20 packets were generated and all destination address are 3’s
It may be difficult to count the number of packets processed by the driver. To
make visual inspection of messages easier to interpret, change the way the
transaction is being displayed in the driver.
3. Open the driver . sv file in an editor
4. Search for the r eq . print () statement and change it to:
'uvm_info ("DRV_RUN" , {"\n" , req.sprint () }, UVM_MEDIUM) ;
5. Save and close the file.
6. Compile and simulate the testbench again:
> make test=test_da_3_seq
At the end of simulation you should see:
** Report counts by id
[DRV_RUN] 20

If you set the ID and Message fields of the UVM Report mechanism appropriately,
you can make use of them during debugging to quickly isolate issues.

Configure Sequences Lab 3-5


SystemVerilog UVM Workshop
,ab 3

With sequence configuration, you now have the capability for both minimal code
and constrainable stimulus generation!

/ Constrainable \ Many runs,


( Random Stimulus^ ■
"* different seeds
\ Generation
......r —
Add/Change "^T estcase Functional
11
constraints ______ _ _ Coverage
wOk \ ...... ....v
Minimal e V Identify ||
\ Modifications / I I holes |

Task 6. Examine the Reset Sequence_______________

In typical testbenches, a reset sequence needs to happen before the functional


verification sequence is executed. The best way to manage this is to make use of
the scheduled phases. You will try this out with a simple reset agent and a simple
reset sequence.

1. Examine the reset_sequence .sv file with an editor


Notice that it only prints a message. Real reset operation will be implemented
in the next lab.
2. Save and close the file

Task 7. Add Reset Agent to the Environment_________

In the interest of lab time, the reset agent has been done for you. You just need to
embed it into the environment.

1. Open the router_env.sv file with an editor


2. Include the reset_agent. sv file
3. In the class, create an instance of reset_agent and call it r_agent
4. In the build phase, use proxy create () method to construct r_agent
5. Configure r_agent's sequencer (seqr) to execute reset_sequence at
reset_phase.
6. Save and close the file

Lab 3-< Configure Sequences


SystemVerilog UVM Workshop
Lab

Task 8. Compile And Simulate___________________

1. Compile and simulate the testbench


> make

Do you see that the reset happens first?


If you are not sure, change the report verbosity to UVM_FULL and look at
the phase execution sequence to see when the reset is executed.
2. Simulate the testbench with UVM_FULL switch
> make verbosity=UVM_FULL

Task 9. Optional: Source Code Debugging in DVE


If you have time left in the lab, you may be interested in continuing with a DVE
source code debugging session starting in the next page. Otherwise, you are done.

Congratulations, you have completed the regular portion of Lab 3!

Configure Sequences Lab 3-7


SystemVerilog UVM Workshop
Lab 3

Task 10. Optional: Interactive Source Code Debugging

There are times when you need to trace the problem in simulation by conducting an
interactive source code debugging session. The following steps will take you
through a simple example.

1. Take a look at the run-time command:


> make -n dve_i

You will see that run-time switch used for the interactive session is -gui
2. Start DVE in interactive mode
> make dve_i

You should see the following DVE display:

□ Rie Viev\ Simulator Signal Scope Trace Window Help


f ^ 0 xiOGps » I^ ® ^ -Cv: |^ % HI JS® m ~3
J i 1!:
*j ilaSIIBISiilBlBlBil id 14
/Hier 1 T 1H /D a te i
H ie ra r c h y p a n e 35 U n le s s r e q u ir e d b y a p p l i c a b l e Xav-
Sam! :F ‘ 3 h 16 v r i t i x ^ softw axs? d i s t r i b u t e d und
Hierarchy Variable a? distributed on an IS' 1
r ^iuvrn_reg_sequence ’do 18 oimrnow of xim, either e*
U V M package Q tesi (test) \uvm _re g _ s e q u e n c e do *9 the lacs&se to r the
S o u rc e c o d e p a n e
20 p ^ m S S lO fiS >f3Tid 1. 1 TO
f \uvm _neg_rnap d o _ b u s _
21
f \uvm _ re g _ s e q ue n ce_0 ■ 22 x fn r ia f PFG__L'V

Y o u r te s tb e n c h
F \u vrn_neg_seq ue n ce_0 .. 33 de x x r,c UVK~ PKG : V
* \uvrn_callbacks initialize .A
f \u v m _ p h a s e :add unnarn 25 x nc 1 ude ‘1 r o s ^s vfe ‘'
F \u v m _ phase get_dom ain
26
if n d e f Nu nvh IN PKG
f \u v m _ c o m p o n e n t"n e w u %%
r ,.uvm_neg_iterri d o _oop y ' e n d if
S o u r c e c o d e p a n e w i l l d is p la y t h e
f \uvm_neg_tlrn_adapter b 30
21 ' ifd e ± m o d u l e / i n t e r f a c e /p r o g r a m /c la s s
r ^ v m _ m e m configure .u...
\uvm_reg__map s et_sub 22 'mclu t h a t y o u d r a g a n d d r o p i n t o it.
f

r \uvm_reg__map get_sub
33 'defin F o r t h is la b , i t d e f a u lt s t o t h e
34 "e n d i f
r \uvm _ re g _ m a p X get_bu 35 U V M p a c k a g e . I f in te r e s t e d , y o u
f \u vm _reg _m ap Xget__bu 3*8 c a n b r o w s e t h r o u g h th e e n t ir e
F \u vm _reg _m ap Xget_bu... n me
r \ uvm _callbacks_0"initia1 1 58 me U V M s o u r c e c o d e h e r e .
f \uvm _callbacks_1 imtiali
'include 1comps/coraps.svh11
40 'include ";eq;seq.svh"
f \uvm _ c a llb a c k s _ 2 mitiali
41 'include 111Ira2/1lm2.svh11
f \u vm _ca 11ba ck s _ 3 ■■i n itia 11 42 ' include 1reg/uvm__reg_jiQdel.svh"
F \u v m callbacks 4 .mitiali

To expand and see contents of module/program/class or macro, simply click


on the +i symbol
Hierarchy Type
iHjjjj test (test) Pnogram
jffl^uvm pkg (uvm... Package

3. Click on the ±r symbol of test to expand it out

Lab 3-8 Configure Sequences


SystemVerilog UVM Workshop
You should see something like the following:

Slmh
hierarchy T yps ’
Variable Value; Type
- Q te s t (test) Prograrr D uvrr_start_uvrn Bit
+ 3 driver Class Def ■0 uvrr_aa_string.. String
: + @ iri p ut_age nt Class Def D uvrr__global__ra.. Int
: + @ packet Class Def 0 max[31:0] Int
Expanded
; + Q packet_da_3 Class Def ■■ D U V M JJN B O U ... Int
content
■ + Q packet_seque Class Def D s_conriection_. String

x : + £ i reset_agent
: + Q reset_sequerice
Class Def
Class
D s_connectiori_..
DefD s__spaces
String
String
Para...
+ @ reset_tr Class Def UVM_HDL_MA.
; 4- 0 router_env Class Def # uvrr_rngc_copy Para...
■ t @ test_base Class D ot uvrr_cdn_copy. Para...
+ CS test_da_3_inst Class De 7\pt uvrr_snps_cop Para.
j + ® test_da_3_seq C lassJD gp^ Wr~w uvrr_cy_copyri. Para..
! + 0 test_da_3_type Class Def # uvrr_nevision[7 Para...
!+ unnarred$$_4 Named Begn # UVM_STREAM. Para...
Q j vrrr_cu sto m_i... Mod u le m UVM_RADIX[3.. Para...
gf uvrr_pkg (uvrn... Package # UVM_MACRO_ Para...
+ (^_MCS_unit__1 (... $unit « UVM_DEFAUL.. Para..
m UVM_ALL_ON[. Para...
m UVM_FLAGS_.. Para...
m UVM FLAGS .. Para...

To see source code, double click on the entity of interest.


4. Double click on test to see the source code in source code pane
1
1/Hie r 1 ysta te , l l t l s s s 1 \
im p o r t uvra_pkg: : *;
l. g jf f ir T ..T. I s
JHierarchy T ^ T yps 4 in c lu d e "t e s t c o lle c t io n .s v "

l i i test (test) Prograrr © UVM_NOPACK[. + Pa ram


+ @ driver Class Def © UVM_UNPACK[... El Param
€ in itia l hegi
7 $ tim e fo r m a t(-
+ 0 input_agent Class Def © UVM_COMPAR... SI Param
ft ru n __test
Click on the file name
+ @ packet Class Def © UVM_ABSTRAC... S3 Param . 9 end
+ 0 packet_da_3 Class Def © UVM_RECORD[... ® Param. X© to see content of the file
+ 0 packet_seque. .. Class Def © UVM_NOCOMP... S Param XX en d p ro g r a n
+ npcpf anpnt npf © LJVM RFADDNI RI Param 12

Within the source code pane, if you entered a source code, you can return back to
where you were by clicking on the scope forward and backward buttons:

\ r -J
m!k.

ill

IfH ier 1 Vstack. 1 y Glass 1 \ /D a l 1 YtocaLI V to r o b e r l \ i


2 ' d e f i n e TEZ T COLLECT1ON SV
1 z jh 3 1 j f f j
.....Jli ^ J! .3
■j H&rar&hy Typs VansSte \M m Type | 4 ' in c l u d e “r o u t e r _ e n v .s v "
1 1 ■ test (test) Program 1 f © UVM_NOPACK[ Param 5
S3 c l a s s t e s t _ h a s e e x t e n d s u w u _ t e s t ;
f t # driver Class Def +- © LJVM_UNPACK[ Param..
§ i $ # input_agent Class Def 1 •ix. iiillV M m y P A B Param >
;T “ 31 'in c lu d e "p a c k e t_ d a _ _ 3 . s v "
I! 1B I I packet Class Def ! S m uvm Click on the + symbol ^?
to expand source code

Configure Sequences Lab 3-9


SystemVerilog UVM Workshop
Lab 3

Source code debugging of simulation involves two general mechanisms: break point
and single-stepping .

For break point, browse through the source code and click on the line number where
you want to set the break point. On the first click, a solid circle will appear next to
the line number. 1 B. program av;toraa 1i c test ;
2 import uvru pkg::*;
3
4 " ine1 ude "test collection.s v 1'

S in itia l begin
WllgSgM $tim e fo r m a t(- 9 , 1, "ns", 10) ;
m $
9 end
10
11 endprogram

On each subsequent clicks on the same line, the solid circle will change to a clear
circle, then disappears, then back to a solid circle and so forth:
i w
| i n i t i a l bet'- i in it ia l b e g in
6 w m m . i n i t i a l b e g in £
7 ] $tim e fo rm a t (- m n s>time form at ( ? £ tim e fo r m a t
• 8 O B (BEBKSBBB s
9 1end end 9 end
h h h h
10 10 10
1 .

ml..........7. _ zl ft & ! » & > # * !

.. \J
program autom atic te
n b e rT \
import uvTivjpkg: : *;

' in c lu d e "te st c o lle c t io n .


oackage
i n i t i a l begin
s>timeforraat (-9 f 1r "n s", 10)

end

The solid circle is an enabled break point. When you click on the continue button,
(or F5 key) simulation will execute up to that line (yellow arrow) and halt.

The clear circle is a disabled break point. It will have no effect when the continue
button is clicked. It’s a convenient reminder of where a break point can/should be
for that debugging session.

No circle indicates break point is not set for that line.

5. Set a break point at the run_test () statement, then click on continue


button
You are now at the beginning of the UVM test execution. The next thing to
try is the single-step mechanism.

Lab 3-10 Configure Sequences


SystemVerilog UVM Workshop
The source code simulation control buttons are group together:

Single step controls for all Single step through Step out of
code including modules all Testbench threads subroutine

Continue for specified time


(blank for no time limit) Single step in active Single step in active
A number (with a unit) is Testbench thread Testbench thread, but does
allowed e.g 1, lOOps, 0.1ns, etc. not enter subroutine scope

6. Click on the |||l button to single step through all threads in testbench
You are now in r u n j t e s t () subroutine scope.
7. Look at the bottom of the source code window, you should be able to see what
file the source code is in and where to locate the file:

p <5oto |%*>bai&pps3/vcg_201l.Q3-l,fetc/uw>-1.G/basewvm_globals.s\*h
§ uvmjjfobals.svh I

z z r ^ ~ ....
File in which the current
source code resides

The reason that run_test () subroutine is in the uvm_globals .svh file


is because it is an independent declaration not inside any class. Thus, when
the UVM package is imported into the program block, run_test () is a
global subroutine within the program block scope.
8. Continue by clicking on to enter the uvm_root: :get () scope
The first line in the get () subroutine checks to see if m_inst is null. What
is m_inst? Let’s find out.
9. Locate the Find button (next to the simulation control buttons) and enter
m_inst in the text field, then click on Find Previous button.

You should see that m_inst is a static uvm_root handle. The find
mechanism combined with the file location can be very helpful for you to
quickly pin point where to examine and correct code when necessary.

Configure Sequences Lab 3-11


SystemVerilog UVM Workshop
10. Click on {j^fr again, to go to next step.
You will see that the source code execution has advanced to the return
statement. Meaning that m_inst had already been constructed.
How can this be? Look at the source code from the m_inst declaration
down to the get () subroutine declaration. Do you see another
uvm_root : : get () call? When will this other get () execute?
Recall from lecture that in the beginning of UVM simulation, the following
structure is created:

Do you see that uvm_top is created at the beginning of simulation via the
get () subroutine?
What about uvm_test_top? How is that created. Continue to find out.
11. Click on to leave the subroutine and go back to the caller scope
What is top handle pointing to now?
12. Click on a couple of times to enter the uvm_root’s run_test ()
method
The source code now starts to get complicated. So, we will focus just on the
creation of the uvm_test_top object
13. Click on £ jj| a few times to get to the following statement:
test_name_count = clp.get_arg_values ("+ U V M _ T E S T N A M E = " ,test_name) ;
Here is where your + U V M _ T E S T N A M E run-time option is read and stored as
the test_name.
14. Click on until you get to the following statement:
$cast (uvm_test_top, factory.create_component_by_name (test_name,
"" , "uvm_test_top", null));

At this point, you have the full initial structure! Components with parent
handle set to null are
children of uvm_top

■uvm t e s t , to p

You can step through the rest of the base class code if desired. However, you
will find it overwhelming. So, you will better off to go to your own source
code and see what’s happening.

Lab 3-12 Configure Sequences


SystemVerilog UVM Workshop
15. From the Hierarchy pane, locate and double click on test_base to see the
source code:
extends uvra
uvth com ponent u t i l s (t e s t base)

Hierarchy - [ry w router e r.v env;

§ § test (test) Program


f unc t x on new (s t r i n g nam e, uvi c om p o n e n t p a re n t ) ;
; 0 driver Class Def
s u p e r . n e w ( narrse, parent) ;
+ 0 input_agent Class Def -u v m _ i n f o ('' T R A C E " , $ s f orraa t f ( " %ni" ) , U V M _H I G H ) ;
+ 0 packet Class Def e n d fun ctio n
+ 3 packet_da_3 Class Def
+ 0 packet_seque... Class Def v irtu a l fu n c tio n v oid faui 1 d _ j p h a s e (u v n ija h a s e phase) ;
s u p e r .b u i l d p h a s e (p h a s e ) ;
+ 0 reset_agent Class Def
' u v m _ i n f o ('' T R A C E " , $• s f o m i a t f ( 1' % m " ) , U V M _H I G H ) ;
+ reset__sequence Class Def
ertv = r o u t e r_e n v : : t y p e _id : : create ("e n v " th is) ;
+ 0 reset_tr Class Def e n d fun ctio n
+ Q router_env Class Def
HS & testjjase Class Def v irtu a l fu n c tio n v oid f i n a l _ p h a s e [u v r ii_p h a se p h a s e );
s up e r . x i n a 1 p h a s e (p h a s e ) ;
; :-^bui!d_phase Function
" u v m _ir if o {" TRACE " , $-sf o r m a t f ( " % r a ") ,, U V M _H IG H ) ;
,£,yfinal_phase Function
u v r & _t o p . p r i n t _ t o p o l o g y () ;
A get_object_t... Function
get_type Function f a c t o x y .p r i 0;
/ \ 9 eU¥Pe_ na • Function en d fu n ctio n

f new Function endclass

16. Click on the + symbol to see what vuvm__component__utils macro expands to


The most important thing to recognize is that the macro creates a proxy type,
t y p e _ i d , which is used in UVM to create objects of the class, y /
$
7
1
c la s s te s t base
'u v ra c o m p o n e n t
ty p e d e f
e x te n d s
u t ils (te st
u v ra t e s t ;
b ase)
u v ra _ c orap o n e n t _ _re g i s t r y # ( te s fc _ _ fe a s e , " t e s t _ b a s e " )
7
t y p e _ _ id ;
J s ta tic fu n c tio n ty p e _ x d g e t _ _ t () ;
Z re tu rn ty p e _ _ id :: g e t 0 ;
4 e n d fu n c tr o n
■5 v ir t u a l f u n c tio n u v r a _ o b je e t _ w r a p p e r g e t _ o b j e c t _ t y p e () ;
r e tu rn t y p e _ id : : g e t 0 ;
7 e n d fu n c t io n
const s ta tic s tr in g ty p e _ _ n a ra e = " te s t_ b a s e " ;
v ir t u a l fu n c tio n s tr in g g e t_ ty p e _ n a ra e ();
10 r e tu rn ty p e n a m e ;
11 e n d fu n c t io n

The rest of the lab is left up to you for experimenting with DVE debugging.
Just a few more notes:
If you want to restart the simulation, just click on the Restart button:
If you want to see the value of local properties of the scope that the source
code pane is in, look under the Local tab:

JIIIIIIIU" .........IJ".......
;* II
Vena Die Value Type
f-.this class test_base j

t- super class uvmjest


| i r- env null class router_env
; =•- type__name "test_base" string
i+i- phase class uvm_phase

You have completed the DVE interactive debugging session!

Configure Sequences Lab 3-13


SystemVerilog UVM Workshop
L a b :5 Answers / Solutions

Answers / Solutions
test__e©llection. sv Solution;

class test__base extends uvm__test; ...

class test_da_3_seq extends test_base; "


suvm_component_utils (test__da__3__seq)

function new(string name, uvm„component parent);


super .new (name/ parent);
'uvm__info (”TRACE”, $sf ormatf (’I%mn), U:¥M__H1GH) ;
endfunction

virtual function void build_phase(uvm__phase phase);


super .build__phase (phase)
uvm_info (’’TRACE”, $sf ormatf ("%m" ), UVM_HIGH) ;
uvm__conf ig_db# (bit [15 ;0]) ::set (this, "envvi_„age:nt^ .seqr ”/
f!da__enable11r 1 6 ’hOOOB);
uvm_conf ig_d.b# (int) ::set (this, "env. i_agent* .seqr ", ”item_count ’’, 20 );
endfunction
endclassendclass
d r i v e r , sv Solution:

class driver extends uvm_driver # (packet);


Nuvm_component_utils(driver)

function n e w (string name, uvm_component parent) ;


super.new(name, parent);
"uvm_info (”TRACE”, $sformatf (”%m”), UVM_HIGH) ;
endfunction

virtual task run_phase (uvm__phase phase);


'uvmjnfo (”TRACE”, $sf ormatf (”%m”), UVM__HIGH) ;
forever begin
seq_item_port.get„next__item (req) ;
'uvm_inf o (11DRV_RUN”, {”\n”, req. sprint () }, UVM__MEDIUM) ;
seq__item__port.item__done () ;
end
endtask
endclass

Lab 3-14 Configure Sequences


SystemVerilog UVM Workshop
Answers I Solutions Lab 3

packet_sequence.sv Solution;

class packet__sequence extends uvrnjsequence # (packet);


int item_count = 10;
int ::: port__id — “1;
bit[15:0] da_enable = '1;
int valid__da [$];

'uvm_ob ject__utils__begin (packet__sequenee)


vuvm__field_int (item_co.unt f UVM_ALL^ON>
Vuvrtv_field__±nt.(port_id, UVM_3-LL_PN):
:
suvrtu_field_int (da_enable, UVM^UL„QN)
suvm__f ield__queue_int(valid_da, UVM„ALL__ON)
'uvm_ob ject__utils__end

: function .void pre_random.ize () ; ;


uvm_conf ig_db# (int)::get (na_sequencer, "’’, "item_count", item_count) ;
uvm„conf ig__db# (int)::get (m_se:quencer , ””f !fport__idl,/ port__id) ;
uvm„conf ig_db# (bit [15 :0] ) ::get (m_sequencer, "% "da__enable",da_enable);
if (! (port_id inside {-1, [0:15] })) begin
suvm_f atal (,fCFGERR" , $sf ormatf ("Illegal port„id value of %0d,f,
port_id));
end

valid__da .delete () ;
for (int i= 0; i<16; i++)
if (da_enable[i])
valid_da.push__back(i);
endfunction

function new(string name = "packet__sequence" );


super.new(name);
"uvm__inf o ("TRACE" , $sformatf("%m" ), UVM_HIGH) ;
endfunction

task body();
'uvm__inf o ("TRACE" , $sf ormatf ("%m" ), UVMJHIGH) ;

if (starting_phase != null)
starting_phase .raise_ob jection (this) ;

repeat (item__count) begin


vuvm_do_with(req, {if (port_id == -1) sa inside {[0:15]}; else sa
== port_id; da inside valid_da; }) ;
end

if (start ing__phase != null)


start ing__phase .drop_objection (this);
endtask

endclass

Configure Sequences Lab 3-15


SystemVerilog UVM Workshop
Lab Answ ers / Solutions

reset_sequence.sv Solution:

class reset__sequence extends uvm__sequence# (reset__tr) ;


Nuvm_ob ject__utils (reset__sequ.ence)

f unctaon;:;.;;new'(s'tring VhameV'^.:.T-xes-Bt_s0c3la;e:
n-ce'*r.)7
super.new(name);
'uym__i.nfo ("TRACE", $sf ormatf (”%m" );, UVM__HIGH) ;
endfunction

task body();
suvrn_info ("TRACE" , $sf ormatf ("%m"), UVM_HIGH) ;

if (starting_phase !- null)
starting_phase.raise_objection(this) ; ■

'uvm__inf o ("RESET”, "Executing Reset11, UVM__MEDIUM) ;

if (starting„phase != null)
starting__phase *drop„obj ection (this ) ;
'::.endt>a;s:k■;';; . ■ . ■ ■ ■■
endclass

router_env. sv Solution:

class- router_env extends uvm_env;


input_agent i_agent;
reset_agent r_agent;

suvm_component_uti 1s (router__env)

function new (string name, uvm__component parent);


super.new(name, parent);
Nuvm__info( "TRACE", $sformatf ("%m" ), UVM_HIGH) ;
endfunction

virtual function void build_phase (uvm„phase phase) ;


super .build__phase (phase) ;
vuvm__inf o (”TRACE" , $sformatf (”%m" ), UVM__HIGH) ;

i_agent = input_agent::type__id: :create ("i_agent" , this ) ;

uvm__conf ig_db # (uvm_ob ject__wrapper) ::set (this, "i__agent .seqr .main_phase


"def ault__sequence", packet__sequence ::get__type () );

r_agent = reset_agent::type_id: :create ("r_agent", this ) ;

uvm_conf ig__db # (uvm__object_wrapper) ::set (this, "r__agent.seqr .reset__phas


"def ault_sequence”, reset_sequence ::get__type () );
endfunction
endclass

Lab 3-16 Configure Sequences


SystemVerilog UVM Workshop
Configure Drivers,
Sequences, and
Environment

After completing this lab, you should be able to:


• Add DUT virtual interfaces to driver
• Add configuration fields to driver
• Add physical device drivers to driver
• Add DUT virtual interfaces to reset sequence
• Add physical device drivers to reset sequence
• Compile and simulate

p *? Lab Duration:
30 minutes

Component Configuration Lab 4-1


Synopsys 40-I-054-LG-003
_ iver and reset sequence to actively process the
stimulus through the DUT.

v ------- — .. ..... — , different seeds «


\ Generation y
Directed
I Add/Change ^Testcase Functional
J constraints J §_______ Coverage
N

Modifications / holes
./ L—

program automatic test;


// class definitions
initial begin
run_test ();
end
endprogram

DUT

Figure 1. Lab 4 Testbench Architecture


Lab 4-2 Component Configuration
SystemVerilog UVM Workshop
Lab

Lab Overview

The work flow for this lab is illustrated as follows:

Figure 2. Lab 4 Flow Diagram

Component Configuration Lab 4


SystemVerilog UVM Workshop
Lab 4

Implement Configurable Environment

Up to this point, you have not driven any test stimulus through the DUT. In order to
do this, you need to embed and configure DUT virtual interfaces in physical drivers
and implement the device drivers.

In this lab, you will add the DUT virtual interface and other configuration fields to
the driver, reset sequence, agent and environment. The device drivers will be
written for you.

Task 1. Go into Iab4 Working Directory

1. CD into the lab4 directory


> cd ../Iab4

Task 2. Add Interface and Configuration to Driver____

1. Open driver.sv file in an editor


2. Create a D U T virtual interface (router_io) handle, call it sigs:

class driver extends uvm_driver # (packet);


virtual router_io sigs;

3. Add the ability to designate the driver to only drive a chosen port with an int
property called port_id with the default value of -1:

This port_id is meant to configure the driver to only drive packets of


matching source address (sa). If the incoming packet’s sa does not match
the driver’s port_id, that packet will be dropped.
If port_id is not set (-1), the driver will accept and drive all incoming
packets. For this lab, you will leave the port_id at the default value of -1.
In the next lab, you will make use of the port_id.
4. Add the port_id to uvm_component_utils:
Add _begin to macro
— : ~ — fe ll!

'uvm_field_int (port_id, UVM_DEFAULT | UVM_DEC)


'uvm_coraponent_utils_end

Notice that the virtual interface handle (sigs) is not added to the
uvm_component_utils macro list. This is because there is no support in
the uvm_component_utils macro to accommodate virtual interfaces.

Lab 4-4 Component Configuration


SystemVerilog UVM Workshop
5. Add the following code to retrieve and check the configuration properties in
build phase:

virtual function void build_phase(uvm_phase phase);


super»build_phase(phase);
'uvm_info("TRACE", $sformatf("%m"), UVM__HIGH);
u v m _ c o n f ig _ d b # ( i n t ) : :g e t ( t h is , " n, " p o r t _ id n, p o r t _ id ) ; Get port_id
i f ( ! ( p o r t _ id in s id e { - 1, [0:15]})) b e g in
su v m _ fa ta l ( "CFG ER R " , $ s fo rm a t f ( " p o r t _ id m ust be {-1, [0:15]}, not %0d!", p o r t _ id ) ) ;
end
u v m _ c o n f ig _ d b # ( v i r t u a l ro u te r_ JL o ) :: g e t ( t h is , "" , " r o u t e r _ i o ff, s ig s ) ;
i f ( s ig s == n u ll) b e g in
' u v m „ fa t a l("C FG E R R ", " In te rfa c e fo r D r iv e r not s e t ");
end
endfunction Retrieve DUT virtual interface and store handle in s ig s ~ ~ J

Locate the run__phas@ () method and add the following:


• Check p o rt_ _ id to see if the driver should accept or drop the packet. If
Drive packet only if port___id is -1 , or if p o r t _ i d matches r e q object’s s a field, call
p o rt_ _ id matches s e n d () method to drive the content of the r e q object through the DUT.
r e q . s a or is - 1 Otherwise, drop the r e q object without processing.

if (port_id inside { - 1 , req.sa }) begin


send(req);
'uvm_inf o ("DRVJRUN", {"\n", req. sprint ()}f UVM_MEDIUM) ;

seq_item_port.item_done () ;

endtask

To save lab time, the start__of_simulation phase and the physical device driver
methods are done for you.
7. Save and close the file

Task 3. Agent Configuration_____________________

The agent which contains the sequencer, driver and monitors should configure its
own sub-components. Then, at the test/env level, the focus of configuration will
only need to target the agent of a given interface.

Since the configuration calls are the same as what you have already done, there is no
learning point in going through a typing exercise to enter the code in the agent. All
the configuration code have been done for you in input_agent.sv.

Take a look at the code if you are interested. Otherwise, continue on to the next
task.

Component Configuration Lab 4-5


SystemVerilog UVM Workshop
;ab 4

Task 4. Compile and Simulate

1. Compile and simulate the testbench


> make
You should see the following error:

UVM_JNFG @ 0.0ns: reporter [RNTST] Running test test„base...


UVMJFATAL driver. sv(77) @ 0.0ns: u v m j e s t Jop.env. i^agent .drv :
[CFGERR] Interface for Driver not set
-- UVM Report Summary —
** Report counts by severity

■ ........ fatal error occurred.


. _, This is because the virtual interface was never set!
UVM_ERROR : 0
UVM FATAL : 1

Even though the DUT virtual interface was added in the driver, you have not yet
configured it in the test. This is a fatal error that you must correct.

Task 5. Add Virtual Interface Configuration in Test

1. Open test_collection.sv file in an editor


2. Locate the build_phase method in test_base class
3. Configure each agent's virtual interface in the environment as follows:

virtual function void build__phase (uvm_phase phase) ;


super.build_phase(phase);
env = router_env::type_id::create ("env", this);
uvm_con£ig__db# (virtual router_±o)::set(this, "env. i_agent",

uvm config db#(virtual router_io)::set(this, "env.r_agent",


"router__io" , router_test_top. sigs);
endfunction
Access the DUT interface with XMR
Note: The testbench harness file is locate in ~/rtl directory. If you are
interested, take a look at the router_test_top.sv file

4. Save and close the file

Lab 4-6 Component Configuration


SystemVerilog UVM Workshop
Task 6. Compile And Debug The Program

1. Compile and simulate the testbench.


> make

How many packets did the driver process? (Hint: DRV_RUN count)
But, did these packets propagate correctly through the DUT? Check it in the
DVE waveform window.
2. Open DVE with the following command:
> make dve

You should see that all output values are red (unknown)! This is because the
DUT needs to be reset before it can successfully process inputs.
3. Exit DVE

Task 7. Update the Reset Sequence______________

In lab 3, you configured a reset_sequence to execute at the reset phase.


However, that reset_sequence code didn’t do anything. In this task, you will
update the reset_sequence to perform a DUT reset.

1. Open the reset_sequence .sv file in an editor


2. In body () task, assert reset for 2 cycles followed by de-assert for15 cycles:

task body();
'uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);

if (starting_phase != null)
starting_phase .raise__ob jection (this) ;

'uvm_do„with (req, {kind == ASSERT; cycles == 2;});


'uvm_do_wifch (req, (kind == DEASSERT; cycles == 15;});

if (starting_phase != null)
starting_phase.drop_objection(this) ;
endtask

3. Save and close the file

Component Configuration Lab 4-7


SystemVerilog UVM Workshop
L ab

Task 8. Compile And Simulate with Reset Sequence

1. Compile and simulate the testbench.


> make

Did it work? Check it in the DVE waveform window.


2. Open DVE with the following command:
> make dve

You should now see that the output signals no longer are red. However, the
base test was designed to send 10 packets through the DUT. In the waveform
window, this is not what you are seeing. There is still a problem.

Task 9. Implement pre_reset and reset Phases

With the reset agent and reset sequence, the only thing that happened was the
assertion and de-assertion of the reset signal. How about the other control signals of
the interfaces? The reset agent and the reset sequence should not be responsible for
taking care of all signals of the DUT. Doing so will complicate the development of
individual tests and integration.

There two ways to resolve this problem. One, create and configure a sequence to
de-assert the the control signals. Or, two, de-assert the control signals with the
pre_reset_phase () and reset_phase () methods.

In this lab, you will embed the de-assertion of control signals within the individual
driver of a given interface. You will implement the pre_reset_phase () and
reset_phase () methods.

1. Open the driver.sv file in an editor


2. Look for the pre_reset_phase () and the reset_phase () methods
In the driver's pre_reset phase, all of the signals are set to their default states
(x for logic, z for wire). This emulates the power up conditions.
In the driver's reset phase, the signals are set to the de-asserted states. This is
to emulate the conditions of the external signals at reset.
3. Uncomment these methods to enable the pre_reset and reset phase execution
for the driver.
4. Save and close the file

Lab 4-8 Component Configuration


SystemVerilog UVM Workshop
Task 10. Compile & Simulate with Driver Reset Phases

1. Compile and simulate the testbench.


> make

2. Open DVE with the following command:


> make dve

You should now see the correct behavior: 10 packets came out of the DUT.
3. Try and run the destination address is 3 and 20 packets test:
> make test=test_da_3_seq

4. Take a look at DVE again


You should see that 20 packets came out of output port 3.

Congratulations, you have completed the regular portion of Lab 4!

Component Configuration Lab 4-9


SystemVerilog UVM Workshop
Task 11. Optional; UVM Transaction Debugging

There are times when you need to trace the problem in simulation by conducting an
interactive source code debugging session. The following steps will take you
through a simple example.

1. Take a look at the run-time command:


> m ake —n ru n

You should see the following:

./simv -1 sxrav.log +ntb_random_seed=l +UVM_TESTNAME==test_jbase \


+UVM_VERBOSITY=UVM_MEDIUM +UVM_TR_RECORD +UVM_LOG_RECORD

Start DVE in post-processing mode with transaction debugging:


> m ake d v e _ .tr

You should see the following panes in the lower portion of the DVE window:

Transaction stream filter

JSl ~3f begin.....fend................. :i|i:


scape
C a lT ^ m B f S [ r ~ 6 9 n v £ co pe| Seventy! Type]
□ES________ (0) 1 ...r:: catch ver LOGSRNTST - NORM NOTE START
r - f ig User - msglog ...action ...nee ...Senv$r_seqnB NORM: XACl: START
i" W o ............. resal
j ' - j l l User -tb log i 155 16500 jpacRet... action ence ,.$agent$seqr » NORM: XACT START
t VMM/UVM- msglog 1' E '1 6 5 0 0 ..... req action req $agent$seqr b NORM XACl START
L H i VMM/UVM-tb log i ' ii"To55oo"" uvrr_test r catch ver $DRV_RUN « NORM NOTE START

i
i f ji^: '105500 ' :req action req $agent$seqr ■ NORM XACl START
i" p 130500 ;uvrrjest,< ...r::catch ver $DRV_RUN■ NORM NOTE START
m p 'l3 0 5 0 0 " " ; req action neq $agent$seqr * NORM XACl START
amstacKJ

Stream browser
(for UVM - components and log messages)

For UVM, the automatically recorded streams are the UVM sequence
transactions and the UVM log messages. For this lab, you will only be
looking at the VMM/UVM - ms l o g folder.

"3 S p lto n s -■ U m r) F r o rr^ [b e g in ^3te je n d ^3


Scope
TKn# (100ps5 Me* rage QM S tuck Nsm*j Stfeam fScape
+ - o (0) r catch ver LOGSRNTST
'*1 User - msglog + - o reset_ action nee SenvSr_seqr
U ser-tb log ] + ~ 16500 packet action ence Sage ntS seqr
t VMM/UVM - msglog +
\ ~ 16500 req action neq Sage nt$ seqr
J VMM/UVM - tDlog + ~ 105500 u v rrje st r catch ver $DRV_RUN
+ v- 105500 req action req Sage ntS seqr
j + ~ 1005*" uv rrje st r catch ver $DRV_RUN
i + ~ 130500 neq action neq Sage nt$ seqr
— 1 Stack;)-*

3. Click on the + symbol of the VMM/UVM - msglog folder to expand it

Lab 4-10 Component Configuration


SystemVerilog UVM Workshop
In the expanded VMM/UVM - ms log folder, you should see that the
recorded streams are displayed. There are two typical streams: sequencer
transaction streams and UVM log (message id) streams. Each stream may
contain a series of transaction over time associated with the source of the
stream.
Note: Use the filter text field to narrow down what get displayed in the
stream browser window if there are too many streams.
"r - ... -g- I '''iijiillj enci

| Tff
■■■■ill User - msglog ■ 0 reporter [LOW]: ...:catch j report_serMrer
■■••fll User - tblog L+i W o .............. iuvrr^testJop,env.r .: ...:catch i report server
m VMM/UVM - msglog i+: () juvtr mte s t jo p ,env . \ j i catch : report_server
••••Es; LOG5 RNTST * W o .............. juvrr^tesMop.env.i^;i catch j repo rt___seu rer
S S o............... i reset_sequence ...action ! reset_sequence
■■••iEsi LOG5 RSTCFG
* W o .............. | req ...action : req
•■••ED LOG$DRV_CFG 1500 |req
+ : ...action ; req
■■•■ilo LOG$AG NTCFG • 16500 | packe't_sequence i ...action | packet_sequence
■■■■05! uvm_test_top$env$r_agent$seqr Si 16500..... i req ; ...action req
-•
■■■■ uvm_test_top$env$i_agent$seqr ' i " 61500..... ju v r r j e s tjc .p env ij i .: catch report_server
-!M!LOG$DRV__RUN r°"
m
■■• LOG$ UVMTOP
J ~3(sw*:F

4. Click on uvm_test_top$env$i_agent$seqr to see the sequence and


sequence_items/ransaction stream that the sequencer generated
delatt] I 1
Tvpp
C-CJD

User - msglog
User - tblog Type of message:
VMM/UVM - msglog
TjLOG$RNTST XACTION for transactions
Z3LOGSRSTCFG
Ji_agent$seqnw NORMAL :TION j START i
-ni LOG$DRV_CFG XA(%ION START
NORMAL
3LOG$AGNTCFG lL i XACTION : START ;
Z3 uvm_1est_top$env$ r_age nt$seqr $i_agent$seqn« NORMAL"" iN j START :
■i uvm_te st__top$env$i_agent$seqr .$i_agent$seqrj» NORMAL jXACTldft^TARfl
,$i_agent$seqns NORMAL XACTION TSTART ]

Severity of message:
Transaction stream recorded NORMAL for transactions

The UVM s uvm_inf o/warning/error/f a t a l macro generated log


messages are also recorded if +'UVM__LOG__RECORD run-time is applied
during simulation (as has been done in the lab).

class driver extends uvm_driver # (packet);


// other code not shown
virtual task runjphase (uvrnjphase phase);
"uvm_info (rrTRACE % $sformatf (rr%mrr), UVM_HIGH) ;
forever begin
seq_item_port *get_next_±tem (req) ;
if (port_id inside { ~lf req.sa }) begin

vuvm_xnf o ( "DRVJR8H!% { " \n r*, r e q . s p r in t () h UVWLMEDXUM);


end

For example, in the driver code, there is a s uvm_info embedded with the
message id of DRV_RUN. This will show up in the browser window under
LOG$DRV_RUN.
Component Configuration Lab 4-11
SystemVerilog UVM Workshop
Lab 4

5. Click on LOG$DRV_JRUN in the browser window to see all the log messages
for mess^ e id DRV.RUN:
Verbosity of message: Severity of message:
Use filter to quickly locate Where message was generated MEDIUM, HIGH, FATAL, ERROR,
message id of interest FULL and BEDUG WARNING and NORMAL
l& re d Frorr begin Sgver^^'iiifilP^Vpelll|
S're~T
] Tirne 5ave-dr;-
-IM I LOG$RSTGFG
+ - 49500 i uvrr_test_top.env.i___agent.dr/ [MEDIUM] :i ...r::catch ; .ver ...$DRV__RUN!« NORMAL jf c T E iS TAR TI
- [S3 LO G $ D RV_C F G
>. + - 114500 : uvrr_te st_to p .e nv. i_age nt.drv j M E D1UM] i ...r::catch 1 ...ver: Z$DRV__r u n ;b ’ n o r m a l ” [NOTE...... ....[ s t a r t
~E§3LOG$AGNTCFG - - 187500... uvrr_test_top.env.i_agent.drv [MEDIUM]... ;i ...r::catch | ...ven [[$DRV__RUN:n ' n o r m a l ”I n c it e ...... .....fSTART*
- Eli uv r n je st_to p $e nv$ r_age nt$: + 276 5 0 0... : uv rr J s st_to p ,env. i_age nt.d rv [ M E D1U M]... . ..r::eaten j ...ver; ...$DRV _RUNi*' n o r m a l ”Tn o t e ...... .....[ s t a r t s
- ESI uvm_te st_to p $e nv$ i_age ntE ikS 333500 i uvir_tBSt_top.env.i_agent.drv [MEDiUM]... r::catch | ...ver; ...$DRV_[ r UN:* n o r m a l ” [ n o t e ...... .....VSTARTs
-vLOG$DRV RUN
.I..0.0.$ I..IVMT.OP User errorsJP

Type of message:
Simulation time when message was generated Method that created message
NOTE for UVM log messages

At the upper right hand corner of the transaction pane, there are two drop­
down tabs for severity and type. Clicking on them will enable you to display
only the severities and types of the messages of interest:

dw height rwghrfi “3
j7 f a il u r e
eriiy Severity Type Targr
V NOTE
TtfOTTt
m ttM r
a NORMAL NOTE STpRT |7 DEBUG
DRMAL ; NC ■ NORMAL NOTE START 17 REPORT
3RM AL NC > NORMAL ; NOTE jTTART
17 NOTIFY
DRMAL INC t WARNING NOTE I tart
EARNING N O ] # ERROR NOTE I tart 17 TIMING

=?ROR NOT r■ NORMAL XACTION jta r t V XHrtNDLING


3RM AL XACT ■ NORMAL NOTE I tart V XACT ON
- NORMAL NOTE Start 17 PROTOCOL
DRMAL NOTE
« NORMAL NOTE S lA R T
17 COMMAND
b NORMAL NOTE S T^T
•17 c y c l e
« NORMAL NOTE STA^T
■ NORMAL NOTE STAR n ■17 TB
* UJADMIMC . M n tc .Q-Tr. DT 17 ALL

Once you located the transaction and UVM log messages, you would typically want
to see the transaction/log message on the Wave window. One quick way of finding
a stream is to make use of the stream filter.

6. In the stream filter text field en terf seqr


j^seqr] ill* j|||j

J Strsarr Scope
P,1 User - msglog
. Q j User - tblog
- n VMM/UVM - msglog
E 3 uvtr _te st_to p $e nv$ r_age nt$ seq r
111 uvirjest_top$env$i_agent$seqr
;
f ] VMM/UVM -tblog :|

As you type, you should notice that the stream source browser window is
updated dynamically to show you the result of the filter.
7. Click on uvm _t@ st__top$@ nv$reagent$s@ qr
This will display the reset„sequence and reset_.tr object re q .

Lab 4-12 Component Configuration


SystemVerilog UVM Workshop
8. Click on the + symbol of reset_sequence and req in the transaction pane
m *seqr .......... d i- \ d f £>ptK>rtS * j 13mei f F n o m j2 ft 3 5 ^ J e n d ..... T i B & w h s jg h t;|T ““ 1 f i ^ Verity y j
| jj Stream | S cape \
rm ie t lOOp <31 | M en ag e 1M EtacK N mop s tre a m s cope | Seventy | Typs j
§ | | U s e r - m sglog
t ~~cT- ie £ o cT i reset_sequence . .nsaction ...ence ...$r_agent$seqr;B NORM AL iXAC TIO N START
! § f U s e r - tb log [V S 0 ireset_sequence .,. :
;■ :j: |:: ;■ ::\j ( :P . ; START
;4- g i V M M /U V M - m sglog | 16500............. ...nsaction :r ;■;::;C •i a \\ '•[):■'<;■. i FINISH
?! uvm_te st_to p $e nv$ r_age nt$ seq r mm o - isoo 1req ...nsaction neq ...$r agent$seqri NORMAL XACTIO N i START1
1H53 uvm _test_top$env$i_agent$seqr |l = o w : req . ' I I : :! -'\m mom
. ; START

| VM M /U V M -tb lo g I
1
s 0
i ~ 1500 \ •kind: ASSERT
: ...nsaction
,-i ...nsaction
m
m ' l y Z c :L
1CHILD
^ F IN IS H
I I + •• 1 5 0 0 - 1 6 5 0 0 ^ ve q ...nsaction neq Ft,r \XACTION jS T A R T

You will see the START and FINISH times of the transaction
9. Click on the Right Mouse Button on the transaction, add it to Wave window
B H H I I | Message m M n M H Streamscope seventy Type
3 0 - 16500 j re s e t_ s e q u e n c e ..nsaction : ...encej ...$r_agent$secjrj« NORMAL iXACTION iSTART
j re s e t_ s e q u e n c e l S i : : : ;:f ‘i ;' : rV'::4r^^ V::5 ? * ' ' ^ : ; V ; - ' r [ S T A RT
= 165 0 0 .. n sa ctio n i e ?'; ?| . ; • •• • •?$ ^ qri ■ N ■::;R iv•,■ I i.;<.*>.07?O N j FINIS H
Sr_agent$seqn NORMAL iXACTION ISTART
= 0 | req □ Show Source START
•I : C H IL D ...
Add To Waves
= 1 50 0 k L r td r ij T [ f in is h
~ 1 50 0 - 1 6 5 0 0 sneq
Add vanabte? T o Wsvec ION TS TAR T
Sync Tran radian Q onM p Create new group
ShowTfsns&cta Rgl&ltone-

AutoErt Golurrn W«lth “3 Us?

10. In the Wave window, click on the zoom out button a few time to see the
reset_sequence fully displa^H tfthe start time and clear at the finish time.
~U!!i » i ____________

rressHsequeice
wrV mri^
(Mi u'vmje st_to p., @ 0 @ 1500
*00 @ 76500

With only transaction displayed, it’s hard to tell what’s going on. You need to
see the DUT signals to start to be able make sense of things.
11. Click on Window -> TopLevel. 1 to go back to the Hierarchy pane
m Bfc dm Vjftw K jirifiJ^f Signal
1 0 ^1&0ps - ^ N&w
1 3&M j^ ^ p n y F d g r set Tfa* f-rame rartj*t *

j ^^ •- Af" New Top 1evei Frwne

* 3rr3|[?3! Lftttti LSjg&ut


Ns>*ns j vsfue |
Save Current layout
Group? .............. : i Itfsuairw®V
te-
vj
forrang©
LzzJ uvm_test_top Dock m New Row
D^ck in Nsw Column
Undock
■N ew Group

s&i Top Levsi rate ,


Switch T ap Level
TopLevel.J. - [Source. ■

Component Configuration Lab 4-13


SystemVerilog UVM Workshop
>afa 4

12. In the Herarchy pane, expand router_test_top, right-click on sigs (router_io)


and add it to the recent Wave window:

; - : J | ro u te r_ te s t_ to p ... M i j--©-clk
! $ f | | d u t (ro u te r) tm h i reset_n
Ih o s t f h o s t J o ) Irlj B - 1 fra m e _ n [1 5:0]

I f me Copy
B H ...si..
.QteS^ — llllllll ro u te r
H Shaw Source lllllll
Q Show Schematic i 5:0] 12 in it ia l
13 $vcdp
U Show Path Schematic 5 0]
lllflllj fo re ’,
Add To W aves £sfew W mm View
Add To y e ts Recent (Wave. 1) Ctrl+4
ftdcl To ofc-up^ P Ofe&te new grc u p
AGd To watches
W ave 1

13. Go back to the Wave window, you should be able to see the reset_sequence
timing with respect to the actual DUT interface signals

rr r^ tlSQO.HSSOCt j
■tojuvrr_test_top... neq I & 0 @ 1500
!1*00 0 16500

•B- C!K 0

■0 reset_n 1'bo:
• 0 frame_n[15:0] 16'hxxxx

■0 valid_n[15:0] 16'hxxxx

■0 din[ 15:0] 16'hxxxx


■0 dout[15:Q] 16'h 0000
• 0 busy_n[15:0] 16'hffff
■1 valido_ri[15:0] 16'hffff
■B frameo_n[15:0] 16'hffff

14. Go back to DVE TopLevel. This time, in Stream browser pane, add
uvm_test_top$env$i_agent$seqr to the Wave window.
_ _ _ _ _
*seqr
1 Options * | Iime:(RDm3f
j Scope
User - msglog r Ttrre(100psl
I"*! User - tblog
!+ ‘ 16500 packet_s
+ 16500 req
□ VMM/UVM - msglog | +' ” 81500 neq
U u v m je st_to p$env$ r_age nt$seqr
{+“ 211500 eq
Acid To W aves New Wave view
VMM/UVM - tblog
Arid Variables To Waves * Re oe nt (Wave. 1) Ctrl+4
Expand Atl r create rew group
C&H&pse All Wave 1
Sgl&ct All j -----------------------------

Lab 4-14 Component Configuration


SystemVerilog UVM Workshop
You should see packet_sequence and its associated sequence_items
displayed.

h'E;- elk

i ■B reset_n

0 fram s_n[15:Q ] "1 M . m . T _T F


+ Q v a lid_n[ 15:0] .n'fwf'xi .fTtf.Tf^ru....TOC*
0 d in [ 1 5:0]

0 do u t[1 5 :0 ]

a busy_n[15:0]
+ D va lido_ri[16:Q ] \ I fffe ). If7ff ( { dfff i i bfff i
+ B fra rre o _ n j 1 5:0] bfff II fff7

req ' f r«q^ W f r req r veq t,$r \


!> 244500 @ 30* \@ 342500 j @ 432500 @ 521500
*3 0 7 5 0 0 @ 34* \@ 415500 @ 5 2 7500 @ 594500

15. Place the cursor over the triangle table for each transaction to see the content
of that transaction

@ 260500

payload[0]: fO
payload[1]: S'c
payload[2]: 38
payload[3]: 65

For the UVM log messages, you can do the same thing.
16. In the Stream browser pane, change to filter to *LOG
You will now see only the log message streams.
*l o g | ..... ...............................

1User - msglog
2 3 User - tblog
- ^ V M M /U V M - msglog
SLO G $R N TST
JT3 LOG$DRV_RUN
r"JLOG$UVMTOP
rMM/UVM - tblog

Component Configuration Lab 4-15


SystemVerilog UVM Workshop
,ab 4

17. Right-click on LOG$DRV_RUN and add the stream to the Wave window

"1 User - msglog


g l j i i 105500 juvm test top.env^d
22U User - tblog
13050 0 iu vm je s t j p . e n v.api
- ^ V M M /U V M - msglog 219500 :u'vrnje sM o p .env.aai
C l LOGSRNTST 260500 iuvrrMest_top.eriv.aoi
500.iivrn.
j Add To Waves New Vjsw
Zj LOG$Lj
Add VsmDles l o Wavet* ►m Recent (Wave. 1) Ctrl+4
Expand All r
, , , , , , , All Wwvii I
;
i!!l§ !!llil||;i!lH
—™ _ r

Once again, you can place the cursor over the triangle tab to see the content of
the message. One thing you should notice, UVM log messages do not have
start and finish time. Yet, in the display, the UVM log messages spand over a
period of time. This is not entirely accurate, but is done for visualization. The
simulation time at which the UVM log message is generated is treated by
DVE as the start time. The UVM log message then persists until the next
UVM log message of that stream is generated. So, in DVE, once the UVM
log message stream starts, you will never see a gap in between the messages.

[3] integral 8 ‘h8c


[4] integral S
[5] integral 8 'h58
[6] integral 8 'hd3
[7] integral 6 'h68 .
[8] integral 8 'h9e
[9] integral 8 'h24
beginjime time 64 8150.0ns
depth int 32 'd2
parent sequence (name) string 15 packet_sequ... Place cursor over
ff7f" y
parent seq uence (fufi name) stri ng: 45 uvrrje st_to, triangle tab to see
sequencer string 29 uvm_test_to.,.
r pa cte1_?aq uence i1
content of message
\uvm_nepo rt_ha nd ler::repo rt
r reef ,;dl500J705: “* \uvm__repo rt_se rve r::repo rt
@ 81500 \uv(n_ne port_catche Il_nepo rt_catche rs
@ 170500 Auvm :repoct^gatfifleripno-cess report catcher
*S^frrwtlog_catche r::catch
r uvrrje? tju p e n v * * y vrrJ i 3 s t j op iv ,tjrt pnUtf* J uw Je v lJu p e ‘f.VM-f
driver.sv(1'18): driver.sv(118): driver.sv(118):

The knowledge that you gained in this exercise may help you to debug your
code in future labs.
The rest of the lab is left for you to do your own exploration.
For more information on the DVE debugger, consult the user guide for DVE.
(see $VCS_HOME/doc/UserGuide/pdf/dve_ug.pdf)

Congratulations, you have completed the optional portion of Lab 4!

Lab 4-16 Component Configuration


SystemVerilog UVM Workshop
Answers / Solutions

Answers / Solutions
test_Gollection.s v Solution:
class test_Joase:extends uvm_test;
suvm„component„utils (test__base)

router_env.env;

function new(string name, uvm_component parent);


super.new(name, parent);
suvm__inf o ("TRACE", $sf ormatf ("%m"), UVM„HIGH) ;
endfunction

virtual function void build_pkase (uvm___phase phase) ;


super *build_phase (phase) ; :
^oiwrinf o ("TRACE ", $sf ormatf ("%m"), UVM^HIGH) ;
env - rout er__env:: type__id:: create ("env" , this);
uvm_conf ig_db# (virtual rout.er__io) ::set (this, "env. i_agent ",
"rout er__io ", router__test_top .sigs );
uvm__conf ig_db# (virtual router__io) ::set (this, "env.r__agent",
"router_io" , rout er__test__top.sigs );
endfunction

virtual function void final„phase(uvm_phase phase);


super.final_phase(phase) ;
suvm_info ("TRACE", $sformatf ("%m") , UVMJSIGH) ;
uvm_top .print__topology () ;
factory.print();
endfunction
endclass

Component Configuration Lab 4-17


SystemVerilog UVM Workshop
Lab 4 Answers / Solutions

d r i v e r . s v Solution:

class -driver extends uvm_driver # (packet):; ;


: :virt-:uai r out er__io sigs; : // :PUT' virtual inter face :;
int port__id = -I ; //Driverfs:designated port

suvm__component_utils_begin (driver)
vuvm__field__int (port_id, UVMJ3EFAULT I UVMJDEC)
vuvm_component_utils_end

function new(string name, uvm__component parent);


super.new(name, parent);
^uvm_info("TRACE", $sformatf ("%rn" ), UVMJIGH) ;
endfunction: new

function void build_phase (uvm_phase phase)


super .-bui-ld_pha.se (phase);.
vuvm__info ("TRACE" , $sformatf ("%m" ), UVMJiIGH) ;
:Uvm__conf ig___db# (int)::get (this, ffport__id" , port__id) ;
if (!(port_id inside {-1, [0:15]})) begin
"uvm_fatal ("CFGERR" , $sf ormatf ("port__id must be {-1,[0:15]}, not
%0d!", port_id));
end
uvm__conf ig__db# (virtual router_io) ::get (this, "", "router__io", sigs) ;
if (sigs == null) begin
suvm_fatal("CFGERR" , "Interface for Driver not. set");
end
endfunction: build_phase

virtual function void start_of_simulation_phase (uvm__phase phase);


super .start_of_simulation_phase (phase);
suvm_info ("TRACE", $sf ormatf ("%m" ), UVMJIGH) ;
suvm_info ("DRV_CFG" , $sf ormatf ("port_id is : %0d" , port_id) ,
UVM__ME DIUM);
endfunction: start__of__simulation__phase

virtual task run_phase (uvm_phase phase);


'uvm__info ("TRACE", $sformatf ("%m" ), UVMJIIGH) ;

forever begin
seq_item_port.get„next__item (req) ;
if (port__id inside { -1, req.sa }) begin
send(req);
'uvm„info("DRVJRUN" , {"\nn, req.sprint() }, UVM_MEDIUM) ;
end
seq__item__port.item__done () ;
end
endtask: run_phase

virtual task pre__reset_phase (uvm_phase phase);


super .pre__reset_jphase (phase) ;
suvm_info ("TRACE", $sformatf("%m"), UVMJIIGH);
phase .raise_objection (this);
if (port__id == -1) begin
sigs .drvClk .frame_n <= 1x;
sigs .drvClk .valid_jn <= 1x;

Lab 4»18 Component Configuration


SystemVerilog UVM Workshop
Answers / Solution

sigs .drvClk. din <- f:x;


end else begin
:sigs.drvClk.frame_n[port_id] <= rx;
sigs:. drvClk.valid_n [port_J-d] <= rx;
sigs drvClk .din [port_id] •<='■ *x ;
end
phase, drop_ob jection (this );
endtask: pre_reset_phase

virtual task reset_phase (uvm_phase phase);


super.reset_phase(phase) ;
'uvm„info ("TRACE”, $sf ormatf ("%m!!), UWL.HIGH) ;
phase.raise_objection(this);
if (port__id == -1) begin
sigs.drvClk.frame_n <= ’1;
sigs .drvClk .valid__n <= 11 ;
sigs.drvClk.din ■<= !0;
end else begin
:sigs .drvClk .frame_n [port__Id] <— M;
sigs .drvClk .valid_n [port__id] <= 11;
sigs.drvClk.din[port_id] <= f0 ;
'.end
phase. drop__object ion (this);
endtask: reset__phase

//
// See file* for device drivers
S lK I S l^
endclass: driver

Component Configuration Lab 4-19


SystemVerilog UVM Workshop
Lab 4 Answers / Solutions

reset__sequence. sv Solution:

class reset_.tr extends uvm_seque n ce_item;


typedef enum {ASSERT, DEASSERT} kind_e;
r and kind_e ki nd;
V-rand int unsigned cycles = 1; "

vuvm_ob ject__utils_begin :(reset__tr)'


suvm_f ield___enum (kind__e, kind,
"uvm_f ield_int (cycles, UVM_ALL_ON).■
siaym_pb ject_u 111 s_e nd

function new (string name '= !lreset_tr ”.);


■; super .new (name);
'uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
endfunction: new
endclass

class reset„sequence extends uvm__sequence # (reset_tr);


'uvm_object_utils (reset_sequence)

function new(string name = "reset_sequence");


super.new(name);
'uvm_info("TRACE" , $sformatf("%m"), UVMJHIGH);
endfunction

task body();
suvm_info("TRACE", $sformatf("%m"), UVM_HIGH);

if (starting_phase != null)
starting._pb.ase .raise_ob jection (this);

'uvm_do_with(req, {kind == ASSERT; cycles == 2;});


suvm_do__with (req, {kind == DEASSERT; cycles == 15;});

if (starting_phase != null)
starting_phase.drop_objection(this);
endtask

endclass

Lab 4 “20 Component Configuration


SystemVerilog UVM Workshop
Monitors and
Scoreboard

After completing this lab, you should be able to:


• Develop a bus monitor with TLM analysis port
• Add the bus monitor to agent
• Implement a scoreboard using
uvm_in_order_class_comparator
• Add scoreboard and an array of agents to the
environment
• Compile and simulate

Lab Duration
60 minutes

Monitor and Scoreboard Lab 5-1


Synopsys 40-1-054-LG-003
Lab5

hh■ *0m«m1
Getting Started

check.

Constrainable Many runs,


Random Stimulus different seeds
Generation
Directed
Add/Change Testcase Functional
constraints Coverage

Identify
Modifications holes

program automatic test;


// class definitions
initial begin
run_test();
end
endprogram

i.,......... j.. ... . ............................... .

........

DUT
wmmU

Lab 5-2 Monitor and Scoreboard


SystemVerilog UVM Workshop
Lab 5

Lab Overview

The work flow for this lab is illustrated as follows:

Figure 2. Lab 5 Flow Diagram

Monitor and Scoreboard Lab 5-3


SystemVerilog UVM Workshop
Lab 5

Implement Monitors and Scoreboard

You have now driven the test stimulus sequence through the DUT.

In this lab, you will add self-checking into the environment.

Task 1. Go into Iab5 Working Directory

1. CD into the lab5 directory


> cd ../Iab5

Task 2. Implement TLM Analysis Port in Monitor

Monitors and drivers have similarities and differences.

Similarities: both need access to DUT virtual interface. For the labs in this
workshop, both need to be configured to handle a specified port of the DUT.

Differences: driver has a built-in TLM port for communication with the sequencer,
but monitors require the implementer to create the required TLM port(s).

Two monitor types will be needed for the lab, one for monitoring the input to the
DUT and one for monitoring the output of the DUT. The input monitor is called
iMonitor. The output monitor is called oMonitor.

In this task, you will implement TLM analysis port in the input monitor. The
physical device drivers and the fields identical to the driver are coded for you.

1. Open iMonitor. sv file in an editor


2. Inside the class, add a T L M analysis port object handle typed to packet

class iMonitor extends uvm_jnonitor;


virtual router_io sigs;
int port_id = -1;
uvm_analysis_port # (packet) analysis_jport;

3. In the build phase, construct the anaylsis port object

virtual function void build_phase(uvm_phase phase);


super.build_phase{phase);

analysis_port = new("analysis_port", this);


endfunction

Note: TLM ports in UVM do not have factory support. You cannot
construct the TLM port with the proxy create () method. You
must construct it with the constructor new ().
Lab 5-4 Monitor and Scoreboard
SystemVerilog UVM Workshop
Lab 5

4. Locate the forever loop in the run phase


Inside the forever loop, you need to call the device driver to re-construct the
packet that was observed on the DUT physical signals. Then, use the TLM
analysis port to pass it on to all other components requiring the observed
transaction.
5. Do the following inside the forever loop:
• Construct the packet object (tr) to store the observed transaction
• Set the source address (sa) field of the packet object to port_id
(The destination address (da) field will be populated by the device driver)
• Call get_packet () method (device driver) to retrieve the observed
transaction
• Use uvm_inf o macro to display the content of the observed transaction
• Pass the observed transaction to all interested components via the TLM
analysis port

iSiiiilil:!:::I®#!:iyyyt;lSi|^^ j | ^11y ^ : | i : ^ ;y: i::::

forever begin
tr = packet::type_id: :create ("tr", this);
tr.sa = this.port_id;
get_packet(tr);
'uvm_info("Got Input Packet", ("\n", tr.sprint ()>, UVMJMEDIDM) ;
analysis_port.write(tr) ;

endtask

6. Save and close the file.

Task 3. Update Agent___________________________

The input_agent class currently only contains a sequencer and a driver. You
need to add a monitor to the agent to complete the class definition.

1. Open input_agent.sv file in an editor


2. Include the iMonitor.sv file
3. Add the following to the class:
• An instance of iMonitor called mon
• An instance of uvm_analysis_port # (packet) called
analysis_port

Monitor and Scoreboard Lab 5-5


SystemVerilog UVM Workshop
Lab 5

Agents can operate in one of two possible modes: active or passive. When
configured to operate in the active mode, all three members (sequencer, driver and
monitor) must be constructed. If the agent was configured to operate in the passive
mode, only the monitor will be constructed. In the active mode, the sequencer's
TLM port also need to be connected the driver's TLM port.

In the uvm_agent base class, the is_active flag is built in for this purpose.
You will construct and connect the sub-component based on the state of this flag.

4. In the build_phase () method check the state of the is_active flag


• If flag is UVM_ACTIVE create and configure the sequencer (seqr) and
driver (drv) objects
5. Regardless of the state of is_active flag, construct and configure the
monitor (mon) object.
6. In the connect_phase () method, again, check the is_active flag
• If is_active flag is UVM_ACTIVE, connect the driver’s TLM port
(seq_item_port) to sequencer’s TLM port (seq_item_export)
7. Regardless of the state of is_active flag, assign the agent's analysis port to
reference the monitor's (mon) analysis port
8. Save and close the file

Task 4. Update Environment & Test to Enable All Ports

The existing environment only has one instance of the agent. Whereas the DUT has
16 ports that need to be tested. In this task, you will change the single instance of
the agent in the environment to an array o f 16 agents. Because there are 16
individual agents, they will each need to be configured to a dedicated port.

1. Open the router_env.sv file in an editor


2. Change the single instance of input agent to an array of 16 agents
3. In the build phase, do the following:
• Change the construction of the single instance of agent to construct each
agent within the array
• For each agent, set a dedicated port_id value for its members
• Finally, for each agent, configure the sequencer’s default_sequence
to packet_sequence
4. Save and close the file
5. Open the test_collections .sv file in an editor
6. In the build phase change the configuration to configure all input agents to
use the correct router_io.
7. Save and close the file.

Lab 5-6 Monitor and Scoreboard


SystemVerilog UVM Workshop
Task 5. Compile and Simulate

1. Compile and simulate the testbench


> make

You should see that 160 packets were processed (16 ports X 10 items each)

Task 6. Implement Basic Scoreboard______________

UVM has minimal scoreboard support. Here you will try out the bare bone
scoreboard implemenation.

1. Open the scoreboard, sv file in an editor


2. Inside the class, add an instance of uvm_in_order_class_comparator:
In-order comparator typed
class scoreboard extends uvm_scoreboard; to check packet objects
uvm_in_order_class_comparator # (packet) comparator; '

You will need two TLM analysis exports to bring in packets from the input
monitor and the output monitor.
3. Add the following TLM exports: Passing iMonitor
packet to comparator
uvm_analy sis__export # (packet:) be£ore_export;
uvm_analysis_export # (packet) a£ter_export ; Passing oMonitor
packet to comparator
4. In the build phase, construct the comparator and set the analysis exports to
reference the comparator’s ports:

virtual function void build_phase(uvrnjphase phase);


super .build_phase (phase) ;
Nuvm__inf o ("TRACE" , $sf ormatf (n%m,T), UVM_HIGH) ;
comparator = uvm_in_order_class_coinparat or# (packet) : :type_id: :create ("comparator", this);
be fore_export = comparator.be fore__@xport;
illlllllllll^^
endfunction

5« Save and close the file

Task 7. Update the Environment Class

1. Open router_env.sv file in an editor.


For the scoreboard to work, you will also need an agent at the output of the
DUT. This is done for you. It is the output_agent class.

Monitor and Scoreboard Lab 5-7


SystemVerilog UVM Workshop
jib 5

2. Add include statements for the s c o r e b o a r d . sv and output___ag@ nt. s v


files

'include 11scoreboard.sv"
Ninclude "output_agent.sv”

3. Inside the environment class, add an instance of s c o r e b o a r d and an array


of o u tp u t_ _ a g e n ts

output_agent o„agent [16] ;

4. In the build phase do the following:


• Construct the s c o r e b o a r d and the output___agent objects
® Configure the o u tp u t_ a g e n t objects to dedicated port

virtual function void build_phase (uvm_phase phase);

sb - scoreboard: rtype__id::create ("sbfff this) ;


foreach (o__agent [i]) begin
o_agent [i] - output_agent::type__id: :create ($sformatf (no_agent [%0d] ” ,i) ,this) ;
uvm_config_db # (int) ; :set (this, o_agent [i] .get_name () , r,port_idrf, i) ;

endfunction

5. In the connect phase, connect the scoreboard to the agents’ analysis ports:

virtual function void connect„phase(uvm_phase phase);


'uvm„inf o ("TRACE ", $sf ormatf (11%m"), UVMJiIGH) ;
foreach (i_agent [i]) begin
i__agent [ij *analysis__port.connect (s b .before„export);

£oreach (o„agent [i]) begin


o_agent [i] .analysis_port.connect (sb.after_export) ;

endfunction

6. Save and close the file


7. Open the t@ s t_ _ c o lle c tio n . s v file in an editor
8. In build phase of te s t_ _ b a se class add configuration statements to
configure all output agents to use the correct router__io.
9. Save and close the file.

Lab 5-8 Monitor and Scoreboard


SystemVerilog UVM Workshop
Task 8. Compile And Debug The Program

1. Compile and run the simulation


> make
You should see something like the following message at end of simulation:

** Report counts by id
[Comparator Match] 153
[Comparator Mismatch] 6
[DRV_RUN] 160

[MISCMP] 12

The simulation is reporting that 160 packets were detected in the input but only 159
packets were observed at the output.

(Ignore the Mismatches for now. It will be solved in a coming Step.)

This is the expected behavior. The cause of the missing output is due to the latency
of the transaction flowing through the DUT. Since the objection were only raised
and dropped on the input side, as soon as the input is done, as far as the UVM
simulation is concerned, everything is done because there are no existing objections.

This is a common problem in UVM testbench. There are multiple ways to solve this
problem. One can add objection mechanisms to the monitors, but it will be costly in
terms of performance.

One way to correct this is to take care of the expected latency on the input side by
implementing an objection drain time. If an objection drain time is set, then when
the objection count reaches 0, the phase must wait for the drain time to elapse before
terminating the phase. If another objection is raised during the drain time, the phase
objection mechanism starts over and waits for objection count to reach 0 again.

2. Open the packet_sequence .sv file


3. In the body () method, retrieve the objection handle for the phase, then set
drain time to lus. This should be sufficient for the lab DUT.

virtual task body();

if (starting_phase != null) begin


uvm_objection objection = starting_phase.get_objection ();
objection.set_drain_time (this, lus) ;
starting_phase.raise_objection(this);

Monitor and Scoreboard Lab 5-9


SystemVerilog UVM Workshop
4. Save and close the file
5. Compile and run the simulation again:
> make

You should see all 160 packets on the output observed.


However, due to the basic nature o f the UVM comparator and scoreboard, you
should also see that there are mismatches.

** Report counts by id
::::Mfttp:ar:;at:t;ii§:|K:ft;- J ; : ® # : ::W;::ii-n^ :^ ::C;:;;:::;^ ;;:K■;:i];ii;!:Iv'
[Comparator Mismatch] 6

[Got Output Packet] 160

[Scoreboard Report] 1

Is this a testbench problem or a DUT problem? One way to isolate the


problem is to just test one port.
6. Compile and run the simulation on destination address 3:
> make test=test_da_3_seq

You should see that 320 packets (20 packets per input port) were successfully
matched. If you see other error, then you have made a mistake in your
testbench code that needs to be corrected.
If it passes, what’s the problem? The problem is that UVM only provides a
mechanism for checking in-order sequence comparison. The DUT you are
testing can have simultaneous input and output packet observed at different
ports. Which one of these output packet will be checked against the input
packet? It is non-deterministic. Thus the lab problem arises.
Again, this is a common problem in UVM testbenches.
How can one solve this problem? I f the sequence is truly out-of-order, then
one must write an out-of-order scoreboard from scratch. If the sequence is in-
order, but, there are multiple streams of in-order sequences at the same time,
then the UVM’s uvm_in_order_class_comparator class can still be
used to implement a multi-stream scoreboard.
A multi-stream scoreboard has been coded for you. Try it out in the next step.
7. Open the router_env.sv file in an editor
8. Replace the include statement for scoreboard.sv with an include
statement for ms_scoreboard.sv
9. Save and close the file

Lab 5-10 Monitor and Scoreboard


SystemVerilog UVM Workshop
Task 9. Compile And Simulate

1. Compile and simulate the testbench.


> make
All should now match!
You can verify that there are activities in the DUT with DVE.
2. Open DVE with the following command:
> make dve
You should see that packets were driven through the DUT.
3. Run the destination address is 3 and 20 packets test:
> make test=test_da_3_seq
4. Take a look at DVE again
You should see that 320 packets were driven through port 3.

Congratulations, you have completed Lab 5!

Monitor and Scoreboard Lab 5-11


SystemVerilog UVM Workshop
Lab 5 Answers / Solutions

A n sw e rs / S o lu tio n s
test.__collection.sv Solutions
class test„base extends uvm_test;
\uvm_component__utils (testjoase)

router__env env;

function new(string "name, uvm„component parent) ;


super.new(name, parent);
"uvm__info (flTRAGEfry-$sf ormatf ("%m”), :UVM__HIGH);
endfunction

virtual function void build_phase(uvm_phase phase);


super .build_jphase (phase) ;
'uvm__info ("TRACE” , $sf ormatf (”%m”), UVM_HIGH) ;
env - router_env::type__id::create ("env”, this) ;

uvm_conf ig_db# (virtual router_io) : :set (this, "env.i_agent [* ]”,


"router__io" , router__test__top .sigs );

uvm__conf ig__db# (virtual router__io) : :set (this , "env.o__agent [* ]",


"router_io" , rout er_test_top .sigs );

uvm__conf ig_db# (virtual router_io) : :set (this, ”env.r_agent",


"router__io" , router_test_top .sigs );
endfunction

virtual function void final_phase(uvmjphase phase);


super .final__phase (phase);
'uvm__inf o ("TRACE" , $sformatf (”%m" ), UVMJiIGH) ;
uvm_top.print_topology () ;

factory.print();
endfunction
endclass

// Other code left out. See file for content.

Lab 5-12 Monitor and Scoreboard


SystemVerilog UVM Workshop
Answers / Solutions Lai

router„env.sv Solution:

class router___env extends: uvm__env;


input_agent :i__agent [16 ] ;
scoreboard sb;
output__agent o___agent [16 ];
reset__agent r__agent;

suvm_component__utils (router__env)

function new (string name, uvm_component parent);


super.new(name, parent);
suvm__inf o ("TRACE" , $sformatf (11%m" ), UWTHIGH) ;:
endfunction

virtual function void build__phase (uvm__phase phase);


super .build__phase (phase) ; .
suvm__i:nfo ("TRACE" , $sf ormatf (!,%m" ), UVM__HIGH) ; ::
foreach (i__agent [i ]) begin
i__agent [i ] = input__agent ::type__id ::create ($sf ormatf (" i„_agent [%0d] ",
i), this);
uvrn_conf ig__db # (int)::set (this, i_agent [i ] .get_name () , "port_id" ,
i);
uvm__config„db # (uvm__object__wrapper) ::set (this,
{i__agent [i] .get__name () , " .", "seqr .mainjphase" }, "def ault„sequence" ,
packet__sequence::get__type () );
■:''::e :::

sb = scoreboard::type__id::create ("sb", this);


foreach (o_agent[i]) begin
o__agent [i] =
output_agent::type_id::create ($sformatf("o_agent[%0d]", i), this);
uvm_config_db #(int) ::set(this, o_agent[i] .get_name(), "port__id",
1) ;
end

r__agent = reset__agent::type_id::create ("r__agent ”, this);


uvm_conf ig_db # (uvm_ob ject_wrapper ) ::set (this,
"r_agent.seqr .reset_phase ", "default_sequence" ,
reset__sequence ::get_type () );
endfunction

virtual function void connect_phase(uvm_phase phase);


'uvm_inf o ("TRACE" , $sf ormatf (”%m" ), UVM__HIGH) ;

foreach (i__agent [i ]) begin


l__agent [i ] .analysis_port.connect (sb. bef ore__export);
end
foreach (o_agent[i]) begin
o_agent [i] .analysis_port.connect (sb. after__export) ;

endfunction

endclass

Monitor and Scoreboard Lab 5-13


SystemVerilog UVM Workshop
Answers / Solutions

in p u t _ a g e n t . s v Solution:

typedef uvm^sequencer # (packet) packet__sequencer;

c1ass inpu t_a gen t ext ends uvm_agen t ;


virtual; router__io:sigs ; . // 0 U T :virtual inter face
int port__id = -1; II Agent rs designated port
packet_sequencer seqr;
driver drv;
iMonitor mon;
uvm__analysis_port # (packet) analysis__port ; : :

'uvm^componentmutils„begin(input__agent) ::
Nuvm_f ieldjnt (porf__id, UVMJDE FAULT | UVM„DEC)
suvm_eomponent_ut ils__end

function new(string name, uvm_component parent);


super.new(name, parent);
suvm__info ("TRACE’1, $sf ormatf ("%m" ), UVMJIGH) ;
endfunction

virtual function void build_phase (uvm_phase phase);


super ,build__phase (phase) ;
'uvm_info( "TRACE", $sf ormatf ("%m" ), UVM_HIGH) ;

uvm_conf ig__db# (int) ::get (this, "", "port__id" , port__id) ;


uvm_conf ig_db# (virtual router_io) :: get (this , "", "r outer__io" , sigs) ;

if (is__active == UVM__ACTIVE) begin


seqr = packet_sequencer ::type_id: :create ("seqr" , this) ;
drv = driver ::type__id::create ("drv" , this) ;
uvm__conf ig_db# (int) : :set (this, "drv", "port__id" , port_id) ;
uvm__conf ig_db# (int) : :set (this, "seqr ", "port__id" , port_id) ;
uvm_conf ig__db# (virtual router_io) : :set (this, "drv", "router__io" ,
sigs);
uvm__config__db# (virtual router„io) : :set (this, "seqr", "router_io",
sigs);

mon = iMonitor::type„id::create("mon", this);


uvm_conf ig_db# (int):: set (this, "mon”, "port_id" , port__id) ;
uvm_conf ig__db# (virtual router„io) ::set (this, "mon", "router__io" ,
sigs);
endfunction

virtual function void connect„phase (uvm__phase phase);


super *connect„phase (phase);
Nuvm_JLnfo ("TRACE", $sformatf ("%m" ), UVMJHIGH) ;

if (is_active == UVM__ACTIVE) begin


drv. seq_item__port,connect (seqr .seq_item_export);

this .analysis_port = mon .analysis__port;


endfunction

endclass

Lab 5-14 Monitor and Scoreboard


SystemVerilog UVM Workshop
i M o n i t o r . sv Solution:

class iMonitor extends uvm_monitor;


virtuai router_io sigs;
int' port__id = -I;
uvm__analysis_port # (packet) analysis__port;

suvm_component_utils_begin (iMonitor)
suvm_fie.ld_int (port_id, UVM_DE FAULT | UVMJDEC)
vuvm_component_utils__end

function -new(string name, uvm_component parent);


super.new(name, parent);
'uvm__inf o ("TRACE", $sformatf("%m"), UVM_HIGH);
endfunction

function void build___phase (uvm__phase :phase);; ;


super.build__phase (phase) ;
suvm_info("TRACE", $sformatf;(ff%m!f), UVM___HIGH) ;-
if (! uvm___conf:ig__db# (int):: get (this , fTff, "port__id" , port__id) ) begin
■ uvm__fatal ("CFGERR" , "iMonitor port__id not:set !:r;)/: ;^
end
if (! uvm„config„db# (virtual router__io) ::get (this, fllf, 11router„io" ,
sigs)) begin
'uvm__fatal("CFGERR", "iMonitor DUT interface not set") ;
end
analysis_port = new("analysis_port", this);
endfunction

virtual task run_phase (uvm__phase phase);


packet tr;
'uvm__info ("TRACE" , $sf ormatf ("%m" ), UVM_HIGH) ;
forever begin
tr = packet::type_id::create("tr", this);
tr .sa = this .port__id;
get_packet(tr);
"uvm_info("Got Input Packet”, {"\n", tr.sprint()}, UVM__MEDIUM);
analysis_port.write (tr);
end
endtask

//
// See file for the device driver code

endclass

Monitor and Scoreboard Lab 5-15


SystemVerilog UVM Workshop
Lab 5 Answers / Solutions

oMonitor. s v Solution;

class oMonitor extends uvm_monitor;


'ifndef OMONITOR__SV
'define OMONITOR__SV

class oMonitor extends uvm__monitor;


int port__id = -1;
virtual ro:uter_io sigs;
uvm__anaTysis_port # (packet) analysis__port;

suvm_component__utils_begin (oMonitor)
suvni^field„int (port_id, UVI^LDEFAULT 0:
\uvm_component__utils_jend '

function ,new:
(string name, uvm_component parent):; ::
super.new(name, parent);
'uvm„info("TRACE", $sformatf ("%m" ), UVM__HIGH) ;
:
en:
dfunction

function void build_phase (uvm_phase phase) ;


super .build_phase (phase) ;
if (!uvm_conf ig_db# (virtual router_io) : :get(this, " ", "router_io" ,
sigs)) begin
'uvm_fatal("CFGERR", "oMonitor DUT interface not set");
,end
analysis_port = new ("analysis_port ", this);
endfunction

virtual task run_phase(uvm_phase phase);


packet tr;
suvm_info( "TRACE", $sf ormatf (" %m" ), UVM__HIGH) ;
forever begin
tr = packet::type_id::create ("tr ", this);
tr.da = this.port_id;
this.get_packet(tr);
'uvm__info ("Got Output Packet" , {"\n" , tr .sprint () }, UVMJMEDIUM) ;
analysis_port.write(tr);

endtask

// See file for the device driver code

endclass

Lab 5-16 Monitor and Scoreboard


SystemVerilog UVM Workshop
Lab 5

scoreboard, sv Solution

class scoreboard extends uvm„scoreboard;


uvm_i n_or de r_c la ss_c ompar at or #( packet) comparator ;
:uvm_analysis_export # (packet) bef or e_e.xport;
uvm__analysis__export # (packet) after_export;

xuvm__component__utils (scoreboard)

function new (string name, uvm_component parent);


super.new(name, parent);
'uvm_info ("TRACE”, $sf ormatf (”%m"), UVMJIGH) ;
endfunction

virtual function void build_phase (uvm_phase phase);


super.build_phase(phase);
'uvm_info ("TRACE”, $sformatf(”%m"), UVMJIGH) ; ^

comparator =
uvm_in_order_class_comparator# (packet) ::type_id ::create ("comparator ”, this);
bef ore_export = comparator .bef ore_export;
after__export : = comparator ,after„export;
endfunction

virtual function void report_phase (uvinjphase phase);


'uvm_info("TRACE", $sformatf ("%m" ), UVMJHIGH) ;
Nuvm_info("Scoreboard Report",
$sf ormatf ("Comparator Matches = %0d, Mismatches = %0d”,
comparator ,m__matches, comparator .m_mismatches), UVM__MEDIUM) ;
endfunction

endclass

Monitor and Scoreboard Lab 5-17


SystemVerilog UVM Workshop
La» a Answers I Solutions

ms_s c o r e b o a r d , sv Solution

'uvm__analysis__imp__decl (_before)
suvm_analysis_imp_decl (_after)

class scoreboard extends uvm_scoreboard;


uvm_analysi s_imp„before # (packet, scoreboard) before_export;
uvm_analysis___imp__af ter # (packet, scoreboard) after_export;
uvm_in_order_class_comparator # (packet) comparator [16 ];

.8u-ym_eomp9 n.ent_ut.ilS:(.scoreboard)'

function new(string name, uvm__component parent);


super.new(name, parent);
'uvm_info ("TRACE1’, $sformatf ("%m") , UVMJIGH) ;
endfunction

: virtual function void build_phase (uvrn__phase:phase)


: super .build___phase (phase);
Kuvm__info ("TRACE", $sf ormatf ("%m" ), UVM_HIGH) ;
bef ore_export = new ("bef ore_export ", this);
af ter__export = new (" aft ereexport", this);
for (int i=0 ; i < 16; i++) begin
comparator [i] = new($sformatf("comparator^Od", i) , this);
end
endfunction

virtual function void write__bef ore (packet pkt);


suvm__inf o ("TRACE" , $sf ormatf ("%m" ), UVM_HIGH) ;
comparator[pkt.da] .before_export.write(pkt);
endfunction

virtual function void write_after(packet pkt);


suvm_info ("TRACE", $sf ormatf ("%m" ), UVMJIGH) ;
comparator[pkt.da] .after_export.write(pkt) ;
endfunction

virtual function void report ();


'uvm__info ("TRACE", $sf ormatf ("%m" ), UVM_HIGH) ;
foreach (comparator[i]) begin
'uvm_info("Scoreboard Report",
$sformatf("Comparator[%0d] Matches = %0d, Mismatches = %0d" ,
i, comparator [i ] ,m_matches, comparator [i ] .m__mismatches),
UVM__ME DIUM);
end
endfunction

endclass

Lab 5-18 Monitor and Scoreboard


SystemVerilog UVM Workshop
Sequence Library

After completing this lab, you should be able to:


• Develop a sequence library
• Modify environment to be configurable
• Implement tests to use sequence library and
environment configuration
• Compile and simulate

J?*? Lab Duration:


YY 30 minutes

Sequence Library Lab 6-1


Synopsys 40-I-054-LG-003
Lab 6

Getting Started

Through the first five labs, you have developed a complete verification platform to
ise the DUT. In the next two labs, you will expand the testbench to add greater
ity for even more productivity.
'''■ ■ ■ • ''. .- ■■■' -.
Constrainable Many runs,
Random Stimulus
Generation
Directed
Add/Change jf^Testcase
constraints

Identify §
Modifications holes f

program automatic test;


// class definitions
initial begin
run_test();
end
endprogram

Environment class

Agent

Driver Monitor

Lab 6-2 Sequence Library


SystemVerilog UVM Workshop
Lab Overview

The work flow for this lab is illustrated as follows:

Figure 2. Lab 6 Flow Diagram

Sequence Library Lab 6-3


SystemVerilog UVM Workshop
Lab 6

Sequence Library

You now have a complete self-checking verification environment. How can you
raise the productivity of the verification environment even higher? One way to do
this is to create a sequence library that can be reused through integration of blocks
and across projects.

Task 1. Go into Iab6 Working Directory

1. CD into the lab6 directory


> cd ../Iab6

Task 2. Implement Base Sequence Library

A sequence library is a collection of sequences packaged so that these sequences


can be reused across integration levels and across different projects.

1. Open packet seq lib p k g .sv file in an editor


For classes to be reused across integration and projects, the proper place to put
them is inside a package.
2. Create a package called packet_seq_lib_pkg
3. Inside the package, import the uvm_pkg package

package packet seq lib pkg;


import uvm_pkg::*;

4. Create the packet sequence library class as follows:

'uvm_object_utils (packet seq lib)


'uvm_sequence_library_utils (packet_seq_JLib)
function new (string name = "packet_seq_lib");
super.new(name);
'uvm_info("TRACE", $sformatf("%m") , UVM_HIGH) ;

endfunction

A sequence library, typed to a particular sequence item, structurally always


looks the same. Notice that there are no sequence registered in the library.
For this lab, the sequences needed by the tests will be registered into the
library on a test by test basis. If there are common sequences that's required
by all tests when using the library, then these sequences can be included in the
package and registered into the library.
5. Save and close the file

Lab 6-4 Sequence Library


SystemVerilog UVM Workshop
Task 3. Modify Sequence to reside in Sequence Library

In this task, you will prepare the existing packet sequence for possible registration
into the sequence library.

1. Open packet_sequence .sv file in an editor


Because the packet class is now inside the packet sequence library package,
you no longer need the include statement for packet.sv file. But you will
need to import the package to get access to the class definition.
2. Delete the ' include "packet. sv" statement and replace it with an
import of the packet sequence library package:

// 'include "packet.sv"
import packet_seq_lib_pkg::*;

Up to now, you have executed sequences by configuring the sequencer to


execute the sequence of choice via the def ault_sequence configuration
field. When you did that, the sequencer treated the sequence you assigned to
it as the top sequence. When the top sequence is executed, the sequencer will
provide it with the executing phase (starting_phase) information.

But, when a sequence is inside a sequence library, that sequence is no longer


the top sequence. It is a child sequence of the sequence library. Because of
this, the sequence no longer has access to starting_phase by default.
You need to fetch the starting_phase from the parent sequence.
3. In the body () method create a handle to reference the parent sequence, call
it parent
4. Call get_parent_sequence () method to retrieve the parent sequence
handle
5. If the parent handle is not null, set the starting_phase to the parent
sequence’s starting_phase
When done, your code should look like the following:

virtual task body();


uvm_sequence_base parent;
Nuvm„inf o ("TRACE1’, $sf ormatf ("%m" ), UVMJiIGH);
uvm_conf ig_db# (int): :get (m_sequencer,"lr,nitem_count11fiterrucount);
parent, = get_parent_sequence {) ;
if (parent !« null) begin

Sequence Library Lab 6-5


SystemVerilog UVM Workshop
,ab 6

If you do not add the above code, you will find that when you execute this
sequence from the sequence library, the starting_phase will be null.
Therefore, phase objection will not be available for setting the drain time.
The potential consequence is that the final outputs of the DUT may not be
observed.
6. Save and close the file

Task 4. Update Environment to Use Sequence Library

1. Open the router_env.sv file in an editor


2. In build_phase () configure the sequencer’s def ault_sequence to
use packet sequence library (packet_seq_lib) instead of packet sequence
(packet_sequence)

3. Save and close the file

Task 5. Update Test to Use Sequence in Library______

Up to this point, you have created the sequence library and set the sequencers to
execute the sequence library. However, there is currently no sequence registered
with the sequence library. If you were to run the test now, nothing will happen.

In this task, you will add the packet_sequence to the sequence library.

1. Open the test_collections .sv file in aneditor


2. In build phase, register packet_sequence in the sequence library with:

virtual function void build_phase (uvm_phase phase)';

endfunction

3. Save and close the file

Task 6. Compile and Simulate____________________

1. Compile and simulate the testbench


> make

You should see that 1600 packets were processed. The reason that you are
seeing 10 times more transaction than you did before is because the sequence
library executes 10 of its registered child sequences by default. (10 sequences
X 16 ports X 10 items each) This can be changed.

Lab 6-6 Sequence Library


SystemVerilog UVM Workshop
Lab 6

Task 7. Configure the Sequence Library in Test _____

To configure the sequence library to execute n number of sequences and to set the
execution type, you will use the uvm_sequence_library_cfg class.

1. Open the test_collection .sv file in an editor


2. Create a test class called tes t _seq__lib_cf g and declare a
uvm_sequence__library_cfg instance, call it seq_cfg

class test_seq_lib_cfg extends t e s t j b a s e ;


uvm_sequence_library__cfg seq_cfg;
Nuvm__component__uti 1 s (test_seq_lib_cfg)
function new(string name, uvm_component parent);
super.new (name, parent) ;
endfunction

3. In the build phase do the following:


• Constructed the s e q _ c f g object to set UVM SEQ LIB RAND mode and
the max_random_count and min_random_count to 1
• Configure sequence library’s configuration to use the content of seq ^ c fg :

virtual function void build phase (uvm_phase phase) ;


super.build_phase (phase) ;
seq__cfg = new ("seq_cfg", UVM SEQ LIB RAND, 1, 1) ;
uvm__config_db # (uvm„sequence„library„cfg) : :set (this,
"env. i__agent* .seqr,main_phase”, "default_sequence.confign, seq_cfg) ;
endfunction
endclass

4. Save and close the file

Task 8. Compile And Simulate____________________

1. Compile and simulate the testbench.


> make test=test_seq_lib_cfg
You should see that 160 packets were driven through the DUT once again.
With the sequence library, you can quickly build up a collection of tests to
focus on what need to be verified.

Congratulations, you have completed Lab 6!

Sequence Library Lab 6-7


SystemVerilog UVM Workshop
Lab © Answers I Solutions

Answers / Solutions
t e s t _ c o l l e c t i o n . sv Solution:

class tes€__.seq_„lib__cfg extends test__base';


uvm_sequence__.library__.cfg seq__cfg;
suvm___Gomponent__utils (test_seq__lib_cfg)
function new(string name, uvm_component parent);
super.new(name, parent);
■endfunction

virtual function void build_phase.(:uvm_phase phase);


super.build_pha.s-e(phase) ;
seq_„cfg - new ("seq_cf g" , UVM__SEQ_LIB__RAND, 1, 1) ;
uvm___config_db # (uvm_sequence„library_cfg) :: set (this,
"env.i_„agent* .seqr ,mainj?hase11, "def ault__sequence .config", seq_cfg) ;
endfunction
endclass
packet__seq_lib_jpkg. s v Solution:

package packet_seq__lib_pkg;
import uvrnjpkg::* ;

class packet extends uvm_sequence_item;


rand bit [3:0] sa, da;
rand bit [7:0] payload[$];

suvm__ob ject_uti 1s__begin (packet)


'uvm_field„int (sa, UVM__ALL__ON + UVM_N0C0MPARE)
suvm_f ie 1d__int (da, UVM_AL L__ON)
'uvm__f ield__queue_int (payload, UVM_ALL„_ON)
suvm_ob je ct__ut i1s__end

constraint valid {
payload.size inside { [1:10] };

function new (string name="packet") ;


super.ne w (name);
'uvm_info("TRACE" , $sformatf("%m"), UVM_HIGH)
endfunction
endclass

class packet__seq_lib extends uvm_sequence__library # (packet);


'uvm__ob jec t_u ti 1s (packet„seq_lib)
'uvm_sequence_library_utils (packet„seq_J_ib)

function new(string name = "packet__seq_lib");


super.new(name);
'uvm__info ("TRACE" , $sf ormatf ("%m" ), UVMJBIGH) ;
init__sequence__library () ;
endfunction
endclass

endpackage

Lab 6-8 Sequence Library


SystemVerilog UVM Workshop
Answer*

p a c k e t _ s e q u e n c e . s v Solution;

import paDke:t^seq_„lib_pkg: :* ; ,
class packet_sequence extends uvm_sequence # (packet);
int itern__count ■= 10;
int port_id = -1
bit [15:0] da__enable = f1
int
vuvm__ob ject___utils__begin (packet_sequence)
■uvm__f ield___int (item_count, UVM_ALL_ON)
;uvmjield„int (port_id, ;UVM_ALL_ON)
suvm_field„int (da_enab 1e, :U¥M_ALL___ON)
suvm_f ield„_.queue__int (valid„da, UVM__ALL^.ON)
Nuvm__ob jeet__utils_end
function void pre__randomize () ;
:uvm_conf ig„db# (int) ::get (m_sequencer, nitem__count",■.'ifcein^QuntO};
uvm_conf ig__db# (int)::get (m_sequencer , "", nport___id", port_id) ;
uvrr^Gonf ig__db# (bit [15 :0]) ::get (irr_sequencer, ""r "da__enable",
da__enable) ;
if (! (port__id inside {-1, [0:15]})) begin
suvm_fatal ("CFGERR" , $sformatf ("Illegal port__id value of %0d",
port__.id) );
end
valid__da .delete () ;
for (int i= 0 ; i<16; i++)
if (da___enable [i ])
valid__da .push_back (i);
endfunction
function new(string name = "packet_sequence") ;
super.n e w (name);
'uvm_info ("TRACE" , $sf ormatf ("%m" ) , UVM_HIGH) ;
endfunction
virtual task body();
uvm_sequence_base parent;
'uvm_info ("TRACE" f $sf ormatf ("%m" ) , UVM„HIGH);
uvm__conf ig_db# (int) ::get (m_sequencer, »* ^ "itern_count", item__count)
parent = get _parent_sequence();
if (parent != null) begin
starting_phase = parent.starting__phase;
end
if (starting_phase i= null) begin
uvm_obj ection objection = starting_phase .get_objection () ;
objection.set_drain_time(this, lus);
starting__phase .raise_ob jection (this) ;
end
repeat(item_count) begin
'uvm__do_with (req, {if (port_id -1) sa inside {[0:15]}; else sa
port__id; da inside valid_da; });
end

if (starting__phase != null) begin


starting_phase.drop_objection(this);
end
endtask
endclass

Sequence Library Lab 6-9


SystemVerilog UVM Workshop
L a b -6 A nsw ers / Solutions

router_env.sv Solution:

cl:asS;:,j:outer_env extends uvm_env;\


7input__agent; i__agent [16 i;
scoreboard sb;
output__agent o__agent [16 ];
reset__agent r_agent;

uvm_component_utils (router_env)

function new (string name, uvm__component parent) ;


super ,new (name, parent );
Nuvm_info ("TRACE", $sformatf ("%m") , UVM__HIGH) ;
endfunction

virtual function void build_phase (uvm_phase phase),;


super .build_jphase (phase) ;
;suvm_info ("TRACE", $sformatf ("%m" ), UVMJIGH) ; ; :v - .

foreach (i__agent [i ]) begin


;i_agent [i ] == input_agent: type_id: :create (:$s>format f;("i^_:agent'[%0d] ",
i), this);
:uvm^_config__db # (int):: set (this, i_agent[i] .get_name () , "port_id" ,
i);
uvm„conf ig__db # (uvm___object_wrapper) ::set (this,
{i__agent[i] .get„name () , " .", "seqr .main__phase" }, "default„sequence" ,
packet_seq__lib ::get_type () );
end

sb = scoreboard::type__id::create ("sb", this) ;


foreach (o__agent [i]) begin
o__agent[i] =
output_agent::type_id::create ($sf ormatf ("o„_agent [%0d] ", i),this);
uvm_conf ig__db # (int)::set (this, o_agent [i] .get_name () , "port__id", .
i) ;
end

r_agent = reset__agent::type_id ::create ("r_agent", this) ;


uvm_conf ig_db # (uvm__object_wrapper ) ::set (this, {r_agent .get_name () ,
" .", "seqr .reset__phase" }, "def ault_sequence" ,
reset_sequence ::get__type () );
endfunction

virtual function void connect__phase(uvm_phase phase);


super .connect„phase (phase);
suvm__info ("TRACE", $sformatf ("%m" ), UVMJSIGH) ;
foreach (i__agent [i] ) begin
i__agent [i] .analysis_port,connect (sb.before„export);
end
foreach (o_agent[i]) begin
o_agent[i] .analysis_port.connect (sb. after__export) ;
lilllSiltllllljSlllflilll^
endfunction

endclass

Lab 6-10 Sequence Library


SystemVerilog UVM Workshop
Register Abstraction
Layer (RAL)

After completing this lab, you should be able to:


• Develop a register configuration sequence without RAL
• Add DUT configuration to environment
• Compile and verify DUT front door configuration
without RAL works correctly
• Implement RAL
• Implement register configuration sequence with RAL
• Modify test to use RAL
• Compile and simulate with RAL

Lab Duration
60 minutes

Register Abstraction Layer (RAL) Lab 7-1


Synopsys 40-I-054-LG-003
,v.v,v.v.v.-.v.v.v.v.-,;.

Constrainable Many runs,


Random Stimulus different seeds
Generation
Directed
Add/Change f^Testcase Functional
;1 constraints |

Modifications

program automatic test ;


// class definitions
initial begin
run_test();
end
endprogram

Environment class

Agent Agent

Host
sequencer

sequence Register

n
Host
Driver
model

Driver Monitor Scoreboard

Figure 1.

Lab 7-2 Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop
Lab Overview

The work flow for this lab is illustrated as follows:

Figure 2. Lab 7 Flow Diagram

Register Abstraction Layer (RAL) Lab 7-3


SystemVerilog UVM Workshop
Implement Register Abstraction

Task 1. Go into Iab7 Working Directory

1. CD into the lab7 directory


> cd ../lab7
In this lab, the DUT has been modified with the addition of configurable registers.
The word width is 16 bits for each register/memory. The address is word address
based (not byte address).

At address 0x0000, two read-only fields exist: chip id (CHIP_ID) and revsion id
(REV_ID). The static values are as shown in the following table.

| HOST_ID Register
| Field CHIP_ID REVJD
1 Bits 15-8 7-0
Mode ro ro
Reset Qx5A 0x03

At address 0x0100, there is a port locking field (LOCK). If a bit has the value of 1,
the corresponding port of the DUT will be disabled. To enable a port, the LOCK bit
must be cleared with a write-one-to-clear. (writing a one to that bit location will
clear the bit). The default value is 16’hffff, meaning that all ports are disabled at
reset. The reading and writing of the field is word based.

PORT_LOCK Register
Field LOCK
Bits 15-0
Mode w1c
Reset Oxff

At address 0x1000 - OxlOFF, there is an array of registers (REG_ARRAY[256]).


These registers can be written and read. The reset values are 16’h0000.

REG_ARRAY[256] Registers
Field HOST_REG
Bits 15-0
Mode rw
Reset 0x00

Lab 7-4 Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop
There is also 4K words of RAM located at address 0x4000 - 0x4FFFF.

RAM (4K)
Bits 15-0
Mode rw

Before proceeding to implement register configuration, compile and simulate the


existing testbench to verify that without register configuration, all ports are locked
and the DUT is, in effect, disabled.

2. Compile and simulate the testbench


> make

You should see that 160 packets were observed at the input, but there were no
observed output! This is the expected behavior. You need to configure the
DUT to unlock the ports.

Task 2. Implement Host Sequence without RAL_____ _

The first step in implementing DUT register configuration is to implement all


components supporting the configuration without RAL.

The host data class is created for you in host_data.sv. It’s pretty simple. It
contains data and address field with two possible kinds of operation: read and write.

class host_data extends uvm_sequence_item;


typedef ervum {READ, WRITE} kind_e;
rand kind_e kind;
rand b i t [15:0J addr;
rand b i t [15:0] data;

endclass

A host agent class is also created for you in host_agent.sv. If interested, you
can examine the file. However, aside from the DUT specific device drivers, it
contain the same things that you have already done in the previous labs. So, there is
not much to gain in going through it in detail.

Register Abstraction Layer (RAL) Lab 7-5


SystemVerilog UVM Workshop
Lab 7

What’s more important is to develop a sequence to configure the DUT PORT_LOCK


register so that the required ports are enabled. You will do this in the next step.

1. Open host_sequence.sv file in an editor


2. In host_bfm_sequence class, create a body () method to do the following:
• Read and print the content of the PORTJLOCK register at address 0x0100.
• Write all one's to the register to enable all ports
• Read and print the content of the register back to verify it is correctly
configured
• Caution: Don’t forget the phase objections!
3. Save and close the file

Task 3. Add Host Components to Environment

1. Open router_env.sv file in an editor


2. Include the host_agent.sv files
3. In the environment, create an instance of host_agent, call it h_agent
4. In build phase, construct the h_agent object with the factory create ()
method
5. Then, configure h_agent’s sequencer to execute host_bfm_sequence at
configure_phase
6. Save and close the file

Task 4. Configure the Host Virtual Interface_________

1. Open test_collection.sv in an editor


2. In test_base class, configure the virtual interface ( "host_io") in
h_agent’scomponent to use router_test_top.host interface
3. Save and close the file

Task 5. Compile and Simulate____________________

1. Compile and simulate the testbench


> make
You should see that 160 packets were successfully processed.
The configuration was correctly done. But, this type of implementation of the
register configuration is not portable across integration and projects because
the addresses are hard-coded.
Using a abstract register to represent the DUT registers can help to make the
configuration sequence portable across integration and projects.

Lab 7-i Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop
Task 6. Create the Register Abastraction (. raif) File

1. Open h o s t .ralf file in an editor


2. Create the RAL register definitions to represent the following set of registers
and memory in the h o s t .ralf file
Hint: reference the lecture slides for Step 2.
For this task, just populate the register and memory field definitions. The
block definition is done for you in the file. The system definition is not
necessary for this lab. (You are verifying the DUT at the block level)

Mode HOSTJD Register


Field C HIPJD REVJD
ro Read Only
Bits 15-8 7-0
rw Read/Write
Mode ro ro
w1c Write 1 clears field
Reset 0x5A 0x03

PORT_LOCK Register
Address Map
Field LOCK
HO STJD 0x0000 15-0
Bits
PORTJLOCK 0x0100 Mode w1c
REG_ARRAY 0x1000-0x1 OFF Reset Oxff

RAM 0x4000-0x4FFF REG_ARRAY[256] Registers


Field HOST_REG
Bits 15-0
Mode rw
Reset 0x00

RAM (4K)
Bits 15-0
Mode rw
Save and close the file when done

Task 7. Generate UVM Register Classes___________

1. Convert the RAL file content into UVM register classes with ralgen:
> ralgen -uvm -t host_regmodel host.ralf
You should see a file called ral_host_regmodel.sv created by ralgen.
If interested, take a look at the content. Otherwise, continue on to the next
task.

Register Abstraction Layer (RAL) Lab 7-7


SystemVerilog UVM Workshop
Lab 7

Task 8. Create Sequence Using UVM Registers

1. Open host_sequence.sv file in an editor


2. Include the ral_host_regmodel.sv file
3. Locate the RAL sequence class called host_ral_sequence
4. Inside the class, create an instance o f ral_block_host_regmodel called
regmodel
5.Define a body () task that configures the DUT register with the exact same
information as host_bfm_sequence, except use UVM register
representation rather than direct access.
6. When done, save and close the file.

Task 9. Implement UVM Register Translator

In order for the UVM Register content to be processed correctly by the host driver,
you must implement a UVM register to host bus and host bus to UVM register
translator.

1. Open the host_data.sv file in an editor


2. Locate class reg_adapter
3. In the reg2bus () method, copy the generic UVM register object (rw
argument of method) content into a host_data object and return the
host_data handle.
4. In the bus2reg () method, check to see that the uvm_sequence_item
(bus_item) from the argument is a host_data type. Then, copy the
host_data object content into the UVM register object (rw).
Reference the lecture slides for exact syntax.
5. When done, save and close the file.

Task 10. Instantiate RAL Model in Environment

1. Open router_env.sv in an editor


2. In class, add an instance of ral_block_host_regmodel called regmodel

Lab 7-8 Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop
Lab 7

3. In the build phase, check to see if regmodel is null. If yes, do the following:
• Add a string called hdl_path
• Use uvm_conf ig_db to retrieve hdl_path . If hdl^path is not
configured, issue a warning message.
• Contruct the regmodel object
• Call the regmodel’s build () method to build the RAL representation
• Call the regmodel’s lock__model () to lock the RAL structure and
create the address map
• Set hdl root path using regmodel’s set_hdl_path_root () method.
When done, the modified build_phase () should contain the following:

virtual function void build_phase (uvm_phase phase) ; ...


i f (re g m o d e l == n u ll) b e g in

s t r in g h d ljp a t h ;

i f ( ! uvm mc o n f i g _ d b # ( s t r in g ) : : g e t. ( t h i s , "", " h d l_ p a t h " , h d l_ p a t h ) )

s u vm _ _ w a rn ± n g ( " H O S T C F G " , "H D L p a th fo r b a ckd o o r n o t s e t ! " ) ;

re g m o d e l « r a l„ b lo c k _ h o s t „ r e g m o d e l: :t y p e _ id : : c r e a t e ( " r e g m o d e l" , t h is ) ;

r e g m o d e l. b u i l d ( ) ;

r e g m o d e l . l o c k j n c t o d e l () ;

r e g m o d e l. s e t h d l p a th r o o t ( h d l_ p a t h ) ;

!!|i|i|(j!;!!!!!!!!!!!!!!!j;!!!!l!!!!!l
endfunction

4. In connect phase, create an instance of reg„adapt@r called adapter


5. Continuing in connect phase, construct a d a p te r
6. Tie the regmodel to a sequencer by calling the set_sequencer () method
in regmodel’s def ault_map. In the argument, pass in sequencer handle
(h__agent.seqr) and RAL translator handle (adapter).

virtual function void connectjphase(uvm„phase phase) ;

llillillllll^^

Register Abstraction Layer (RAL) Lab 7-9


SystemVerilog UVM Workshop
Lab 7

7. When done, save and close the file.

Task 11. Execute RAL Sequence in Test

The last piece of the RAL puzzle is to execute the RAL sequence. You should do
this in a test.

1. Open test_collection.sv file in an editor


Near the bottom of the file, there is a test called test_ral_seq extended
from test_seq_lib_cfg.
2. In the build phase, disable the host agent's sequencer at the
conf igure_phase by setting its de fault_sequence to null
3. Continuing in build phase, set the environment’s hdl_path to point to
router_test_top.dut
4. In the configure phase, instantiate and construct a host_ral_sequence
object called host_seq
5. Continuing in the configure phase, set the host_seq’s regmodel to
environment’s regmodel (env. regmodel)
6. Finally, in configure phase, call host_seq’s start () method to execute the
RAL sequence
7. Save and close the file

Task 12. Compile And Simulate____________________

1. Compile and simulate the testbench.


> make test=test_ral_seq
You should see that 160 packets were driven through the DUT once again.

Congratulations, you have completed Lab 7!

Lab 7-10 Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop
Answers / Solutions

Answers / Solutions
test__collection.sv Solutions

class testjoase extends uvm_t'est.;


suvrn_component_utils (test__base)
router_env env;
function new (string name, uvm_component parent ).;
super.new(name, parent);
; uvm__info ("TRACE11, $sf ormatf ("%m!f), UVM_HIGH) ; ;
endfunction

virtual function void build__phase (uvm__phase phase) ;


super. build__phase (phase);
s:Uvm_info ("TRACE" , $sformatf:( "%mn ), UVMJIGH) ; 1
env .'3-out er__.env ::typ e__id::cr eat e ("env ", this) ; '
uvm__conf ig___db# (virtual router_io) ::set (this, "env.i_agent [* ]",
"router_io", router„test__top .sigs);
uvm_config_db#(virtual router_io) ::set(this, "env.o_agent [*] ",
"router_io" ,:router_test__top .sigs); :
uvm__conf ig_db#(virtual router__io)::set(this, "env.r_agent",
"router_io", router_test_top.sigs );
uvm_conf ig__db# (virtual host_io) : :set (this, "env.h__agent", "host_io",
router„test_top.host);
• endfunction

endclass

class test_ral_seq extends test__seq_lib__cfg;


suvm_component_utils (test_ral_seq)

function new(string name, uvm_component parent);


super.new(name, parent);
endfunction

virtual function void build__phase(uvm_phase phase);


super.build_phase(phase);
uvm_conf ig_db # (uvm__object__wrapper) ::set (env,
"h__agent.seqr .conf igure__phase ", "def ault__sequence", null) ;
uvm_config_db #(string)::set(this, "env", "hdl_path",
"router_t est_top.dut") ;
endfunction

virtual task configure_phase(uvm_phase phase);


host_ral_sequence host_seq =
host_ral_sequence ::type__id::create ("host__seq" , this) ;
super .conf igure_phase (phase) ;
host__seq.regmodel = env. regmodel;
phase •raise_objection (this);
host_seq.start(null);
phase.drop_objection(this);
endtask
endclass

Register Abstraction Layer (RAL) Lab 7-11


SystemVerilog UVM Workshop
Lab Answers ; ^ctUtttons

host___data. s v Solution:

class Vhost_data extends uvm_sequenoe_i'fcem; :


typedef enurn {READ, WRITE} kind_e;.v
rand ki.nd_e kind;
rand bit[15:0] addr;
rand bit[15:0] data;

vuvm_ob ject__utils__begin (host__data)


xuvm__field__int (addr, UVM__ALL_ON)
suvrTL_field_int (data, UVM__ALL_ON)
suvm_f ield__enum (kind_e, kind, UVM_ALL_ON)
'uvm_object_utils_end

function new (string name="host__data" ) ;


super.new(name);
'uvm_info( "Trace”, $sf ormatf ("%m"),:.:.UVM^HIGH:).;;:.
endfunction .:
endclass

class reg_adapter extends uvm_reg_adapter;


; vuvm_ob jec.t_ut.ils (reg_adapter)

function new(string name="reg„adapter" );


super.new(name);
'uvm__inf o ("Trace" , $sf ormatf ("%m" ), UVMJHIGH) ;
endfunction

virtual function uvm„sequence_item reg2bus (const ref uvm__reg„bus__op


rw) ;
host_data tr;
'uvm_info("TRACE", $sf ormatf (" %m" ), UVM__HIGH) ;

tr = host_data: :type_id: :create("tr") ;


tr .kind - (rw.kind == UVM_READ) ? host__data ::READ : host„data ::WRITE ;
tr.addr = rw.addr;
tr,data = rw.data;
return tr;
endfunction

virtual function void bus2reg (uvm_sequence_item bus__item, ref


uvm__reg_Jous__op rw) ;
host__data tr;
suvm_inf o ("TRACE" , $sf ormatf ("%m" ), UVMJHIGH) ;

if (!$cast (tr, bus_item) ) begin


'uvm__fatal ("NOT__HOST__REG__TYPE" , "bus„item is not correct type ");
end
rw.kind = (tr.kind == host_dat.a::READ) ? UVM___READ : UVM__WRITE;
rw.addr = tr.addr;
rw.data = tr.data;
rw. status = UVM_IS_OK;
endfunction
endclass

Lab 7-12 Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop
Answers / Solutions

host__agent:.sv Solutions

class host_agent extends uvm__agent;


virtual host_io sigs; // DUT host interface
:uvm___anaIysis_port # (host_dat;a:)\ analysis_port ; :
host__sequencer seqr;/
host__driver drv;
host_monitor mon;
suvm_component__utils (host__agent)
function new (string name, uvm_component parent);
super.new(name, parent);
suvm__info ("TRACE", $sf ormatf ("%m" ) , -.UVMJHIGH) ;
endfunction
virtual function void bulld__phase (uvm_phase phase);
super .build__phase (phase),v
J uvm_inf o ("TRACE", $sf ormatf ("%m") , UVM__HIGH) ;
uvm_config_db# (virtual hostile) ::get (this, "rV, "hosf___io", sigs) ;
if (is_^active) begin
seqr = host_sequencer::type„id::create("seqr", this);
drv = host__driver ::type_id ::create ("drv" , this);
uvm__conf ig_db# (virtual host_J_o) : :set (this, "drv" , "host__io" , sigs );
uvm_config_db#(virtual host_io) : :set(this, "seqr", "host_io" , sigs);
end
mon = host_monitor::type__id::create("mon", this);
uvm__conf ig__db# (virtual host_io) ::set (this, "mon" , "host_io" , sigs) ;
endfunction
virtual function void connect_phase(uvm_phase phase);
super .connect__phase (phase);
'uvm__inf o ("TRACE" , $sf ormatf ("%m" ) , UVMJHIGH) ;
if (is_active)
drv .seq__item__port.connect (seqr .seq_item_export);
endfunction
endclass
class host__driver extends uvm_driver # (host__data) ;
virtual host_io sigs;
event go;
"uvm_component_utils (host__driver)
function new(string name, uvm_component parent);
super.new(name, parent);
vuvm__info ("TRACE" , $sf ormatf ("%m" ) , UVMJIGH) ;
endfunction
v.1.rtua 1 function void bui 1d_pbase (uvm__phase phase);
'uvm_inf o ("T R A C E , $sf ormatf (" %m" ) , UVMJHIGH) ;
if (!uvm_config_db# (virtual host_io) :: get (this, "", "host__io" , sigs ))
begin
'uvm_f atal ("CFGERR" , "DUT host interface not set" );

endfunction
virtual task pre_reset_phase(uvm_phase phase);
sigs.wr_n = ’x;
sigs.address = rx ;
sigs.data = ’x;
endtask
virtual task reset_phase(uvm_phase phase);

Register Abstraction Layer (RAL) Lab 7-13


SystemVerilog UVM Workshop
Lab 7 Answers / Solutions

. .sigs .wr___n : -= rl;:


sigs .address = M ; ;
sigs .data = 11;
endtask
virtual task run_phase (uvm_phase phase );
\uvm__info ("TRACE" $sf ormatf ("%m" ), UVMJiIGH) ;
forever begin
seq__item__port.get__next_item (req) ;
'uvm_info("RUN", { "Before process\n", req.sprint() }, UVM__FULL);
data__rw (req) ;
iuvm__inf o ('"RUN"'/ { "After processXn”, req .sprint () }f UVMJFULL) ;
Jseq_item__port.item_done () ;
end
endtask
task suspend() ;
wait(go.triggered);
endtask
/;/ :;Bee/file for device driver code
endclass;
class host_monitor extends uvm_monitor ;
uvm_analysis_port # (host__data) analysi.s_port;
virtual host__io sigs;
event go;
'uvm__component_utils (host__monitor)
function new(string name, uvm_component parent);
super.new(name, parent);
'uvm__info( "TRACE", $sf ormatf ("%m" ), UVM_HIGH) ;
endfunction
virtual function void build_phase(uvm__phase phase);
'uvm_info( "TRACE", $sformatf ("%m") , UVM_HIGH) ;
if (!uvm__conf ig_db# (virtual host__io) :: get (this, "", "host_io" , sigs ))
begin
suvm_fatal("CFGERR", "DUT host interface not set");
end
analysis__port = new ("analysis_port ”, this) ;
endfunction
virtual task run„phase (uvm„phase phase) ;
host__data tr;
suspend();
suvm_info("TRACE", $sformatf("%m"), UVM_HIGH) ;
forever begin
tr = host_data : :type__id ::create ("tr ", this) ;
data_rw(tr) ;
analysis__port .write (tr);
end
endtask
virtual task post__reset„phase (uvmjphase phase);
-> go;
endtask
task suspend();
wait(go.triggered);
endtask
// See file for device driver code
endclass
Lab 7-14 Register Abstraction Layer (RAL)
SystemVerilog UVM Workshop
A n s w e r s / S o lu tio n L ab

h o s t „ s e q u e n c e . sv Solution:

class host„bfm__sequence extends uvm_sequence #(host__data);


'uvm_ob ject_utils (host__bfm_sequence )
function new (string name = "host_bfm_sequence");
super.new(name);
'uvrn_info ("TRACE" , $sformatf("%m"), UVMJiIGH) ;
endfunction

virtual task body() ;


suvm___info ("TRACE" , $sformatf("%m"), UVM_HIGH);
if (start ing__phase != null)
starting_phase.raise_objection(this)-;
xuvm__do„with(req, {addr == ThlOO; kind == host__data: :READ; }) ;
suvm_info("HOST BFM READ", {"\n", req.sprint () }; WNLMEDiUM) f
suvm__do__with (req, {addr == fhlOQ; data ==- ’1; kind == ■::
hos t_dat a ::WRITE; });
- 'uvm__inf o ("HOST BFM WRITE", {"\n" , req. sprint () }, UVMJMEDIUM) ;
Nuvm___do_with (req, (addr ■== 1hlOO; kind == host__data ::READ; });
'uvmJLnfo ("HOST BFM READ", {"\n", req.sprint ()} , UVM__MEDIUM) ;
if (start ing__phase != null)
starting_phase.. drop___objection (this);
endtask
endclass

class host__ral__sequence extends uvm_reg_sequence # (uvm_sequence


# (host_data));
ral__block_host__regmodel regmodel ;
'uvm„ob ject__utils (host_ral_sequence )

function new (string name = "host__ral__sequence") ;


super.new(name);
vuvm__inf o ("TRACE" , $sf ormatf ("%m" ) , UVM__HIGH) ;
endfunction

virtual task body();


uvm_status„e status;
uvm_reg_data__t data;
'uvm__inf o ("TRACE ", $sformat f ("%m" ), UVM_HI GH) ;
if (starting__phase != null)
starting__phase .raise__ob jection (this) ;
regmodel.PORT__LOCK.read(.status(status), .value(data),
.path(UVM_FRONTDOOR), .parent(this));
vuvm__inf o ("RAL READ", $sf ormatf ("PORT_LOCK= %2h", data), UVM__MEDIUM) ;
regmodel.PORT_LOCK.write(.status(status), .value(11),
.path (UVM_FRONTDOOR) , .parent (this) );
"uvm_info ("RAL WRITE", $sformatf("PORT_LOCK= %2h", fl), UVM„MEDIUM) ;
regmodel.PORT„LOCK.read(.status(status), .value(data),
.path (UVM__FRONTDOOR) , .parent (this) );
'uvm_info ("RAL READ", $sf ormatf ("PORT__LOCK= %2h" , data), UVM_MEDIUM) ;
if (starting_phase I= null)
starting_phase.drop_objection(this);
endtask
endclass

class host_noop_sequence extends uvm^sequence # (host_data);


Nuvm_object_utils (host_noop__sequence)

Register Abstraction Layer (RAL) Lab 7-15


SystemVerilog UVM Workshop
Lab 7 Answers / Solutions

function new (string name - f!host_noop„sequenceH);


'super.new(name);
suvm_inf o ("TRACE" , $sf ormatf ("%m" ), UVM___HIGH) ;
endfunction v
task body();
endtask
endclass

host.ralf Solution:

register HOST__ID {
field REV_ID {
bits 8;
access ro;
reset ’h03;
; ) .
field CHIP_ID: { ;
bits 8;
access ro;
1 reset ’h5A;
}
}

register PORT__LOCK {
field LOCK {
bits 16;
access wlc;
reset ’hffff;

register REG_ARRAY {
field USER__REG {
bits 16;
access rw;
reset ’hO}
i

memory RAM {
size 4k;
bits 16;
access rw;

block host_regmodei {
bytes 2;
register HOSTJD (host__id) @ 1hOOOO
register PORT_LOCK (lock) 0 fhOlOO
register RE G__ARRAY [256] (host_reg [%d] ) @ fhl000 # array must specify index
memory RAM (ram) 0*h4OOO

Lab 7-16 Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop
Answers / Solutions

router_e n v .sv Solutions

class router_env extends1uvrTv__env; ::


: input_ag:ent i_agent:[:16:] ; ■
scoreboard sb;
output__agent o__agent [16 ];
reset__agent r__agent;
host_agent h_agent;
ral_block__host__regmodel regmodel;
vuvm__component_utils (router_env)

function new (string name, uvm__component parent);


super.new(name, parent);
'uvm__info ("TRACE" , $sf ormatf (11%m" ) , UVM__HIGH) ;
endfunction

virtual function void build__phase (uvm_phase phase); \


super .build__phase (phase);
suvrn_info ("TRACE" , $sf ormatf ("%m" ) , UVM__HIGH) ;
foreach (i___agent [i] ) be:
gin
i_agent [i] = input__agent::type_id ::create ($sf ormatf ("i_agent [%0d] ", i
this);; _
uvm_conf ig_db #(int):: set (this, i__agent [i ] .get_name () , "port__id", i) ;
uvm_conf ig.mdb # (uvm_ob ject_wrapper) ::set (this, {i_agent [i ] ,get_name()
" .", "seqr .main__phase"}, "def ault_sequence" , packet„sequence ::get__type () );
end
sb = scoreboard::type_id : :create (" sb" , this);
foreach (o__agent [i ]) begin
o_agent [i] =
output__agent::type__id ::create ($sf ormatf ("o_agent [%0d] ", i ),this);
uvm_conf ig__db # (int) ::set (this, o__agent [i] .get_name () , "port__id", i) ;
end
r_agent = reset_agent ::type__id::create ("r_agent", this);
uvm_conf ig_db # (uvm_ob ject__wrapper ) ::set (this, {r_agent.get__name () ,"."
"seqr .reset__phase" }, "def ault_sequence ", reset_sequence : :get_type () ) ;

h__agent - host„agent: :type__id: :create ("h__agent" , this) ;


uvm_conf ig_db # (uvm_object_wr apper):: set (this, {h_agent.get_name () ,
"seqr .conf igure_phase "}, "def ault_sequence" , host_bfm_sequence ::get_type () )

if (regmodel == null) begin


string hdl_path;
if (!uvm_conf ig_db #( string) ::get (this, "", "hdl_path" , hdl_path) )
begin
'uvm__warning ("HOSTCFG" , "HDL path for backdoor not set!");
end
regmodel = ral_block___host__regmodel::type_id: :create ("regmodel", this)
regmodel.build();
regmodel.lock_model () ;
regmodel.set_hdl_path_r oot (hdl__path) ;

endfunction

virtual function void connect__phase(uvm_phase phase);


reg_adapter adapter;

'uvm„info ("TRACE" , $sf ormatf ("%m" ) , UVMJHIGH) ;

Register Abstraction Layer (RAL) Lab 7-17


SystemVerilog UVM Workshop
.ab 7 Answers ' Solutions

adapter = reg__adapter ::type_id: :create ("adapter11, this );

■regmodel .def ault_map .set__sequencer (h_agent.seqradapter) ;

foreach ("i_agent[i] ) begin


i_agent [i] .analysis__port.connect (sb.bef ore__export);
end
foreach (o_agent[i ]) begin
o_agent [i ] .analysis_port.connect (sb.af ter_export);
end
endfunction
endclass

Lab 7-18 Register Abstraction Layer (RAL)


SystemVerilog UVM Workshop

You might also like