0% found this document useful (0 votes)
214 views12 pages

Uvm 2012.09 LG 01

The document describes building a simple UVM testbench including creating a test class, registering it with the factory, adding a test program, and compiling and running the test. It then discusses creating a packet sequence item class, a packet sequence class, a sequencer class, a driver agent class, and an environment class to generate stimulus and interact between the sequencer and driver.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
214 views12 pages

Uvm 2012.09 LG 01

The document describes building a simple UVM testbench including creating a test class, registering it with the factory, adding a test program, and compiling and running the test. It then discusses creating a packet sequence item class, a packet sequence class, a sequencer class, a driver agent class, and an environment class to generate stimulus and interact between the sequencer and driver.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

UVM Environment

Learning Objectives

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-004
Lab 1

Getting Started

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

build
Environment class

connect

end_of_elaboration Agent Agent


start_of_simulation
Sequencer
run

extract
Monitor Scoreboard Monitor
check
Driver
TBD TBD TBD
report

final

DUT

Figure 1. Lab 1 Testbench Architecture

Lab 1-2 UVM Verification Environment


SystemVerilog UVM 1.1 Workshop
Lab 1

Lab Overview

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

labs/ solutions/ rtl/

lab1/ Lab7/ lab1/ Lab7/ router.sv

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:

Create
UVM Test File

Create
UVM Test
Program file

Compile and simulate


UVM Testbench

Add Sequence_item,
Sequence, Driver,
Agent and
Environment

Display Testbench
topology

Figure 3. Lab 1 Flow Diagram

UVM Verification Environment Lab 1-3


SystemVerilog UVM 1.1 Workshop
Lab 1

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 lab1 directory:


> cd labs/lab1
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, %m is a format
specifier that prints the current hierarchical path.

`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);

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 test.sv. Enter the following test code:

program automatic test;


import uvm_pkg::*;
`include "test_collection.sv"
initial begin
$timeformat(-9, 1, "ns", 10);
run_test();
end
endprogram

Lab 1-4 UVM Verification Environment


SystemVerilog UVM 1.1 Workshop
Lab 1

8. Save and close the file.


9. Compile and simulate this simple UVM testbench:
> vcs –sverilog –ntb_opts uvm-1.1 test.sv
> simv +UVM_TESTNAME=test_base
At the end of simulation, you should see something like the following:
Test as specified by
UVM_INFO @ 0: reporter [RNTST] Running test test_base... +UVM_TESTNAME
#### Factory Configuration (*)
No instance or type overrides are registered with this factory
You will be modifying the test via factory
All types registered with the factory: 37 total configuration with overrides in future labs
(types without type names will not be printed)
Type Name factory.print() displays all class
--------- types registered in the factory via the
test_base `uvm_component_utils macro

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
 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_field_* macros embedded within the
`uvm_object_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 1.1 Workshop
Lab 1

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
 And the body() method (see comments)
4. Save and close the file.

With the packet and the packet_sequence classes, you have created
the base mechanism for generating stimulus in UVM.

The next step is to create the component that will be processing the stimulus.
5. Open the driver.sv file with an editor, and look for the comments that
start with: “// Lab 1”. Enter the following:
 The class declaration
 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, you will be calling the device driver to drive the contents of the request
object through the DUT.
6. Save and close the file.

Once you have the stimulus generating mechanism and the component to
process the stimulus, you are ready to create the container that will house
them. This container is called an agent.
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 the 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 1.1 Workshop
Lab 1

8. Save and close the file.

You are now ready to build an environment class for your DUT.
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
 Then, set the agent’s sequencer to execute packet_sequence as
the default sequence in the main phase

10. Save and close the file.

An environment consists of a set of components that are configured to process


some default stimulus through the DUT. Where these configurations and
stimulus will be managed is at the test level.
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

12. Save and close the file.

UVM Verification Environment Lab 1-7


SystemVerilog UVM 1.1 Workshop
Lab 1

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...


UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology:
-------------------------------------------------------------
Name Type Size Value
-------------------------------------------------------------
uvm_test_top test_base - @460
env router_env - @469
i_agent input_agent - @477
drv driver - @599
rsp_port uvm_analysis_port - @614
sqr_pull_port uvm_seq_item_pull_port - @606
seqr uvm_sequencer - @490
rsp_export uvm_analysis_export - @497
seq_item_export uvm_seq_item_pull_imp - @591
arbitration_queue array 0 -
lock_queue array 0 -
num_last_reqs integral 32 'd1
num_last_rsps integral 32 'd1
------------------------------------------------------------
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);
No 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
via the `uvm_component_utils() and the
input_agent
`uvm_object_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 1.1 Workshop
Lab 1

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_info 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 1.1 Workshop
Lab 1 Answers / Solutions

Answers / Solutions
test.sv Solution:

program automatic test;


import uvm_pkg::*;
`include "test_collection.sv"
initial begin
$timeformat(-9, 1, "ns", 10);
run_test();
end
endprogram

test_collection.sv Solution:

class test_base extends uvm_test;


`uvm_component_utils(test_base)
router_env env;
function new(string name, uvm_component parent);
super.new(name, parent);
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
endfunction: new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
env = router_env::type_id::create("env", this);
endfunction: build_phase
virtual function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
uvm_top.print_topology();
factory.print();
endfunction: start_of_simulation_phase
endclass: test_base
driver.sv Solution:

class driver extends uvm_driver #(packet);


`uvm_component_utils(driver)
function new(string name, uvm_component parent);
super.new(name, parent);
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
endfunction: new
virtual task run_phase(uvm_phase phase);
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
forever begin
seq_item_port.get_next_item(req);
req.print();
seq_item_port.item_done();
end
endtask: run_phase
endclass: driver

Lab 1-10 UVM Verification Environment


SystemVerilog UVM 1.1 Workshop
Answers / Solutions Lab 1

packet.sv Solution:

class packet extends uvm_sequence_item;


rand bit [3:0] sa, da;
rand bit [7:0] payload[$];
`uvm_object_utils_begin(packet)
`uvm_field_int(sa, UVM_ALL_ON | UVM_NOCOMPARE)
`uvm_field_int(da, UVM_ALL_ON)
`uvm_field_queue_int(payload, UVM_ALL_ON)
`uvm_object_utils_end
constraint valid {
payload.size inside {[1:10]};
}
function new(string name = "packet");
super.new(name);
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
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 new(string name, uvm_component parent);


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

virtual function void build_phase(uvm_phase phase);


super.build_phase(phase);
`uvm_info("TRACE", $sformatf("%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);
`uvm_info("TRACE", $sformatf("%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 1.1 Workshop
Lab 1 Answers / Solutions

router_env.sv Solution:

class router_env extends uvm_env;


input_agent i_agent;
`uvm_component_utils(router_env)

function new(string name, uvm_component parent);


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

virtual function void build_phase(uvm_phase phase);


super.build_phase(phase);
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
i_agent = input_agent::type_id::create("i_agent", this);
uvm_config_db #(uvm_object_wrapper)::set(this, "i_agent.seqr.main_phase",
"default_sequence", packet_sequence::get_type());
endfunction: build_phase
endclass: router_env
packet_sequence.sv Solution:

class packet_sequence extends uvm_sequence #(packet);


`uvm_object_utils(packet_sequence)

function new(string name = "packet_sequence");


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

task body();
`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
if (starting_phase != null) begin
starting_phase.raise_objection(this);
end
repeat(10) begin
`uvm_do(req);
end
if (starting_phase != null) begin
starting_phase.drop_objection(this);
end
endtask: body

endclass: packet_sequence

Lab 1-12 UVM Verification Environment


SystemVerilog UVM 1.1 Workshop

You might also like