In UVM, UVM test component is a specialized object that sets up the verification environment and controls the execution of tests. It coordinates stimulus generation, DUT interactions, and result checking, ensuring that the design behaves as expected.
Test components are typically derived from the uvm_test base class, providing a customizable way to implement test cases for different scenarios.
Steps to Write a UVM Test Component
To create an effective UVM test component, we should follow these steps:
1. Define the Test Component Class
Start by creating a new class for your test. This class should extend the uvm_test base class. The uvm_test base class provides a starting point for building tests and includes essential features like phasing and reporting.
class my_test extends uvm_test;
`uvm_component_utils(my_test) // Register the component with the factory
my_sequence seq;
my_env env;
// Constructor
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
2. Implement the Build Phase
Within the test component, this phase is typically used to configure and instantiate the environment, sequence or any additional components needed for the test.
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// Example: Create and configure the environment
env = my_env::type_id::create("env", this);
seq = my_sequence::type_id::create("seq",this);
endfunction
3. Implement the Run Phase
The run_phase is the main simulation loop where the test logic is executed. This phase involves applying stimulus, monitoring responses, and verifying results. The sequence starting will happen here.
task run_phase(uvm_phase phase);
phase.raise_objection(this);
// Start sequence
seq.start(env.sequencer);
phase.drop_objection(this);
endtask
Example:
Let’s see a simple uvm_test component code example.
class mem_test extends uvm_test;
`uvm_component_utils(mem_test)
mem_env env;
mem_sequence seq;
virtual mem_interface vif;
function new(string name="mem_test", uvm_component parent=null);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = mem_env::type_id::create("env",this);
endfunction
task run_phase(uvm_phase phase);
seq = mem_sequence::type_id::create("seq",this);
phase.raise_objection(this,"starting sequence in main phase");
$display ("%t starting sequence mem_sequence run_phase",$time);
seq.start(env.mem_agnt.sequencer);
#50ns;
phase.drop_objection(this,"finish sequence in main phase");
endtask
endclass