UVM user defined phases - vineethkumarv/uvm-repos GitHub Wiki

UVM supports user defined phases that are customizable by the user.These can be inserted anywhere.
Steps to create a custom phase :

1. Define phase.
We create a phase by extending it from appropriate base class uvm_task_phase,uvm_topdown_phase, uvm_bottomup_phase. If your phase consumes time extend it from uvm_task_phase else go with the requirement.Implement exec_task or exec_func.

class u_phase extends uvm_topdown_phase;                                                            
 static local u_phase up;                                                                          
 function new(string n="u_phase");                                                                 
   super.new(n);                                                                                   
 endfunction                                                                                       
                                                                                                  
 virtual function string get_type_name();                                                          
 return "user_defined_phase";                                                                      
 endfunction                                                                                       
                                                                                                   
 static function u_phase get();                                                                    
 if (up==null) begin                                                                               
  up=new();                                                                                        
 end                                                                                               
 return up;                                                                                        
 endfunction                                                                                       
                                                                                                   
 virtual function void exec_func(uvm_component comp,uvm_phase phase);                              
 comp.parent=null;                                                                                 
 //display("in the function");                                                                     
 `uvm_info(get_full_name(),$sformatf("in %s phase",phase.get_name()),UVM_MEDIUM);                  
 endfunction                                                                                       
endclass     

Here we extended a user defined phase from uvm_topdown_phase base class. And in the exec_func which is the predefined function that is to be overridden so that the defined function is done as per requirement,we are just printing an info regarding phase.

2. Insert into a schedule.
Inorder to execute a phase it must be added into a domain and that domain is inserted into a schedule.A domain is a phasing schedule node representing an independent branch of schedule.We can insert the new user defined phase in between any of the existing phases. And to do so we need to create a handle for the uvm phase scheduler or domain.
We can do that in the following ways:
By using the handles of domain and phase.

uvm_domain d=uvm_domain::get_common_domain();                                                     
uvm_phase up=d.find(uvm_build_phase::get());  
d.add(user_phase::get(),null,up,null);   

In this we use handles for uvm_domain and uvm_phase for adding the user defined phase u_phase into the domain.In add, The first field is 'instance_field',that should return an instance of a phase,second field is 'with_field',that should represent a phase along with which the user phase should be run,third and fourth fields are 'after and before_fields', to specify the phase after and before which the user phase should be run/inserted respectively. Here the user phase is inserted after build_phase as specified.

  • Both 'with_field' and 'after and before_fields' cannot be given at the same time as they lead to contradiction. So one should be null for other to happen.

Without any handles

uvm_domain::get_common_domain().add(u_phase::get(),null,uvm_build_phase::get(),null);  

Here without any handles we are adding the user defined phase into the domain.

3. Use the defined phase.

 class test extends uvm_test;                                                                        
 `uvm_component_utils(test)                                                                        
 function new(string n="test",uvm_component p=null);                                               
 super.new(n,p);                                                                                                                                                                  
 endfunction                                                                                       
                                                                          
 virtual task run_phase(uvm_phase phase);                                                          
 `uvm_info(get_type_name(),$sformatf("in %s phase",phase.get_name()),UVM_MEDIUM);                  
 endtask                                                                                           
                                                                                                
 virtual function void build_phase(uvm_phase phase);    
 //uvm_domain u=uvm_domain::get_common_domain();                                                   
 //uvm_phase up=u.find(uvm_build_phase::get());                                                    
 uvm_domain::get_common_domain().add(u_phase::get(),null,uvm_build_phase::get(),null);                                                                                                                                                            
 `uvm_info(get_type_name(),$sformatf("in %s phase",phase.get_name()),UVM_LOW);                     
 endfunction                                                                                       
                                                                                                
 virtual function void connect_phase(uvm_phase phase);                                              
 `uvm_info(get_type_name(),$sformatf("in %s phase",phase.get_name()),UVM_LOW);                     
 endfunction                                                                                                 
endclass    

Output:

image

Here we created a user defined phase u_phase and inserted it after build_phase, as we did mention before_field to null,the u_phase will be executed just after build_phase.