In UVM we directly use phases to do different things. But how simulator understands from uvm base library that it need to start with build_phase and after that need to execute connect_phase and so on …
Till now I just got this info but don’t understand how it actually works. Could anyone help me understand summarizing underlying mechanism ?
The simulator understands UVM because ir is written in SystemVerilog. The phasing is taking advantage of virtual methods and building lists of “Component” classes and simply iterating over that list for each phase. Below is a very simplified example showing the structures the UVM creates and how it executes them:
class Component;
string m_name;
Component m_parent;
static Component list[$];
function new(string name, Component parent);
m_name = name;
m_parent = parent;
list.push_back(this);
endfunction
function string get_fullname;
if (m_parent == null)
return m_name;
else
return {m_parent.get_fullname(), "." , m_name};
endfunction
virtual function void build_phase;
endfunction
virtual task run_phase;
endtask
virtual function void report_phase();
endfunction
endclass
class A extends Component;
function new(string name, Component parent);
super.new(name,parent);
$display("A Constructing: ", get_fullname);
endfunction
task run_phase;
#10 $display("Running from ",get_fullname(),,$time);
endtask
function void report_phase;
$display("Reporting from ",get_fullname(),,$time);
endfunction
endclass
class B extends Component;
function new(string name, Component parent);
super.new(name,parent);
$display("B Constructing: ", get_fullname);
endfunction
A a;
function void build_phase;
a = new("a",this);
endfunction
task run_phase;
#20 $display("Running from ",get_fullname(),,$time);
endtask
endclass
class Root extends Component;
function new(string name, Component parent);
super.new(name,parent);
$display("env Constructing: ", get_fullname);
endfunction
A a;
B b;
function void build_phase;
a = new("a",this);
b = new("b",this);
endfunction
task run_test;
// build_phase
for(int item=0;item<list.size();item++)
list[item].build_phase();
// run_phase
foreach(list[item])
fork
int k = item;
list[k].run_phase();
join_none
wait fork;
// report phase
foreach(list[item])
list[item].report_phase();
endtask
endclass
module top;
Root root;
initial begin
root =new("root",null);
root.run_test();
end
endmodule