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