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:
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.