In the previous session, we had a simple testbench structure with only test and environment.That was just enough to utilize a UVM component, and print "Hello UVM". But, in a normal testbench we would have a data element that gets routed through different verification components. So, in this part, we will create a "data" packet object and send it to the "driver".
As you might know already, data packet encapsulates a lot of information into a single entity - a class object. We may not need all the information in the data object to drive signals to DUT. The driver obtains the data packet and extracts the required information and converts it into the pin-wiggles of DUT interface.
GitHub
You can download/clone uvm-201 from repository.
TestBench
We have added two more elements to the environment
- Data Object
- Driver


Let us discuss on the new additions
Data
A data packet should be extended from uvm_sequence_code
so that it can interact with a uvm_sequencer
. Since our design element is a simple memory element, we only need address and data to be captured inside the data class. We also have a custom function to display data values. Note that this class has been registered with the factory as `uvm_object_utils
because it is a derivative of uvm_sequence_item
(another derivative of uvm_object
).
class my_data extends uvm_sequence_item;
`uvm_object_utils (my_data)
rand bit [7:0] data;
rand bit [7:0] addr;
constraint c_addr { addr > 0; addr < 8;}
virtual function void display ();
`uvm_info (get_type_name (), $sformatf ("addr = 0x%0h, data = 0x%0h", addr, data), UVM_MEDIUM);
endfunction
endclass
Driver
This is the component responsible for driving data values to the DUT using the interface. Data is usually generated by another component called generator, but for our purposes in this session, we have data being generated inside the driver. We have already seen the following code in the previous session.
class my_driver extends uvm_driver;
`uvm_component_utils (my_driver)
int unsigned n_times;
my_data data_obj;
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
Next, we'll write the reset_phase
, so that reset can be applied to the DUT in this phase.
task reset_phase (uvm_phase phase);
super.reset_phase (phase);
`uvm_info (get_type_name (), $sformatf ("Applying initial reset"), UVM_MEDIUM)
this.vif.rstn = 0;
repeat (20) @ (posedge vif.clk);
this.vif.rstn = 1;
`uvm_info (get_type_name (), $sformatf ("DUT is now out of reset"), UVM_MEDIUM)
endtask
Now, we'll focus on how data should be generated and how it can be driven to the DUT. Note, that we already have a handle to the DUT interface that was obtained from top-level module during the build_phase
. So, all we have to do now is generate and drive data.
task main_phase (uvm_phase phase);
super.main_phase (phase);
phase.raise_objection (phase);
`uvm_info (get_type_name (), $sformatf ("Inside Main phase"), UVM_MEDIUM)
// Let's create a data object, randomize it and send it to the DUT
n_times = 5;
repeat (n_times) begin
`uvm_info (get_type_name (), $sformatf ("Generate and randomize data packet"), UVM_DEBUG)
data_obj = my_data::type_id::create ("data_obj", this);
assert(data_obj.randomize ());
@(posedge vif.clk);
`uvm_info (get_type_name (), $sformatf ("Drive data packet to DUT"), UVM_DEBUG)
this.vif.en = 1;
this.vif.wr = 1;
this.vif.addr = data_obj.addr;
this.vif.wdata = data_obj.data;
data_obj.display ();
end
phase.drop_objection (phase);
endtask
raise_objection
and drop_objection
are methods of the phase object that allows the testbench to know about the current status of each component. So, if a component is actively working during the run_phase, it has to raise an objection. Only when all the components have dropped their objection will the simulation end. If you have forgetten to drop objection on a component, there are chances that your simulation will keep running.
Simulation Output
---------------------------------------------------------------- CDNS-UVM-1.1d (14.10-s004) (C) 2007-2013 Mentor Graphics Corporation (C) 2007-2013 Cadence Design Systems, Inc. (C) 2006-2013 Synopsys, Inc. (C) 2011-2013 Cypress Semiconductor Corp. ---------------------------------------------------------------- UVM_INFO @ 0: reporter [RNTST] Running test base_test... UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology: -------------------------------------------------------- Name Type Size Value -------------------------------------------------------- uvm_test_top base_test - @2615 m_top_env my_env - @204 m_drv0 my_driver - @198 rsp_port uvm_analysis_port - @2814 seq_item_port uvm_seq_item_pull_port - @2763 -------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(74) @ 0: uvm_test_top.m_top_env.m_drv0 [my_driver] Applying initial reset UVM_INFO ./tb/my_pkg.sv(84) @ 0: uvm_test_top.m_top_env.m_drv0 [my_driver] Inside Main phase UVM_INFO ./tb/my_pkg.sv(46) @ 10000: reporter@@data_obj [my_data] addr = 0x6, data = 0x15 UVM_INFO ./tb/my_pkg.sv(46) @ 30000: reporter@@data_obj [my_data] addr = 0x5, data = 0xa8 UVM_INFO ./tb/my_pkg.sv(46) @ 50000: reporter@@data_obj [my_data] addr = 0x3, data = 0xcf UVM_INFO ./tb/my_pkg.sv(46) @ 70000: reporter@@data_obj [my_data] addr = 0x2, data = 0xaa UVM_INFO ./tb/my_pkg.sv(46) @ 90000: reporter@@data_obj [my_data] addr = 0x5, data = 0x4c UVM_INFO ./tb/my_pkg.sv(105) @ 90000: uvm_test_top.m_top_env.m_drv0 [my_driver] Finished DUT simulation --- UVM Report catcher Summary --- Number of demoted UVM_FATAL reports : 0 Number of demoted UVM_ERROR reports : 0 Number of demoted UVM_WARNING reports: 0 Number of caught UVM_FATAL reports : 0 Number of caught UVM_ERROR reports : 0 Number of caught UVM_WARNING reports : 0 --- UVM Report Summary --- ** Report counts by severity UVM_INFO : 10 UVM_WARNING : 0 UVM_ERROR : 0 UVM_FATAL : 0 ** Report counts by id [RNTST] 1 [UVMTOP] 1 [my_data] 5 [my_driver] 3 Simulation complete via $finish(1) at time 90 NS + 83
Go to the next step Sequencer and Monitor