TB Components
➢ UVM Sequencer
➢ UVM Driver
➢ UVM Monitor
➢ UVM Agent
➢ Environment
➢ Test
➢ Top
UVM Sequencer
• The uvm_sequencer act as a routing component
between sequence and driver
• User sequencer is extended from uvm_sequencer
bass class
• It is parametrized with REQ, RSP
▪ REQ
▪ RSP
are the handles of uvm sequence item
uvm_sequencer #(type REQ=uvm_sequence_item,RSP=REQ)
EXAMPLE
class ram_sequencer extends uvm_sequencer #(write_xtn)
Sequencer Driver Connection
• Seq_item_port ,Seq_item_export are the builtin tlm
interface in uvm_sequencer and uvm_driver .
• It gets inherit to ram_sequencer and ram_driver.
• seq_item_port is the handle of
uvm_seq_item_pull_port present in uvm driver class
• seq_item_export is the handle of
uvm_seq_item_pull_imp present in uvm sequencer
class
• Both seq_item_port and seq_item_export are used for a
bidirectional communication .
• Driver get the data through seq_item_port
• Sequencer provide a data through seq_item_export.
• Driver seq_item_port connected to a
sequencer seq_item_export.
• seq_item_port, seq_item_export are comes under
TLM 2.0.
• put_port , put_imp, get_port, get_imp are comes under
TLM 1.0
UVM Driver
• Fetches data repeatedly from a sequencer
• Declare a virtual interface in a driver to connect the
driver to dut.
• Driver can be derived from a uvm_driver base class
• It is parametrized with REQ and RSP
Run phase (3 methods)
forever
begin
// get the next data item from sequence
seq_item_port.get_next_item(req)
//execute the item to dut
Drive_item(req)
//consume the request
Seq_item_port.item_done()
End
Querying for next item
➢ get_next_item()
➢ try_next_item()
get_next_item()
It is blocking method .
It going to call item_done explicitly.
Try_next_item()
It is a non blocking method.
It is used inside a if else condition
Get()
It is a blocking method.
It going to call item_done implicitly so it is not
recommended.
Example
class my_driver extends uvm_driver #(my_data);
`uvm_component_utils (my_driver)
virtual dut_if vif;
function new (string name, uvm_component parent);
super.new (name, parent);
endfunction
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
if (! uvm_config_db #(virtual dut_if) :: get (this, "", "vif",
vif))
begin
`uvm_fatal (get_type_name (), "Didn't get handle to
virtual interface dut_if")
end
endfunction
task run_phase (uvm_phase phase);
my_data data_obj;
super.run_phase (phase);
forever begin
`uvm_info (get_type_name (), $sformatf ("Waiting for
data from sequencer"), UVM_MEDIUM)
seq_item_port.get_next_item (data_obj);
drive_item (data_obj);
seq_item_port.item_done ();
end
endtask
virtual task drive_item (my_data data_obj);
// Drive based on bus protocol
endtask
endclass
Sending data to Sequencer
▪ item done() and put_response() provide a response back to
sequencer from a driver
▪ It is a non blocking method
▪ In driver we use put_response() there should be a
get_response in a sequencer.
▪ rsp_port, rsp_export is a builtin analysis interface present
in sequencer and driver.
▪ rsp_port is a handle of uvm_analysis port
▪ rsp_export is a handle of uvm_analysis Export
seq_item_port.item_done()
seq_item_port.put_response(rsp)
rsp_port.write(rsp)
are used in driver send a response back to the sequencer
UVM MONITOR
▪ It samples a data through Virtual Interface.
▪ It is not a parametrized class.
▪ Monitor is connected to other components such as
scoreboard, coverage checker, etc via Standard tlm
interfaces Analysis ports and exports.
To create a monitor
➢ Monitor is extends from a uvm_monitor .
➢ Derive a virtual interface in the monitor to the
connect a monitor to DUT .
➢ Declare a analysis port
➢ Obtain a data item from the interface and send
it to the score board.
Example
class my_monitor extends uvm_monitor ;
`uvm_component_utils(my_monitor)
virtual ram_if vif;
ram_config m_tb_cfg;
wr_xtn data;
uvm_analysis_port#(write_xtn) monitor_port;
function new(string name ,uvm_component parent);
super.new(name,parent);
monitor_port=new(“monitor_port ”,this);
endfunction
function build_phase (uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db #(ram_config)::get
(“this”, “”, “ram_config”, m_tb_cfg));
`uvm_fatal(“get_type_name()”, “cannot get from the
ram_config”)
endfunction
function connect_phase(uvm_phase phase);
super.connect_phase(phase);
vif=m_tb_cfg.vif;
endfunction
task run_phase(uvm_phase phase );
data= write_xtn::type_id::create(“data”);
forever
collect_data();
endtask
task collect_data();
………………….
endtask
endclass
UVM_AGENT
▪ Agent is extends from a uvm_agent.
▪ An agent encapsulates
a Sequencer, Driver and Monitor into a single entity by
instantiating and connecting the components together via
TLM interfaces.
▪ Since UVM is all about configurability, an agent can also
have configuration options like the type of UVM agent
(active/passive), knobs to turn on features such as
functional coverage, and other similar parameters.
Types of Agents
Active
➢ Instantiates all three components [Sequencer,
Driver, Monitor].
Passive
➢ Instantiates only monitor.
Creating Agents
➢ Write_agent is extends from uvm_agent.
➢ Instance a driver, monitor, sequencer inside a agent
class.
➢ In build phase create a object for a monitor . If
is_active flag is set to UVM_ACTIVE ,construct the
driver and sequencer.
➢ If is_active is set to uvm_active in connect_phase()
method connect a driver and sequencer .
Example
Class my_agent extends uvm_agent;
ram_driver driver;
ram_monitor monitor;
ram_sequencer sequencer ;
ram_config m_tb_cfg;
function void build_phase (uvm_phase phase);
if(!uvm_config_db #(ram_config)::get(this, “”,
“ram_config”,m_tb_cfg))
`uvm_fatal(“get_type_name”, “cannot get()
from the uvm_config ”)
Monitor=ram_monitor::type_id::create(“monitor”,this);
if(m_tb_cfg.is_active==uvm_active)
begin
Sequencer=ram_sequencer::type_id::create(“sequencer”,
this);
driver =ram_driver::type_id::create(“driver”,this);
end
endfunction
function void connect_phase(uvm_phase phase);
if(m_tb_cfg.is_active==uvm_active)
begin
driver.seq_item_port.connect(sequencer.seq_item_export);
end
endfunction
UVM Environment
A UVM environment contains multiple, reusable
verification components and defines their default configuration
as required by the application.
For example, a UVM environment may have multiple
agents for different interfaces, a common scoreboard, a
functional coverage collector, and additional checkers.
Creating Environment
▪ my_env extends from a uvm_env.
▪ Declare a instances of all the agents inside a class .
▪ build phase() method in the environment class construct
all the agents .
Example
Class my_env extends uvm_env;
Ram_write_agent write_agent;
Ram_read_agent read_agent ;
Ram_config m_tb_cfg;
Function void build_phase (uvm_phase phase );
Super.build_phase(phase);
if(!uvm_config_db #(ram_config)::get(this, “”,
“ram_config”,m_tb_cfg))
`uvm_fatal(“get_type_name”, “cannot get()
from the uvm_config ”)
if(m_tb_cfg.has_write_agent)
write_agent=ram_write_agent::type_id::create
(“write_agent”,this)
if(m_tb_cfg.has_read_agent)
read_agent=ram_read_agent::type_id::create(“
read_agent”,this)
endfunction
UVM_TEST
A testcase is a pattern to check and verify specific
features and functionalities of a design.
A verification plan lists all the features and other
functional items that needs to be verified, and the tests neeeded
to cover each of them.
Creating test
▪ The user-defined test is derived from uvm_test.
▪ Declare a instances of env /agent inside a class.
▪ In build_phase construct all the environment.
▪ In build_phase configure all the parameters.
Example
Class my_test extends uvm_test;
Ram_env env_h;
Ram_config m_tb_cfg;
Function void build_phase (uvm_phase phase);
m_tb_cfg=ram_config::type_id::create(“m_tb_cfg”,
this);
m_tb_cfg.has_write_agent=1;
if(!uvm_config_db #(virtual ram_if)::get(this, “”,
“virtual ram_if”,m_tb_cfg.vif))
`uvm_fatal(“get_type_name”, “cannot get()
Interface from the uvm_config ”)
Uvm_config_db #(ram_config)::set(this, “env”,
“ram_config ”,m_tb_cfg)
Env=ram_env::type_id::create(“env”,this);
Endfunction
UVM Top
Typical Tes_top contains,
• DUT instance
• interface instance
• run_test() method
• virtual interface set config_db
• clock and reset generation logic
• declare a instance of test
Example
module tbench_top;
bit clk;
bit reset;
always #5 clk = ~clk;
initial begin
reset = 1;
#5 reset =0;
end
mem_if intf(clk,reset);
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)
);
initial begin
uvm_config_db#(virtual mem_if)::
set(uvm_root::get(),"*","mem_intf",intf);
end
initial begin
run_test();
end
endmodule