UVM Test

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