前言:
理论学习总感觉差不多了,但是实际运行后才能更深刻的理解,今天运行了路科uvm0的实验lab1中的phase_order_test,算是具体了解phase机制各个组件和对象build_phase、connect_phase、run_phase、与report_phase运行的规律了。下有一目了然结构图,一秒就看懂。
1、运行代码
package phase_order_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
class comp2 extends uvm_component;
`uvm_component_utils(comp2)
function new(string name = "comp2", uvm_component parent = null);
super.new(name, parent);
`uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
endfunction
//TODO-3.1
//Refer comp1 and define methods:
// - build_phase()
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("BUILD","comp2 bulid phase entered", UVM_LOW)
`uvm_info("BUILD","comp2 bulid phase exited", UVM_LOW)
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("CONNECT","comp2 connect phase entered",UVM_LOW)
`uvm_info("CONNECT","comp2 connect phase exited",UVM_LOW)
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
`uvm_info("RUN","comp2 run_phase entered",UVM_LOW)
`uvm_info("RUN","comp2 run_phase exited",UVM_LOW)
endtask
function void report_phase(uvm_phase phase);
super.report_phase(phase);
`uvm_info("REPORT","comp2 report_phase entered",UVM_LOW)
`uvm_info("REPORT","comp2 report_phase exited",UVM_LOW)
endfunction
// - connect_phase()
// - run_phase()
// - report_phase()
endclass
class comp3 extends uvm_component;
`uvm_component_utils(comp3)
function new(string name = "comp3", uvm_component parent = null);
super.new(name, parent);
`uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("BUILD","comp3 bulid phase entered", UVM_LOW)
`uvm_info("BUILD","comp3 bulid phase exited", UVM_LOW)
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("CONNECT","comp3 connect phase entered",UVM_LOW)
`uvm_info("CONNECT","comp3 connect phase exited",UVM_LOW)
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
`uvm_info("RUN","comp3 run_phase entered",UVM_LOW)
`uvm_info("RUN","comp3 run_phase exited",UVM_LOW)
endtask
function void report_phase(uvm_phase phase);
super.report_phase(phase);
`uvm_info("REPORT","comp3 report_phase entered",UVM_LOW)
`uvm_info("REPORT","comp3 report_phase exited",UVM_LOW)
endfunction
//TODO-3.1
//Refer comp1 and define methods:
// - build_phase()
// - connect_phase()
// - run_phase()
// - report_phase()
endclass
class comp1 extends uvm_component;
comp2 c2;
comp3 c3;
`uvm_component_utils(comp1)
function new(string name = "comp1", uvm_component parent = null);
super.new(name, parent);
`uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("BUILD", "comp1 build phase entered", UVM_LOW)
c2 = comp2::type_id::create("c2", this);
c3 = comp3::type_id::create("c3", this);
`uvm_info("BUILD", "comp1 build phase exited", UVM_LOW)
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("CONNECT", "comp1 connect phase entered", UVM_LOW)
`uvm_info("CONNECT", "comp1 connect phase exited", UVM_LOW)
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
`uvm_info("RUN", "comp1 run phase entered", UVM_LOW)
`uvm_info("RUN", "comp1 run phase exited", UVM_LOW)
endtask
function void report_phase(uvm_phase phase);
super.report_phase(phase);
`uvm_info("REPORT", "comp1 report phase entered", UVM_LOW)
`uvm_info("REPORT", "comp1 report phase exited", UVM_LOW)
endfunction
endclass
class phase_order_test extends uvm_test;
comp1 c1;
`uvm_component_utils(phase_order_test)
function new(string name = "phase_order_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("BUILD", "phase_order_test build phase entered", UVM_LOW)
c1 = comp1::type_id::create("c1", this);
`uvm_info("BUILD", "phase_order_test build phase exited", UVM_LOW)
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("CONNECT", "phase_order_test connect phase entered", UVM_LOW)
`uvm_info("CONNECT", "phase_order_test connect phase exited", UVM_LOW)
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
`uvm_info("RUN", "phase_order_test run phase entered", UVM_LOW)
phase.raise_objection(this);
#1us;
phase.drop_objection(this);
`uvm_info("RUN", "phase_order_test run phase exited", UVM_LOW)
endtask
function void report_phase(uvm_phase phase);
super.report_phase(phase);
`uvm_info("REPORT", "phase_order_test report phase entered", UVM_LOW)
`uvm_info("REPORT", "phase_order_test report phase exited", UVM_LOW)
endfunction
//TODO-3.2
//Refer to phase_order_test::run_phase and define phase tasks:
// - reset_phase()
// - main_phase()
//Ask each task to be finished within 1us
task reset_phase(uvm_phase phase);
`uvm_info("RESET","phase_order_test reset_phase entered",UVM_LOW)
phase.raise_objection(this);
#1us;
phase.drop_objection(this);
`uvm_info("RESET","phase_order_test reset_phase exited",UVM_LOW)
endtask
task main_phase(uvm_phase phase);
`uvm_info("MAIN","phase_order_test main_phase entered",UVM_LOW)
phase.raise_objection(this);
#1us;
phase.drop_objection(this);
`uvm_info("MAIN","phase_order_test main_phase exited",UVM_LOW)
endtask
endclass
endpackage
module phase_order;
import uvm_pkg::*;
`include "uvm_macros.svh"
import phase_order_pkg::*;
initial begin
run_test(""); // empty test name
end
endmodule
总结来说代码的结构为:
2、运行结果
相同phase的运行结果我都用同一种颜色表示出来了,在结构图中表示呢如下:
3、总结
1)自顶向下:bulid_phase与run_phase是从顶层开始运行。其中run_phase与其他12个小phase是并行开始的,12个小phase按照既定的顺序运行。run_phase的结束不用等待其他12个小phase,但只有等其他12个小phase全部运行结束,才能进入report_phase阶段。
2)自底向上:connect_phase与report_phase是从层次底部开始运行。
3)各层次相同phase执行完后,才会进入下一个phase。
4)上述代码总共运行了2us,因为run_phase(1us)与reset_phase(1us)、main_phase(1us)并行执行,总共运行2us。