[go: up one dir, main page]

0% found this document useful (0 votes)
11 views56 pages

Uvm PDF

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)
11 views56 pages

Uvm PDF

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/ 56

UVM Introduction

Introduction to UVM

Table of Contents

 Introduction to UVM
o UVM Classes
o uvm_object
o uvm_transaction
o uvm_component
o UVM Class Hierarchy

The Universal Verification Methodology (UVM) consists of class libraries needed for
the development of well constructed, reusable SystemVerilog based Verification
environment.
In simple words, UVM consists of a set of base classes with methods defined in it, the
SystemVerilog verification environment can be developed by extending these base
classes.
Now on will refer the UVM base classes as UVM Classes.

UVM Classes
UVM consists of three main types of UVM classes,

 uvm_object
 uvm_transaction
 uvm_component

uvm_object

 Core class based operational methods (create, copy, clone, compare, print,
record, etc..), instance identification fields (name, type name, unique id,
etc.) and random seeding were defined in it.
 All uvm_transaction and uvm_component were derived from the
uvm_object.

uvm_transaction

 Used in stimulus generation and analysis.

uvm_component

 Components are quasi-static objects that exist throughout the simulation.


 Every uvm_component is uniquely addressable via a hierarchical path
name, e.g. “env.agent.driver”.
 The uvm_component also defines a phased test flow, that components
follow during the course of the simulation. Each phase(build, connect, run,
etc.) is defined by a callback that is executed in precise order.
 The uvm_component also defines configuration, reporting, transaction
recording, and factory interfaces.

UVM TestBench

Table of Contents

 UVM TestBench
o UVM testbench hierarchy
 UVM test
 UVM Environment
 UVM Agent
 UVM Sequence item
 UVM Driver
 UVM Sequence
 UVM Sequencer
 UVM Monitor
 UVM Scoreboard
 UVM TestBench Block Diagram

UVM testbench hierarchy

Below is the typical UVM testbench hierarchy diagram.


UVM test

The test is the topmost class. the test is responsible for,

 configuring the testbench.


 Initiate the testbench components construction process by building the next
level down in the hierarchy ex: env.
 Initiate the stimulus by starting the sequence.

UVM Environment

Env or environment: The environment is a container component for grouping


higher level components like agent’s and scoreboard.

UVM Agent

UVM agent groups the uvm_components specific to an interface or protocol.


example: groups the components associated with BFM(Bus Functional Model).\
The components of an agent are,
UVM Sequence item

The sequence-item defines the pin level activity generated by agent (to drive to
DUT through the driver) or the activity has to be observed by agent (Placeholder
for the activity monitored by the monitor on DUT signals).

UVM Driver

Responsible for driving the packet level data inside sequence_item into pin level
(to DUT).

UVM Sequence

Defines the sequence in which the data items need to be generated and
sent/received to/from the driver.

UVM Sequencer

Responsible for routing the data packet’s(sequence_item) generated in sequence to


the driver or vice verse.

UVM Monitor

Observes pin level activity on interface signals and converts into packet level
which is sent to components such as scoreboards.

UVM Scoreboard

Receives data item’s from monitor’s and compares with expected values.

expected values can be either golden reference values or generated from the
reference model.
For a detailed explanation of each component and methods refer to UVM Tutorial.

UVM TestBench Block Diagram

 UVM TestBench Block Diagram with a single agent.


UVM Sequence item

Table of Contents

 UVM_Sequence_item
o UVM Utility Macros
o UVM Field Macros
 Sequence item:
 Sequence item example:
o UVM Sequence item Methods
 create():
 print():
 copy:
 clone
 compare
 pack, pack_bytes, pack_ints
 unpack,unpack_bytes,unpack_ints
The sequence-item is written by extending the uvm_sequence_item,
uvm_sequence_item inherits from the uvm_object via the uvm_transaction class.
therefore uvm_sequence_item is of an object type.

UVM Utility Macros

The utility macros provide implementations of the create method (needed for
cloning) and the get_type_name method (needed for debugging), etc.
objects with no field macros,

`uvm_object_utils(TYPE)

objects with field macros,

`uvm_object_utils_begin(TYPE)
`uvm_field_*(FIELD,FLAG)
`uvm_object_utils_end

UVM Field Macros

The `uvm_field_* macros are invoked inside of the `uvm_*_utils_begin and


`uvm_*_utils_end, for the implementations of the methods: copy, compare, pack,
unpack, record, print, and etc.

Each `uvm_field_* macro is named to correspond to a particular data type:


integrals, strings, objects, queues, etc., and each has at least two arguments: FIELD
and FLAG.
Sequence item:

 fields required to generate the stimulus are declared in the sequence_item.


 sequence_item can be used as a placeholder for the activity monitored by the
monitor on DUT signals.

Data fields represent the following types of information,


 Control Information – a type of transfer, transfer size, etc
 Payload Information – data content of the transfer
 Configuration Information – mode of operation, error behavior, etc
 Analysis Information – fields used to capture information from DUT, ex:
read data, response, etc

Sequence item example:

class mem_seq_item extends uvm_sequence_item;


//Control Information
rand bit [3:0] addr;
rand bit wr_en;
rand bit rd_en;

//Payload Information
rand bit [7:0] wdata;

//Analysis Information
bit [7:0] rdata;

//Utility and Field macros,


`uvm_object_utils_begin(mem_seq_item)
`uvm_field_int(addr,UVM_ALL_ON)
`uvm_field_int(wr_en,UVM_ALL_ON)
`uvm_field_int(rd_en,UVM_ALL_ON)
`uvm_field_int(wdata,UVM_ALL_ON)
`uvm_object_utils_end

//Constructor
function new(string name = "mem_seq_item");
super.new(name);
endfunction

//constaint, to generate any one among write and read


constraint wr_rd_c { wr_en != rd_en; };

endclass
UVM Sequence item Methods

create():

The create method allocates a new object of the same type as this object and
returns it via a base uvm_object handle.

print():

The print method deep-prints this object’s properties in a format and manner
governed by the given printer argument;

Create() and Print() Method

class mem_seq_item extends uvm_sequence_item;


//Control Information
rand bit [3:0] addr;
rand bit wr_en;
rand bit rd_en;

//Payload Information
rand bit [7:0] wdata;

//Analysis Information
bit [7:0] rdata;

//Utility and Field macros,


`uvm_object_utils_begin(mem_seq_item)
`uvm_field_int(addr,UVM_ALL_ON)
`uvm_field_int(wr_en,UVM_ALL_ON)
`uvm_field_int(rd_en,UVM_ALL_ON)
`uvm_field_int(wdata,UVM_ALL_ON)
`uvm_object_utils_end

//Constructor
function new(string name = "mem_seq_item");
super.new(name);
endfunction

//constaint, to generate any one among write and read


constraint wr_rd_c { wr_en != rd_en; };

endclass
//-----------------------------------------------------
--------------------
//Simple TestBench to create and randomize sequence
item
//-----------------------------------------------------
--------------------
module seq_item_tb;

//instance
mem_seq_item seq_item;

initial begin
//create method
seq_item = mem_seq_item::type_id::create();

//randomizing the seq_item


seq_item.randomize();

//printing the seq_item


seq_item.print();
end
endmodule

Simulator Output:
---------------------------------------
Name Type Size Value
---------------------------------------
mem_seq_item mem_seq_item - @334
addr integral 4 'h4
wr_en integral 1 'h1
rd_en integral 1 'h0
wdata integral 8 'h88

copy():

The copy makes this object a copy of the specified object.

clone():

The clone method creates and returns an exact copy of this object. clone = create()
+ copy();
compare

Deep compares members of this data object with those of the object provided in
the RHS (right-hand side) argument, returning 1 on a match, 0 otherwise.

pack, pack_bytes, pack_ints

The pack methods bitwise-concatenate this object’s properties into an array of bits,
bytes, or ints

unpack,unpack_bytes,unpack_ints

The unpack methods extract property values from an array of bits, bytes, or ints.

UVM Sequence

 Sequence generates the stimulus and sends to driver via sequencer.


 An agent can have any number of sequences.

Sequence is written by extending the uvm_sequence.

 A uvm_sequence is derived from an uvm_sequence_item

sequence base class

virtual class uvm_sequence #( type REQ = uvm_sequence_item,


type RSP = REQ ) extends uvm_sequence_base

example:
class write_sequence extends uvm_sequence #(mem_seq_item);
....
....
endclass

the sequence has handle req and rsp of mem_seq_item.


request/req:

A transaction that provides information to initiate the processing of a particular


operation.

response/rsp:

A transaction that provides information about the completion or status of a


particular operation.

UVM Sequence macros

These macros are used to start sequences and sequence items on default sequencer,
m_sequencer.

difference between m_sequencer and p_sequencer:

m_sequencer,

The m_sequencer handle contains the reference to the sequencer(default


sequencer) on which the sequence is running.
This is determined by,

 the sequencer handle provided in the start method


 the sequencer used by the parent sequence
 the sequencer that was set using the set_sequencer method
p_sequencer,

The p_sequencer is a variable, used as a handle to access the sequencer properties.


p_sequencer is defined using the macro
`uvm_declare_p_sequencer(SEQUENCER_NAME)

UVM Sequencer
Sequencer is written by extending uvm_sequencer, there is no extra logic
required to be added in the sequencer.

 The sequencer controls the flow of request and response sequence items
between sequences and the driver
 Sequencer and driver uses TLM Interface to communicate transactions
 uvm_sequencer and uvm_driver base classes have seq_item_export and
seq_item_port defined respectively. User needs to connect them using TLM
connect method.

Example:
driver.seq_item_port.connect(sequencer.seq_item_export);

UVM Sequencer Code


class mem_sequencer extends uvm_sequencer#(mem_seq_item);

`uvm_sequencer_utils(mem_sequencer)

function new (string name, uvm_component parent);


super.new(name, parent);
endfunction : new

endclass : mem_sequencer

UVM Config db

Table of Contents

 UVM Config db
o uvm config db get and set
 uvm config db set method
 uvm_config_db set example
 uvm config db get method
 uvm_config_db get example

The configuration database provides access to a centralized database, where type


specific information can be stored and received. config_db can contain scalar
objects, class handles, queues, lists, or even virtual interfaces.

uvm config db get and set

uvm_config_db::set and uvm_config_db::get methods are used to store and


retrieve the information from the database respectively.

uvm config db set method

 value is the value to be stored in the database


mem_if intf(clk,reset); //interface instance
uvm_config_db#(virtual mem_if)::set(null,"*","mem_intf",intf);

uvm config db get method

 value is the variable to which the value is to be retrieved from the database

uvm_config_db get example

Below example shows. Using the get method to get a virtual interface handle from
a database and assigns it to mem_vif. If the get method fails, the fatal message will
be displayed.
virtual interface mem_if mem_vif; //virtual interface declaration
if( !uvm_config_db#(virtual mem_if)::get(this,"*", "mem_intf",
mem_vif))
`uvm_fatal(get_full_name(),{"virtual interface must be set
for:",".mem_vif"} );

UVM Phases
UVM Phases top down

 1. Build Phases
 2. Run-time Phases
 3. Clean up Phases
 UVM Phases are a synchronizing mechanism for the environment

 Phases are represented by callback methods, A set of predefined phases and


corresponding callbacks are provided in uvm_component. The Method can
be either a function or task.

the run phase is implemented as a task and remaining all are function.

Phases can be grouped into 3 categories,


1. Build Phases

build phase, connect phase and end_of_elobaration phase belongs to this category.
Phases in this categorize are executed at the start of the UVM testbench simulation,
where the testbench components are constructed, configured and testbench
components are connected.
All the build phase methods are functions and therefore execute in zero
simulation time.

2. Run-time Phases

start of simulation and run phase belongs to run-time phases, the run phase will
get executed from the start of simulation to till the end of the simulation.
the run phase is time-consuming, where the testcase is running

3. Clean up Phases

extract, check, report and final belong to this category.


where the results of the testcase are collected and reported. example: the number of
error’s during the simulation is reported.

UVM Driver
UVM Driver

 UVM_Driver Methods
o get_next_item
o try_next_item
o item_done
o put
 A driver is written by extending the uvm_driver
 driver receives the stimulus from sequence via sequencer and drives on
interface signals
 The uvm_driver is a parameterized class and it is parameterized with the
type of the request sequence_item and the type of the response
sequence_item

UVM_Driver Methods

get_next_item

This method blocks until a REQ sequence_item is available in the sequencer.

try_next_item
This is a non-blocking variant of the get_next_item() method. It will return a null
pointer if there is no REQ sequence_item available in the sequencer.

item_done

The non-blocking item_done() method completes the driver-sequencer handshake


and it should be called after a get_next_item() or a successful try_next_item() call.

put

The put() method is non-blocking and is used to place an RSP sequence_item in


the sequencer.

UVM Monitor

 The user-defined monitor is extended from uvm_monitor, uvm_monitor is


inherited by uvm_component
 A monitor is a passive entity that samples the DUT signals through the
virtual interface and converts the signal level activity to the transaction
level.
 Monitor samples DUT signals but does not drive them

UVM Agent

 Active agent
 Passive agent

UVM Agent

 a user-defined agent is extended from uvm_agent, uvm_agent is inherited by


uvm_component
 An agent typically contains a driver, a sequencer, and a monitor
 Agents can be configured either active or passive
 //declaring agent components
 mem_driver driver;
 mem_sequencer sequencer;
 mem_monitor monitor;
Passive agent

Passive agents sample DUT signals but do not drive them


A passive agent consists of only the monitor

An agent can be configured as ACTIVE/PASSIVE by using a set config method,


the default agent will be ACTIVE. the set config can be done in the env or test.
UVM Scoreboard

 scoreboard receives the transaction from the monitor and compares it with
the reference values.
 the scoreboard will check the correctness of the DUT by comparing the
DUT output with the expected values
 the scoreboard will receive the transactions from the Monitors implemented
inside agents
 Monitor and scoreboard will communicate via TLM ports and exports

Scoreboard shall compare the DUT output values with,

1. The golden reference values


2. The values Generated from the reference model

UVM Environment:
The environment is the container class, It contains one or more agents, as well as
other components such as the scoreboard, top-level monitor, and checker.

The user-defined environment is derived from uvm_env, uvm_env is inherited


from uvm_component.
UVM Test

The user-defined test is derived from uvm_test, uvm_test is inherited from


uvm_component.

 The test defines the test scenario for the testbench


 test class contains the environment, configuration properties, class overrides
etc
 A sequence/sequences are created and started in the test

The UVM testbench is activated when the run_test() method is called, the global
run_test() task should be specified inside an initial block.

UVM tb top

TestBench top is the module, it connects the DUT and Verification environment
components.

Typical Testbench_top contains,

 DUT instance
 interface instance
 run_test() method
 virtual interface set config_db
 clock and reset generation logic
 wave dump logic
 uvm tb top

 module tbench_top;

 //clock and reset signal declaration
 bit clk;
 bit reset;

 //clock generation
 always #5 clk = ~clk;

 //reset Generation
 initial begin
 reset = 1;
 #5 reset =0;
 end

 //creatinng instance of interface, inorder to connect DUT and
testcase
 mem_if intf(clk,reset);

 //DUT instance, interface signals are connected to the DUT ports
 memory DUT (
 .clk(intf.clk),
 .reset(intf.reset),
 .addr(intf.addr),
 .wr_en(intf.wr_en),
 .rd_en(intf.rd_en),
 .wdata(intf.wdata),
 .rdata(intf.rdata)
 );

 //enabling the wave dump
 initial begin
 uvm_config_db#(virtual
mem_if)::set(uvm_root::get(),"*","mem_intf",intf);
 $dumpfile("dump.vcd"); $dumpvars;
 end

 initial begin
 run_test();
 end
 endmodule
UVM Callback Tutorial

 UVM Callback
 UVM Callback add method

UVM Callback

What is Callback?

Callbacks are empty methods with a call to them.

Where callbacks can be implemented?

Callbacks can be implemented in an object or component.

What are the benefits of callback?

Different flavors of the component can be obtained by customizing the empty


callback methods.

About UVM Callbacks


UVM provides a set of classes, methods, and macros to implement the callbacks.
TestBench with callbacks

For easy understanding will see through below steps,

 Adding callback support


 Implementing the callback methods
 Using callback

Using Callback

In the testcase where callbacks need to be applied,

 Declare and create an object of callback class in which methods are


implemented (callback_1).
user_callback callback_1;
callback_1 = user_callback::type_id::create("callback_1", this);

 In order to execute the callback method, register the callback object to the
driver using the ‘add’ method
uvm_callbacks#(driver,driver_callback)::add(env.driv,callback_1);

Callback add method


Add method implementation
static function void add(
T obj,
uvm_callback cb,
uvm_apprepend ordering = UVM_APPEND
)

 Registers the callback object with the object in which callback is used
 It is allowed to register multiple callbacks derived from the same callback
 If ordering is UVM_APPEND (default), the callback will be executed after previously added
callbacks, else the callback will be executed ahead of previously added callbacks

Using add method

The previous example shows the usage of the add method.

In order to execute the callback method, the Callback object needs to be


registered to the object/component.
uvm_callbacks#(T, CB)::add(t,cb);
UVM Callback in uvm sequence

Callback hooks can be placed in uvm_sequnence. Different flavors of the sequence


can be obtained by implementing custom callback methods.

In the previous example’s we have seen callback implementation in uvm_driver. In


this section will see how to implement the callback in uvm_sequence.

Callback implementation in uvm_sequence

Callback implementation steps for uvm_sequence are the same as in uvm_driver.


Before going through this section, it is required to refer to the UVM callback
example.

Below are the testbench components.

Let’s implement the callback in uvm_sequence to modify the sequence_item


before sending it to the driver.

Steps involved are,

 Write callback class


 Register the callback class
 Place the callback hook
 Implement the callback method
 Create and register the callback object
uvm_event
Events are static objects useful for synchronization between the process. Event
operations are of two staged processes in which one process will trigger the
event, and the other processes will wait for an event to be triggered

UVM Event Methods

 new; Creates a new event object


 wait_trigger; Waits for an event to be triggered
 wait_ptrigger; Waits for a persistent trigger of the event, avoids race
conditions
 wait_on; Waits for the event to be activated for the first time, returns
immediately if the event is already triggered
 wait_off; Returns if the event is off, else waits for the event turned off via
reset event call
 is_on; Returns 1 if the event has triggered
 is_off; Returns 1 if the event has not been triggered
 reset; resets the event to its off state
 get_trigger_time; Returns the last time at which the event got triggered
is_on is_off reset
 get_num_waiters; Returns the number of processes waiting on the event

UVM Event Syntax


uvm_event event_name; // Event declaration

event_name = new(); // Creating an event

event_name.trigger(); // Triggering event

event_name.wait_trigger(); // Waiting for event trigger

uvm event pool

uvm_event_pool is a pool that stores the uvm_events.

uvm_event is used to synchronize the two processes. If the processes to trigger and
wait for a trigger of an event are running in different components then it is required
to share the event handle across the components. the uvm_event class makes it
easy by providing uvm_event_pool.
SYNTAX
module uvm_events_ex;
uvm_event ev[string];

initial begin

ev["ev_1"] = new(); //Creating the event


ev["ev_2"] = new();

uvm_event_callback

UVM provides the facility to add callbacks to a uvm_event trigger. The pre_trigger
and post_trigger are the callback hooks placed with the event trigger method. for
more on uvm callback refer to uvm_callback.

uvm event callbacks are an alternative to using processes that wait on events.
When a callback is attached to an event, the attached callback function/s is called
each time the event is triggered.

uvm_event_callback methods

new

Creates a new callback object.

pre_trigger
virtual function bit pre_trigger (
uvm_event#(T) e,
T data )

// e is the uvm_event#(T) that is being triggered


// data is the data associated with the event trigger

 This will get called just before triggering the associated event
 In extended class, the user can override this method in a derived class to
implement any pre-trigger functionality
 This method returns bit type
 If the method returns 1, the event will not trigger and the post-trigger
callback is not called. This provides a way for a callback to prevent the
event from triggering
post_trigger
virtual function void post_trigger (
uvm_event#(T) e,
T data )

// e is the uvm_event#(T) that is being triggered


// data is the data associated with the event trigger

 This will get called after triggering the associated event


 In extended class, the user can override this method to implement any post-
trigger functionality

UVM TLM

Transaction-Level Modeling (TLM) is used for communication among modules.


TLM is the concept in which transaction based methods are implemented, these
methods can be used for communication between the modules.

The UVM provides TLM library with transaction-level interfaces, ports, exports,
imp ports, and analysis ports. all these TLM elements are required to send a
transaction, receive transaction, and transport from one component to another.
where each one plays its unique role.

 TLM Interfaces consists of methods for sending and receiving the


transaction
 All different types of TLM Ports are used like PIPES to connect between the
components

The UVM TLM library provides,

 TLM1 – The TLM1 ports provide blocking and non-blocking pass-by-value


transaction-level interfaces.

 TLM2 – The TLM2 sockets provide blocking and non-blocking transaction-


level interfaces with well-defined completion semantics.

 Sequencer Port – A push or pull port, with well-defined completion


semantics.

 Analysis – The analysis interface is used to perform non-blocking


broadcasts of transactions to connected components
Summary of UVM TLM

TLM1

UVM TLM provides unidirectional and bidirectional,

 TLM interfaces
 ports
 exports
 imp ports
 analysis portss
 FIFOs

Each TLM interface is either blocking, non-blocking, or a combination of these


two.

 Blocking – Blocking TLM methods call will not return until the transaction
has been successfully sent or retrieved

 Non-blocking – Non-Blocking TLM methods call attempts to convey a


transaction without consuming simulation time

 Combination – A combination interface contains both the blocking and


nonblocking variants.
UVM TLM Interface

The TLM Interface class declares all the methods required to perform
communication.

put

 put method is used to send a transaction to another component


 Calling <port>.put(trans) sends a transaction to other component
 put() method call is a blocking call. It will not return until the transaction
has been successfully sent

get

 get method is used to retrieve transaction from another component


 Calling <port>.get(trans) retrieve transaction from other component
 get() method call is a blocking call. It will not return until the transaction
has been successfully retrieved
 get() method call consumes the transaction. i.e like how FIFO get method
will takeout the entry from FIFO
 Subsequent calls to get must return a different transaction instance. Means
as the previous get will takeout the trans, new trans is expected

peek

 peek method obtain a transaction without consuming it


 Calling <port>.peek(trans) retrieve transaction from other component
 peek() method call is a blocking call.
 The returned transaction is not consumed. A subsequent peek or get will
return the same transaction

try_put

 the try_put method is used to send a transaction to another component


without blocking the execution
 Calling <port>.try_put(trans) sends a transaction to another component, if
possible
 try_put method returns 1 If the component is ready to accept the
transaction, otherwise it returns 0
can_put

 can_put() method call returns 1 if the component is ready to accept the


transaction, otherwise, it returns 0
 no argument must be passed to can_put, this method is used to see
whether the other component is ready to accept the trans

try_get

 the try_get method is used to retrieve transaction from another


component without blocking the execution
 Calling <port>.try_get(trans) retrieve transaction from another component,
if possible
 try_get method returns 1 if the transaction is available, otherwise, it
returns 0

can_get

 can_get() method call returns 1 if the component can get transaction


immediately, otherwise, it returns 0
 no argument must be passed to can_get, this method is used to see
whether any transaction is available to get

transport

 Calling <port>.transport(req,resp) method executes the given request and


returns the response in the given output argument
 The transport method call is blocking, it may block until the operation is
complete

nb_transport

 Calling <port>.nb_transport(req,resp) the method executes the given


request and returns the response in the given output argument, if possible
 If for any reason the operation could not be executed immediately, then a
0 must be returned, otherwise 1
UVM TLM Export

 The TLM Export is a port that forwards a transaction from a child


component to its parent
 The TLM Export has unidirectional and bidirectional ports
 An export can be connected to any compatible child export or imp port. It
must ultimately be connected to at least one implementation of its
associated interface

TLM Export Classes


uvm_*_export#(T) //unidirectional export class

uvm_*_export #(REQ,RSP) //bidirectional export class

Type parameters,

 T – The type of transaction to be communicated by the export


 REQ – The type of request transaction to be communicated by the export
 RSP – The type of response transaction to be communicated by the export

Export Methods

new

This is a constructor method used for the creation of TLM Export.

function new (string name,


uvm_component parent,

int min_size=1,

int max_size=1);

UVM TLM Port

 The TLM Port is used to send the transactions


 TLM Ports has unidirectional and bidirectional ports
 A port can be connected to any compatible port, export, or imp port

TLM Port Classes


uvm_*_port #(T) //unidirectional port class

uvm_*_port #(REQ,RSP) //bidirectional port class

Type parameters,

 T – The type of transaction to be communicated by the port, type T is


not restricted to class handles and may be a value type such as int, enum,
struct or similar
 REQ – The type of request transaction to be communicated by the port
 RSP – The type of response transaction to be communicated by the port

Port Methods

new

This is a constructor method used for the creation of TLM Port.


function new (string name,

uvm_component parent,

int min_size=1,

int max_size=1);

The name and parent are the standard uvm_component constructor arguments.

UVM TLM Imp Port

 The TLM Imp Port is used to receive the transactions at destination


 TLM Imp Ports has unidirectional and bidirectional ports

TLM Imp Port Classes


uvm_*_imp #(T,IMP) //unidirectional Imp port class

uvm_*_imp #(REQ, RSP,

IMP, REQ_IMP, RSP_IMP) //bidirectional Imp port class

Type parameters,

 T – The type of transaction to be communicated by the imp


 IMP – The type of the component implementing the interface. That is the
class to which this imp will delegate.
 REQ_IMP – The component type that implements the request side of the
interface. Defaults to IMP. For master and slave imps only.
 RSP_IMP – The component type that implements the response side of the
interface. Defaults to IMP. For master and slave imps only.
Port Methods

new

This is a constructor method used for the creation of TLM Imp Port.

Transport imp constructor


function new(string name, IMP imp)

Master and slave imp constructor


function new(string name, IMP imp,

REQ_IMP req_imp=imp, RSP_IMP rsp_imp=imp)

The name and parent are the standard uvm_component constructor arguments.

UVM TLM FIFO

The TLM FIFO provides storage for the transactions between two independently
running processes

 In TLM FIFO, the sender pushes the transactions to FIFO and whenever it
required reiver pops it out or fetches from the FIFO
 Transactions are put into the FIFO via the put_export method
 Transactions are fetched from the FIFO via the get_peek_export method
 As its FIFO (First In First Out), transactions are fetched from the FIFO in
the order they are put
TLM FIFO Classes
uvm_tlm_fifo #(T)

This class provides storage of transactions between two independently running


processes

TLM FIFO Methods

new

This is a constructor method used for the creation of TLM FIFO

function new (string name,

uvm_component parent,

int size=1);

The name and parent are the normal uvm_component constructor arguments
The size indicates the maximum size of the FIFO; a value of zero indicates no
upper bound

size

Calling size() returns the size of the FIFO


A return value of 0 indicates the FIFO capacity has no limit

used

Returns the number of entries put into the FIFO

is_empty

Returns 1 when there are no entries in the FIFO, 0 otherwise

is_full

Returns 1 when the number of entries in the FIFO is equal to its size, 0 otherwise

flush

Calling flush method will Remove all entries from the FIFO
after the flush method call used method returns 0 and the is_empty method returns
1
Summary of TLM FIFOs

UVM Basic TLM Communication

TLM Communication

TLM is used for communication among the components. The most basic TLM
operation allows one component to sends a transaction packet to another
component.

TLM Symbolic Representation

It’s allowed to connect,

 port-to-imp
 port-to-port
 port-to-export
 export-to-export
 export-to-imp
Introduction to UVM RAL

Introduction to UVM Register Model

The UVM Register Layer provides a standard base class libraries that enable users
to implement the object-oriented model to access the DUT registers and memories.
UVM Register Layer is also referred to as UVM Register Abstraction Layer
(UVM RAL).
Advantages of UVM RAL

The advantages of UVM RAL Model are,

 Provides high-level abstraction for reading and writing DUT registers. i.e, registers can be
accessed with its names
 UVM provides a register test sequence library containing predefined test cases these can be
used to verify the registers and memories
 register layer classes support front-door and back-door access
 Design registers can be accessed independently of the physical bus interface. i.e by calling
read/write methods
 The register model can be accessed from multiple concurrent threads. it internally serializes
the access to the register.
 Reusability, RAL packages can be directly reused in other environments
 Uniformity, Defines the set of rules or methodology on register access, which can be
followed across the industry
 Automated RAL model generations, Tools or open-source scripts are available for RAL Model
generation

UVM Register Model Overview

The register model is composed of a hierarchy of blocks that map to the design
hierarchy, which means the RAL model consists of equivalent which will refer to
the design register fields, registers, and memory.
RAL Building blocks

 Register block
 Register file
 Register
 Register Filed

Each is explained in detail below,

Register Block

The reg block is written by extending the uvm_reg_block.

A block corresponds to a design component/hierarchy with its own interface(s), registers,


register files, memories, and sub-blocks.

In simple words, a block can be referred to as a design module with its own interface(s),
registers, register files, memories, and sub-blocks. And it will be having unique address
decoding to route the access to it.
A register model is an instance of a register block, which may contain any number of
registers, register files, memories, and other blocks.

Register File

The reg file is written by extending the uvm_reg_file.

The reg file shall be used to group the number of registers or register files. below block
diagram shows the register file consists of reg_file_0, reg_file_1 and reg_file_2. and each
register file consists of a set of registers. ( registers are shown only in reg_file_2, Assume that
there are registers in reg_file_0 and reg_file_1 )

UVM Register File

Register

The uvm register class is written by extending the uvm_reg.


A register represents a set of fields that are accessible as a single entity.

Each register contains any number of fields, which mirror the values of the corresponding
elements in hardware.

Register Field

The register field is declared with the type uvm_reg_filed.

Fields represent a contiguous set of bits. All data values are modeled as fields. A field is
contained within a single register but may have different access policies. access policies are
explained in the next sections.

UVM Reg Field

Complete Register Model block diagram


UVM RAL Methods

APIs can either use front door access or back door access to DUT registers and
register fields.

 Front door access involves using the bus interface and it is associated with
the timing
 Back door access uses simulator database access routines and this happens
in zero simulation time

API methods

read and write

 read() returns and updates the value of the DUT register.


 write() writes and updates the value of the DUT register.
 both read and write can be used for front door access or back door access.

peek and poke

 peek() reads the DUT register value using a backdoor


 poke() writes a value to DUT register using backdoor

set and get

 set() and get() writes and reads directly to the desired value.
 set and get methods operates on the register model desired value, not
accesses to DUT register value. The desired value can be updated to the
DUT using the update method.
update

 if there is a difference between desired value and mirrored value,update()


will initiate a write to register.update method can be used after the set metho
mirror

 mirror() reads the updated DUT register values. The mirroring can be
performed in the front door or back door( peek() ).

randomize

 randomize() randomizes register or field values with or without


constraints.as per the requirement register values can be modified in
post_randomize().after randomization update() can be used to update the
DUT register values.

reset

reset() sets the register desired and mirrored value to the pre-defined reset value
Constructing Register Model

Register Field

Register fields are declared with uvm_reg_field class type.


uvm_reg_field reg_name;

 Register fields are declared in register class


 The field name must be unique within the scope of its declaration
 The access policy of a field is specified using the uvm_reg_field::configure()
method
 Configure method has to be called from the build() method of the register
that instantiates it (refer to register example)

Register

The register is constructed by writing a class extended from the uvm_reg class.
There must be one class per unique register type
class my_reg extends uvm_reg;
rand uvm_reg_field Field_0;
rand uvm_reg_field Field_1;
endclass

 The name of the register type class must be unique within the scope of its
declaration
 The uvm_reg_field::configure() method shall be called from the register
type build method
class my_reg extends uvm_reg;
virtual function build();
this.Field_0 = my_reg::type_id::create(
.name(“Field_0”),
.parent(null),
.contxt(get_full_name()));
this.Field_0.configure(this, ...);
endfunction
endclass

Register File

A register file type is constructed by writing a class extended from


the uvm_reg_file class
class my_reg_file extends uvm_reg_file;
`uvm_object_utils(my_reg_file)
endclass
 The name of the register file type class must be unique within the scope of
its declaration
 Register files can contain other register files.
 The build() method shall call the configure() method for all register and
register file class properties
 specifying get_block() for the parent block and this for the parent register
file
class reg_file extends uvm_reg_file;

virtual function build();


uvm_reg_block blk = get_block();
this.rf = reg_file_0::type_id::create(
.name($psprintf(“%s.rf1”, get_name())),
.parent(null),
.contxt(blk.get_full_name()));
this.rf.configure(get_block(), this, ...);
this.rf.build();
this.rf.add_hdl_path();
endfunction

endclass

map() Method

 A virtual map() function, with uvm_reg_map and address offset arguments


map() method shall call uvm_reg_map::add_reg() for all register class
properties, adding the value of the address offset argument to the offset of
the register in the register file map() method shall call the map() method of
all register file class properties, adding the value of the address offset
argument to the offset of the register file base offset
 The map() method may call the add_hdl_path() method for all register or
register file class properties
virtual function map(uvm_reg_map mp, uvm_reg_addr_t offset);
mp.add_reg(this.reg_0, base_addr + 'h0);
mp.add_reg(this.reg_1, base_addr + 'h4;
this.rf.map(mp, base_addr + 'h100);
endfunction

set_offset() Method

 A virtual set_offset() function, with a uvm_reg_map and address offset


arguments, may also be implemented
 The set_offset() method shall call the set_offset() method for all register
and register file class properties
virtual function set_offset(uvm_reg_map mp, uvm_reg_addr_t offset);
this.reg_0.set_offset(mp, base_addr + 'h0);
this.reg_1.set_offset(mp, base_addr + 'h4);
this.rf.set_offset(mp, base_addr + 'h100);
endfunction

Memory Types

 A memory type is constructed using a class extended from the uvm_mem


class
 The name of the memory type class must be unique within the scope of its
declaration
class my_mem extends uvm_mem;
`uvm_object_utils(my_mem)
endclass

Register Block

 A block is constructed by writing a class extended from the uvm_reg_block


class
 The name of the block type class must be unique within the scope of its
declaration
class my_blk extends uvm_reg_block;
`uvm_object_utils(my_blk)
endclass

The block type must contain a class property for each,

 named address map


 register
 register file
 memory
 sub-block

 These shall have the rand attribute


 The build() method shall instantiate all named address maps by calling the
uvm_reg_block::create_map() method

Packaging a Register Model

The following practices are recommended, but not required.

 Block types, and all the register, register file, and memory types they
require, should be located in separate packages
 Register, register file, and memory types shared by more than one block
type should be located in separate packages
 A header file, with all the required import statements to use the register
model, should be generated
 A lengthy build() method may be split into several, shorter sub-methods.
The sub-methods shall be declared local and called by the build() method

Integrating a Register Model

 A register model must be integrated with the bus agent


 The integration with the bus agent must only be done on root blocks
 Root blocks model the entire DUT and they are the only ones who have
access to and knowledge of the externally-visible address maps.i.e in the
environment of the testbench

UVM RAL Predictor

UVM RAL Predictor predicts the register access done through the register model
and updates the RAL Model registers. UVM RAL provides the base
class uvm_reg_predictor. uvm_reg_predictor updates the register model based
on observed transactions published by a monitor.

Implicit prediction

 Implicit prediction only requires the integration of the register model with
one or more bus sequencers
 Updates to the mirror are predicted automatically (i.e., implicitly) by the
register model after the completion of each read, write, peek, or poke
operation

Explicit prediction

 Explicit prediction requires the register model to be integrated with both


the bus sequencers and corresponding bus monitors
 In this mode, the implicit prediction is turned off and all updates to the
mirror are predicted externally (i.e., explicitly) by a uvm_reg_predictor
component, one for each bus interface
UVM RAL Adapter

The RAL adapter acts as a converter between the RAL model and Interface. It
converts transactions of RAL methods to Interface/Bus transactions.

UVM RAL reg2bus

 reg2bus method converts the RAL transactions to Interface (bus)


transactions

UVM RAL bus2reg

 bus2reg method converts the Interface (bus) transactions to RAL


transactions

Integrating RAL to Bus Agent

Once after the RAL implementation, RAL has to be connected with the Bus Agent.
This section describes connecting RAL with the sequencer and monitor of the bus.

Integrating Bus Sequencers

All integration approaches require a register model to be configured with one or


more bus sequencers.

The register model becomes a property of a uvm_reg_sequence subtype that


executes

 Directly on a bus sequencer, if there is only one bus interface providing


access to the DUT registers
 As a virtual sequence, if there are one or more bus interfaces providing
access to the DUT registers;
 As a register sequence running

Integrating the Register Model with a Bus Monitor

By default, the register model updates its mirror copy of the register values
implicitly. Every time a register is read or written through the register model, its
mirror value is updated.

If other agents on the bus interface perform read and write transactions outside the
context of the register model, the register model must learn of these bus operations
to update its mirror accordingly.
UVM Register Defines

UVM register library has the defines declared in it. these are being used in the
RAL model base classes, user can override these defines.

uvm_reg_defines are,

 `UVM_REG_ADDR_WIDTH
 `UVM_REG_DATA_WIDTH
 `UVM_REG_BYTENABLE_WIDTH
 `UVM_REG_CVR_WIDTH

UVM_REG_ADDR_WIDTH

 Maximum address width in bits


Default value is 64
 Used to define the uvm_reg_addr_t type

UVM_REG_DATA_WIDTH

 Maximum data width in bits


Default value is 64
 Used to define the uvm_reg_data_t type

UVM_REG_BYTENABLE_WIDTH

 Maximum number of byte enable bits


 Default value is one per byte in `UVM_REG_DATA_WIDTH
 Used to define the
uvm_reg_byte_en_t type

UVM_REG_CVR_WIDTH

 Maximum number of bits in a uvm_reg_cvr_t coverage model set


 Default value is 32
uvm barrier

The uvm barrier class enables synchronization control between the processes.

 uvm_barrier allows a set of processes to be blocked until the desired number


of processes get to the
 synchronization point
 Processes get released Once after all the process reaching synchronization
point

If the threshold is set to a value less than the number of currently waiting for
processes, then the barrier is reset and waiting processes are activated

The uvm_barrier class has below built-in methods,

 new
 set_auto_reset
 set_threshold
 get_threshold
 get_num_waiters
 wait_for
 reset
 cancel

uvm_barrier methods

new

function new (

string name = "",

int threshold = 0

Creates a new barrier object.

wait_for

virtual task wait_for()


This method call, Waits for enough processes to reach the barrier before
continuing.

set_threshold

virtual function void set_threshold (

int threshold

The number of processes to wait for is set by the set_threshold method.


This determines how many processes must be waiting on the barrier before the
processes may proceed.

get_threshold

virtual function int get_threshold ()

Gets the current threshold setting for the barrier.

get_num_waiters

virtual function int get_num_waiters ()

Returns the number of processes currently waiting at the barrier.

reset

virtual function void reset (

bit wakeup = 1

Resets the barrier. This sets the waiter count back to zero.
The threshold is unchanged. After reset, the barrier will force processes to wait for
the threshold again. If the wake-up bit is set, any currently waiting processes will
be activated.

set_auto_reset

virtual function void set_auto_reset (

bit value = 1
)

Determines if the barrier should reset itself after the threshold is reached.

cancel

virtual function void cancel ()

Decrements the waiter count by one. This is used when a process that is waiting on
the barrier is killed or activated by some other means.

uvm_barrier usage

Using uvm_barrier involves below methods,

1. Declare and create the uvm_barrier


2. Set the process to be waiting
3. Calling wait_for() method inside the process

uvm_heartbeat

UVM_heartbeat watches for an activity in the test bench and if it finds that there
is no activity in the specified interval of time, then uvm_heratbeat issue a fatal
message which leads to the end of the simulation.

What are the benefits of using the uvm_heartbeat?

As mentioned earlier uvm_heartbeat identifies the simulation hang situation and


terminates the run,

 which will help in identifying the component which is cause for deadlock
 saves the simulation time and releases the resources by early termination
of simulation

How to use the uvm_heartbeat?

It involves the below steps,


 Create the heart_beat object
 Set the components to be monitored
 trigger the heartbeat monitor

To make the above steps easy, the uvm_heartbeat has a set of inbuilt methods.

uvm_heartbeat methods

new

function new(

string name,

uvm_component cntxt,

uvm_objection objection = null

 Creates a new heartbeat instance associated with cntxt.


 The cntxt is the hierarchy of components to be monitored.
 The object of uvm_objections_callback type

set_heartbeat

function void set_heartbeat (

uvm_event#(uvm_object) e,

ref uvm_component comps[$]

This method sets a list of objects to be watched at event e.

set_mode

function uvm_heartbeat_modes set_mode (

uvm_heartbeat_modes mode = UVM_NO_HB_MODE

This method call Sets or retrieves the heartbeat mode.


the mode shall be,
UVM_ALL_ACTIVE – all components
UVM_ONE_ACTIVE – exactly one component
UVM_ANY_ACTIVE – any component

add

function void add (

uvm_component comp

The add method Adds a single component to the set of components to be


monitored.

remove

function void remove (

uvm_component comp

The Remove method removes a single component from the set of components
being monitored.

start

function void start (

uvm_event#(uvm_object) e = null

Calling the start method Starts the heartbeat monitor.

stop

function void stop ()

Calling stop method Stops the heartbeat monitor.

You might also like