UVM Class Notes Deepak Kumar Panda
UVM Class Notes Deepak Kumar Panda
What is Methodology?
.❖ Best practices by verification experts
l
• The primary advantage is that the methodology specifies and lays out a set of
guidelines to be followed for creation of verification testbenches.
• This will ensure testbench uniformity between different verification teams,
cross-compatability between IP and standalone environment integration,
flexibility and ease of maintaining testbenches.
• For example, there can be many different ways to implement display messages
and control verbosity with different settings such as warning, error and debug.
• In UVM, the underlying reporting mechanism has been standardized and made
available so that engineers can instead focus on the most important part of their
job which is design verification.
• Another example is that the sequencer-driver handshake mechanism is taken
care of under the hood so that only stimulus needs to be written.
• This saves quite a lot of time in setting up a testbench structure since the
foundation itself is well defined.
How does UVM help ?
• The idea behind UVM is to enhance flexibility and reuse code so that the same testbench
can be configured in different ways to build different components, and provide different
stimulus.
• These new user defined configuration classes are recommended to be derived from
uvm_object .
• For example, a configuration class object can be built to have certain settings that define
how the testbench environment has to be built.
UVM Sequence
❖ component hierarchy,
❖ configuration database,
which enable the user to create virtually any structure for the
testbench.
Features of uvm_component Class
❖ hierarchy searching,
❖ phasing,
❖ configuration,
❖ reporting,
❖ factory,
❖ transaction recording
UVM Building Blocks
.
l
UVM UVM
UVM env
Components test
UVM Testbench
.
l
UVM Test
Sequences
UVM Environment
UVM Agent
UVM
Sequencer UVM Agent Design
UVM
Under Test
UVM
Scoreboard Environment ( DUT )
UVM
Config/Factory Environment
Overrides
UVM Testbench Architecture
Module TOP
UVM Test
UVM Env
Agent [0]
Sequencer Config
Config Interface
Sequencer [0]
Scoreboard 0
Scoreboard 0 Driver Driver
MonitorMonitor
Agent [1]
Config
Config Interface
Sequencer
Sequencer
[1]
Scoreboard 1
Scoreboard 1 Driver Driver
MonitorMonitor
➢ Instantiate
● Design under Test (DUT) module
● UVM Test class
➢ Dynamically Instantiate
● UVM Test
➢ Advantage
● compiled once
● run with many different tests.
UVM Test
----------------------
endclass
➢ So uvm_test is a component.
UVM Environment
Agent/UVC
Mem Controller Agent DUT
Component
Repository
UVM
UVM Driver
Sequencer Memory
Controller
UVM Monitor
Peripheral Agent
UVM
UVM Driver
Sequencer
Peripheral
UVM Monitor
UVM Environment
----------------------
endclass
➢ So uvm_env is a component.
UVM Environment (Example)
➢ UVM Agent
● Encapsulated, Ready to use, Configurable components
● Reusable - plug and play
Sequence
UVM Agent
UVM
UVM Driver
Sequencer
DUT
UVM Monitor interface
UVM Agent
● Sequencer
■ Manage stimulus flow
■ Route sequence_items from a sequence to the driver
● Driver
■ It converts sequence_item into the pin level for DUT
● Monitor
■ It converts pin level data to the transactions for use in scoreboard, coverage
models, etc
UVM Agent
● Other components
■ coverage collectors,
■ protocol checkers,
■ TLM mode
UVM Agent
----------------------
endclass
➢ So uvm_agent is a component.
UVM Agent
Interface
Config
DUT is_active = 0
UVM
Agent Monitor
vi
(Passive)
UVM
UVM
Sequen vi
Driver
Interface
cer
Config
DUT
is_active = 1
UVM
Agent Monitor
vi
(Active)
UVM Agent
● an active mode
● a passive mode
----------------------
endclass
➢ So uvm_sequencer is a component.
UVM Sequence
----------------------
endclass
➢ So uvm_sequence is a object.
UVM Driver
➢ TLM port
● Receive transactions from the Sequencer
● Access to the DUT interface in order to drive the signals.
UVM Driver
----------------------
endclass
➢ So uvm_driver is a component.
UVM Monitor
----------------------
endclass
➢ So uvm_sequence is a component.
UVM Scoreboard
• Receives data item’s from monitor’s and compares with expected values.
Summary : UVM Testbench Overview
.1. UVM Testbench
l
2. UVM Test
3. UVM Environment
4. UVM Agent
5. UVM Sequencer
6. UVM Sequence
7. UVM Driver
8. UVM Monitor
Thank You
Questions ??
UVM Sequencer
• The DUT used is a simple ALU, limited to a single operation: the add
operation. The inputs and outputs are represented in Figure.
• This DUT takes two values of 2 bits each, ina and inb, sums them and
sends the result to the output out.
• The inputs are sampled to the signal of en_i and the output is sent at
the same time en_o is signalled.
• Right now, we have a DUT and we will have to interact with it in
order to test its functionality, so we need to stimulate it.
• To achieve this, we will need a block that generates sequences
of bits to be transmitted to the DUT, this block is going to be
named sequencer.
• UVM uses the concept of factory where all the objects are
registered with it so that it can return an object of the
requested type when required.
• The utility macros help to register each object with the factory.
• UVM also introduces a bunch of automation mechanisms for
implementing print (/uvm/uvm-object-print) , copy (/uvm/uvm-
object-copy-clone) , and compare (/uvm/uvmobject-compare)
objects and are defined using the field macros.
Utility Macros
FLAG Description
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;
How to write uvm sequence
body Method:
• body method defines, what the sequence does.
m_sequencer Handle:
• The m_sequencer handle contains the reference to the
sequencer on which the sequence is running.
• The sequence will get executed upon calling the start of the
sequence from the test
sequence_name.start(sequencer_name);
sequencer_name specifies on which sequencer sequence has to
run.
• There are Methods, macros and pre-defined callbacks
associated with uvm_sequence.
• Users can define the methods(task or function) to pre-defined
callbacks.
• these methods will get executed automatically upon calling the
start of the sequence.
• These methods should not be called directly by the user.
Starting The Sequence:
Communication between the Sequence and driver
involves below steps,
1.create_item() / create req.
2.wait_for_grant().
3.randomize the req.
4.send the req.
5.wait for item done.
6.get response.
Method Call Description
Create and initialize* a sequence_item or
create_item() sequence
req = **_seq_item::type_id::create(“req”); *initialize – initialized to communicate with the
specified sequencer
This method call is
blocking, Execution will be blocked until the
method returns.
1.This method issues a request to the current
wait_for_grant()
sequencer
2.The sequencer grants on getting
get_next_item() request
from driver
This method is to randomize the
req.randomize()
sequence_item
Send the request item to the sequencer,
send_request(req,re-randomize) which will forward it to the driver.
re-randomize = 0 or If the re-randomize the bit is set, the item will
re-randomize = 1; be randomized before being sent to the
driver.
This call is optional.
wait_for_item_done() This task will block until the driver calls
item_done or put.
Returns the request item currently being
executed by the sequencer.
get_current_item()
If the sequencer is not currently executing an
item, this method will return null.
get_response(rsp) receives the response from driver.
• The sequence englobes a group of transactions and the
sequencer takes a transaction from the sequence and takes it
to the driver.
• To test our DUT we are going to define a simple transaction,
extended from uvm_sequence_item.
• It will include the following variables:
rand bit[1:0] ina
rand bit[1:0] inb
bit[2:0] out
• The code for the sequencer is very simple, this line will tell UVM to
create a basic sequencer with the default API because we don’t
need to add anything else.
• You might have noticed two things missing:
• How does the sequence connects to the sequencer?
• How does the sequencer connects to the driver
• The connection between the sequence and the
sequencer is made by the test block, we will come to
this later on chapter 10, and the connection between
the sequencer and the driver will be explained on
chapter 7.
Driver
• T is the type of element being configured. Type can be scalar objects, class
handles, queues, lists, or even virtual interfaces)
• cntxt is the hierarchical starting point of where the database entry is
accessible.
• inst_name is a hierarchical path that limits the accessibility of the database
entry.
example:
• top.env.agent.monitor
top.* – all of the scopes whose top-level
component is top.
top.env.*.monitor – all of the scopes in env that end
in the monitor;
• field_name is the label used as a lookup for the
database entry
• value is the value to be stored in the database
uvm_config_db set example
uvm config db get method
• value is the variable to which the value is to be retrieved from the database
• The method returns 1 if it is successful and 0 if there is no such resource of this type
in the database.
• .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.
UVM Phases top down
• the run phase is implemented as a task and remaining all are function.
• Phases can be grouped into 3 categories,
1. Build Phases
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.
Writing Driver :
5. Add driving logic. get the seq_item and drive to DUT signals,
complete drive code
1. The monitor is written by extending the UVM_MONITOR,
5. Declare seq_item handle, Used as a place holder for sampled signal activity,
UVM Monitor
Active agent
4. Connect the driver seq_item_port to sequencer seq_item_export for communication between driver and
sequencer in the connect phase.
Complete Agent code,
UVM Scoreboard
Writing Scoreboard
The scoreboard is written by extending the UVM_SCOREBOARD.
• 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
write method of the scoreboard will receive the transaction packet from the
monitor, on calling write method from the monitor.
UVM scoreboard code
UVM Environment
3. Create an agent,
Complete environment code
UVM 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.
Writing Test
• If directions of data and control flow agree, producer puts transaction into
consumer:
• If directions of data and control flow disagree, consumer gets transaction from the
producer:
No matter if it is put or get situation, the process with export (the executor) is
responsible for implementation of the transaction; requester is using its port
to call services of the executor.
TLM Fifo [uvm_tlm_fifo]
• Assume data rate of the sender is much faster than the rate at which the
receiver can get packets.
• A FIFO element is required in between to store packets so that it allows
both the sender and the receiver to independently operate.
• TLM FIFO is used to synchronize data flow between producer and
consumer.
• Depth of the FIFO is typically calculated based on the rate of data transfer.
A TLM FIFO is placed in between testbench components that transfer data
objects at different rates.
TLM Analysis Port
Agent
• There are predefined UVM verbosity settings built into UVM (and
OVM).
• The settings actually have integer values that increment by 100 as
shown below.
• By default, when running a UVM simulation, all messages with
verbosity settings of UVM_MEDIUM or lower (UVM_MEDIUM,
UVM_LOW and UVM_NONE) will print.
Scoreboard
• phase.raise_objection(this);
• seq.start(sa_seqr);
• phase.drop_objection(this);