| |
不同于verilog的module,OVM中所有object的产生和运行都被OVM phase controller控制,每个object都包含以下过程:
new is not technically a phase, in that it’s not managed by the
phase controller. However, for each component, the constructor
must execute and complete in order to bring the component into
existence. Therefore, new() must run before build() or any
other subsequent phases can execute.
build is the place where new components, ports, and exports are
instantiated and configured. This is also the recommended place
for calling set_config_* and get_config_* (see Section4.4).
connect is where components, ports, and exports created in
build() are connected.
end_of_elaboration is where you can make configuration
changes, knowing that elaboration is complete. That is, you can
assume that all components are built and connected.
start_of_simulation executes just before time 0.
run is the only pre-defined task phase. All of the run tasks are
forked to run in parallel. Each run task continues until its locus of
control passes the endtask statement or it is explicitly shut down.
Later in this chapter, we will discuss how to shut down testbenches.
extract is intended for collecting information relating to coverage
or other information about how to answer the testbench questions.
check is where any correctness checking or validation of
extracted data is done.
report is where final reports are produced.
下面这个例子展示OVM component的各个phase执行次序:
class sub_component extends ovm_component;
function new(string name, ovm_component parent);
super.new(name, parent);
endfunction
function void build();
ovm_report_info("build", "");
endfunction
function void connect();
ovm_report_info("connect", "");
endfunction
function void end_of_elaboration();
ovm_report_info("end_of_elaboration", "");
endfunction
function void start_of_simulation();
ovm_report_info("start_of_simulation", "");
endfunction
task run();
ovm_report_info("run", "");
endtask
function void extract();
ovm_report_info("extract", "");
endfunction
function void check();
ovm_report_info("check", "");
endfunction
function void report();
ovm_report_info("report", "");
endfunction
endclass
class component extends sub_component;
sub_component s1, s2;
function new(string name, ovm_component parent);
super.new(name, parent);
endfunction
function void build();
super.build();
s1 = new("s1", this);
s2 = new("s2", this);
endfunction
endclass
class env extends sub_component;
component c1, c2;
function new(string name, ovm_component parent = null);
super.new(name, parent);
endfunction
function void build();
ovm_report_info("build", "");
c1 = new("c1", this);
c2 = new("c2", this);
endfunction
task run();
ovm_report_info("run", "");
#1;
ovm_top.stop_request();
endtask
endclass
module top;
env e;
initial begin
e = new("env");
run_test();
end
endmodule
输出:
# OVM_INFO @ 0: reporter [RNTST] Running test ...
# OVM_INFO @ 0: env [build]
# OVM_INFO @ 0: env.c1 [build]
# OVM_INFO @ 0: env.c1.s1 [build]
# OVM_INFO @ 0: env.c1.s2 [build]
# OVM_INFO @ 0: env.c2 [build]
# OVM_INFO @ 0: env.c2.s1 [build]
# OVM_INFO @ 0: env.c2.s2 [build]
# OVM_INFO @ 0: env.c1.s1 [connect]
# OVM_INFO @ 0: env.c1.s2 [connect]
# OVM_INFO @ 0: env.c1 [connect]
# OVM_INFO @ 0: env.c2.s1 [connect]
# OVM_INFO @ 0: env.c2.s2 [connect]
# OVM_INFO @ 0: env.c2 [connect]
# OVM_INFO @ 0: env [connect]
# OVM_INFO @ 0: env.c1.s1 [end_of_elaboration]
# OVM_INFO @ 0: env.c1.s2 [end_of_elaboration]
# OVM_INFO @ 0: env.c1 [end_of_elaboration]
# OVM_INFO @ 0: env.c2.s1 [end_of_elaboration]
# OVM_INFO @ 0: env.c2.s2 [end_of_elaboration]
# OVM_INFO @ 0: env.c2 [end_of_elaboration]
# OVM_INFO @ 0: env [end_of_elaboration]
# OVM_INFO @ 0: env.c1.s1 [start_of_simulation]
# OVM_INFO @ 0: env.c1.s2 [start_of_simulation]
# OVM_INFO @ 0: env.c1 [start_of_simulation]
# OVM_INFO @ 0: env.c2.s1 [start_of_simulation]
# OVM_INFO @ 0: env.c2.s2 [start_of_simulation]
# OVM_INFO @ 0: env.c2 [start_of_simulation]
# OVM_INFO @ 0: env [start_of_simulation]
# OVM_INFO @ 0: env [run]
# OVM_INFO @ 0: env.c2 [run]
# OVM_INFO @ 0: env.c2.s2 [run]
# OVM_INFO @ 0: env.c2.s1 [run]
# OVM_INFO @ 0: env.c1 [run]
# OVM_INFO @ 0: env.c1.s2 [run]
# OVM_INFO @ 0: env.c1.s1 [run]
结论:
各个phase按照次序执行
build按照top-down的次序执行,其余是按照bottom-up
疑问:top中 run_test();调用的是谁的方法?