You are on page 1of 34

Universal Verification

Methodology

Introduction to UVM

Need for a Methodology


What is
methodology?

Key Aspects of a Good Methodology

UVM
4

Need for UVM

Could not meet all verification interoperability needs


Vendors came up with their own methodologies
Synopsys came up with VMM
Cadence with URM
Mentor with AVM

OVM
Mentor and Cadence jointly came up with OVM(Open)
But synopsys users had a hard time

Each one different and not interoperable with each other

What does UVM address?

UVM
UVM Class Library

Universal Verification Methodology (UVM)


UVM

Open Source and Interoperable verification methodology


SV based test benches
jointly developed by Cadence , Mentor Graphics and Synopsys
Leverages on eRM for Specman and URM for SV developed by
Cadence, AVM for SV developed by Mentor Graphics and VMM
for SV by Synopsys

Coverage Driven Verification Framework with automatic


test generation
Reusable test bench architecture by providing a
consistent set of well defined interfaces through which
various test bench components interact with each other
Well established mechanisms for full integration of mixed
language models, VIPs, transaction-level and RTL
models
7

Benefits of UVM
TLM interfaces - reuse and modularity
UVC - Standardized architecture for all test bench
components
UVM Factory - Change the objects types during run time
High level of Flexibility and Configurability
Automatic test phasing of test bench components
Unified customizable messaging and reporting features
Powerful and Flexible Sequences

UVM Verification Component UVC

What is an UVC
Also called
as Agent

Universal
Verification
Component

10

UVC Summary
uvc consists of
Data item : For modeling transaction data
Driver : For driving the stimulus to the DUT
Sequencer : For generating transaction data sequences for the
driver
Monitor : For monitoring the activity on the DUT interface and
collect data for coverage
Agent : To emulate and verify DUT devices by combining driver,
sequencer and monior
Environment : Top level component of the uvc that
encapsulates one or more agents and other components

11

UVC Components
Agent
Contains instances of the sequencer,
driver and monitor
uvcs can contain more than one agent
Configurable as active or passive
Active agent can initiate transactions to
the DUT and react to signals from DUT.
Passive agent will never drive any DUT
signals. It mostly monitors an interface
or a group of DUT signals.
Example: Master/Slave agents, TX/RX
agents

12

Agent

UVC Components (Contd.).


Environment
Top-level component of the uvc
Contains one or more agents, as well as other components such as a
bus monitor
Contains configuration properties that enable you to customize the
topology and behavior and make it reusable

Environment

13

UVM Class Hierarchy


UVM Base Class
Library

14

UVM Factory

15

UVM Factory

16

uvm_factory is used to create UVM objects and components.


Factory Registration:
`uvm_object_utils(T) uvm_objects
`uvm_component_utils(T) - uvm_components
Factory Overriding: - Two Types
Create invokes
Set_type_override_by_type
function new() and
Set_inst_override_by_type
constructs according
to the factory
Factory provides a create() function
database
type_name::type_id::create(string name, uvm_component parent)
Objects are constructed dynamically
User can alter the behavior of the pre-build code without modifying
the code.

Component Overriding

17

Component Overriding Examples


set_type_override_by_type( driver::get_type(),
driver0::get_type());

set_inst_override_by_type(env. master0.* ,
driver::get_type(),
driver0::get_type());

18

TLM

19

What is TLM & TLM Interfaces (API)?

20

TLM Transaction Level Modeling

TLM is used for:


l
Architecture design and (performance) analysis
l
Reference model development
l
Functional verification

TLM API (Application Programming Interface)


l
Developed by Open SystemC Initiative (OSCI)
l
Standardize communication interface between TLM
components
l
Allow plug-and-play of TLM components

SystemVerilog implementation of TLM API: Cadence, Mentor

TLM Terminologies: Port/Export, Initiator/Target


txn_req

Verilog I/O

txn_rdy

Consumer

Producer
yapp packet

Target

TLM API

uvm_get_imp
uvm_get_export

Producer

Initiator
Symbols
yapp packet

uvm_get_port

Consumer

TLM port
TLM export

sub-component

uvm_get_imp

21

Port and export/imp are the equivalence of Verilog module ports


Port: specifies the API (TLM interface) required (by initiators)
Export: provides the implementation of the API (by targets)

TLM Put Port


Initiator
uvm_put_port

TLM API

Producer

Target
uvm_put_imp
Uvm_put_export

Consumer

Symbols
TLM port
TLM export

22

class producer extends uvm_component;


uvm_blocking_put_port #(simple_trans) put_port; // 1 parameter
function new( string name, uvm_component parent);
put_port = new(put_port, this);
...
endfunction
virtual task run();
simple_trans t;
for(int i = 0; i < N; i++) begin
// Generate t.
put_port.put(t);
end
endtask

TLM Put Export


Initiator
uvm_put_port

TLM API

Producer

Target
uvm_put_imp
uvm_put_export

Consumer

Symbols
TLM port
TLM export

The actual implementation of the put() call is supplied by the consumer.


class consumer extends uvm_component;
uvm_blocking_put_imp #(simple_trans, consumer) put_export; // 2 parameters
...
task put(simple_trans t);
case(t.kind)
READ: // Do read.
WRITE: // Do write.
endcase
endtask
endclass

23

TLM Get Port/Export Examples

Symbols
TLM port
TLM export

Producer

class get_producer extends


uvm_component;
uvm_blocking_get_imp
#(simple_trans, get_producer)
get_export;
...

task get(output simple_trans t);


simple_trans tmp = new();
// Assign values to tmp.
t = tmp;
endtask
endclass

24

Consumer

simple_trans

class get_consumer extends uvm_component;


uvm_blocking_get_port #(simple_trans)
get_port;
function new( string name, uvm_component
parent);
get_port = new(get_port, this);
...
Endfunction
virtual task run();
simple_trans t;
for(int i = 0; i < N; i++) begin
// Generate t.
get_port.get(t);
end
endtask

TLM Examples

Symbols
TLM port
TLM export

class tlm_example_top extends uvm_component;


yapp_m_producer producer;
yapp_m_consumer consumer;
`uvm_component_utils(tlm_example_top)
function new(string name="", uvm_component parent=null);
super.new(name, parent);
producer = new(producer", this);
consumer = new(consumer", this);
consumer.txn_req.connect(producer.txn_req);

txn_req

Producer

25

yapp packet

txn_req

Consumer

Communicating Between Processes


Scenarios like producer is creating transactions in one process while
the consumer needs to operate on those transactions in another
It may be necessary for components to operate independently
The tlm_fifo implements all of the TLM interface methods, so the
producer puts the transaction into the tlm_fifo, while the consumer
independently gets the transaction from the fifo
When the producer puts a transaction into the fifo, it will block if the fifo
is full, otherwise it will put the object into the fifo and return
immediately.
The get operation will return immediately if a transaction is available
(and will then be removed from the fifo), otherwise it will block until a
transaction is available

uvm_put_port

initiator
26

packet

tlm FIFO

packet

uvm_get_port

initiator

Communication Model
Producer

Consumer
Symbols

uvm_get_imp

packet

target
uvm_put_port

initiator

27

TLM port

initiator
packet

initiator
uvm_put_port

uvm_get_port

TLM export

uvm_put_imp

target
packet

tlm FIFO

packet

uvm_get_port

initiator

Connecting Transaction-Level Components


The actual connection between transaction-level components is
accomplished via the connect() method in the parent (component or
env),with an argument that is the object (port or export) to which it will be
connected
The series of connect() calls between ports and exports establishes a netlist
of peer-to-peer and hierarchical connections, ultimately terminating at an
implementation of the agreed-upon interface
class my_env extends uvm_env;
...
virtual function void connect();
// component.port.connect(target.export);
producer.blocking_put_port.connect(fifo.put_export);
get_consumer.get_port.connect(fifo.get_export);
...
endfunction
endclass
28

Hierarchical Connections

Initiator

29

Target

Connection E would be coded as:

Connection C would be coded as:

class consumer extends uvm_component;


uvm_put_export #(trans) put_export;
tlm_fifo #(trans) fifo;
...
function void connect();
put_export.connect(fifo.put_export); // E
bfm.get_port.connect(fifo.get_export); // F
endfunction
...
endclass

class producer extends


uvm_component;
uvm_put_port #(trans) put_port;
conv c;
...
function void connect();
c.put_port.connect(put_port);
...
endfunction

Hierarchical Connections (Contd.).


The following table summarizes connection types and elaboration
functions

Initiator -> Target

30

TLM Interfaces
n

Put interfaces

tlm_blocking_put_if #(type T=int)


put(T trans)

tlm_nonblocking_put_if
try_put(T trans), can_put()

Get interfaces

tlm_blocking_get_if
get(T trans)

tlm_nonblocking_get_if
try_get(output T trans), can_get()
Peek interfaces

tlm_blocking_peek_if
peek(output T trans)

tlm_nonblocking_peek_if
try_peek(output T trans), can_peek()

31

TLM FIFO

tlm_fifo:
Used for buffering transactions between producer(s) and
consumer(s)
Symbols
Implement the following TLM interfaces:
tlm_put_if
TLM port
tlm_get_if
TLM export
tlm_peek_if
Producer
put_port

initiator

32

Consumer
packet

tlm FIFO

packet

get_port

initiator

Analysis Communication -Monitors

Uvm_analysis_port - Port to multiple exports


consists of a single function, write().
contains a list of analysis_exports that are connected to it
If nothing is connected, the write() call simply returns. Thus, an analysis
port may be connected to 0, 1, or many analysis exports, but the
operation of the component that writes to the analysis port does not
depend on the number of exports connected.
n

Analysis interface

analysis_if #(type T=int)


write(input T t)
l
l
l

33

Non-blocking
Transaction T is broadcasted to zero, one, or multiple consumers
Intended for non-intrusive monitoring of transactions

Analysis Port/Export

Analysis
port

class get_ap_consumer extends


get_consumer;
uvm_analysis_port #(my_trans) ap;
function new(...);
super.new()
ap = new(analysis_port, this);
...
endfunction
task run;
...
for(int i=0; i<10; i++)
if(get_port.try_get(t)) begin
//Do something with t.
ap.write(t); // Write transaction.
...
end
endtask
34

class sub1 extends uvm_subscriber ;


uvm_analysis_imp #(simple_trans, sub1) aimp;
function void write(T t);
// Record coverage information of t.
endfunction
endclass
class my_env extends uvm_env;
get_ap_component g;
sub1 s1;
sub2 s2;
...
function void connect();
g.ap.connect(s1.aimp);
g.ap.connect(s2.aimp);
...
endfunction
endclass

You might also like