uvm有自己的顶层uvm_root,是一个componet,提供了一些像run_test()这样的方法,它在uvm_pkg中例化,uvm_root例化的uvm_top,是唯一一个顶层类
验证平台的top层只是充当了一个容纳所有组件的容器,通过调用uvm库中的run_test函数启动环境,run_test函数内部会索引到顶层uvm_root,调用真正的run_test函数,所以在top层进行vif set的时候,用的路径是null,uvm_test_top.env,用的都是uvm自身的树形结构
task run_test (string test_name="");
uvm_root top;
uvm_coreservice_t cs;
cs = uvm_coreservice_t::get();
top = cs.get_root();
top.run_test(test_name);
endtask
uvm-1.2/base/uvm_globals.svh
通过uvm_top调用run_test(test_name),uvm_top做了如下初始化:
1.得到正确的test_name
2.初始化objection机制
3.创建uvm_test_top实例
4.调用phase控制方法,安排所有phase执行顺序
5.等待所有phase执行结束,关闭phase控制进程
6.报告总结和结束仿真
task uvm_root::run_test(string test_name="");
uvm_report_server l_rs;
uvm_coreservice_t cs = uvm_coreservice_t::get();
uvm_factory factory=cs.get_factory();
bit testname_plusarg;
int test_name_count;
string test_names[$];
string msg;
uvm_component uvm_test_top;
process phase_runner_proc; // store thread forked below for final cleanup
testname_plusarg = 0;
// Set up the process that decouples the thread that drops objections from
// the process that processes drop/all_dropped objections. Thus, if the
// original calling thread (the "dropper") gets killed, it does not affect
// drain-time and propagation of the drop up the hierarchy.
// Needs to be done in run_test since it needs to be in an
// initial block to fork a process.
uvm_objection::m_init_objections();
`ifndef UVM_NO_DPI
// Retrieve the test names provided on the command line. Command line
// overrides the argument.
test_name_count = clp.get_arg_values("+UVM_TESTNAME=", test_names);
// If at least one, use first in queue.
if (test_name_count > 0) begin
test_name = test_names[0];
testname_plusarg = 1;
end
// If multiple, provided the warning giving the number, which one will be
// used and the complete list.
if (test_name_count > 1) begin
string test_list;
string sep;
for (int i = 0; i < test_names.size(); i++) begin
if (i != 0)
sep = ", ";
test_list = {test_list, sep, test_names[i]};
end
uvm_report_warning("MULTTST",
$sformatf("Multiple (%0d) +UVM_TESTNAME arguments provided on the command line. '%s' will be used. Provided list: %s.", test_name_count, test_name, test_list), UVM_NONE);
end
`else
// plusarg overrides argument
if ($value$plusargs("UVM_TESTNAME=%s", test_name)) begin
`uvm_info("NO_DPI_TSTNAME", "UVM_NO_DPI defined--getting UVM_TESTNAME directly, without DPI", UVM_NONE)
testname_plusarg = 1;
end
`endif
// if test now defined, create it using common factory
if (test_name != "") begin
uvm_coreservice_t cs = uvm_coreservice_t::get();
uvm_factory factory=cs.get_factory();
if(m_children.exists("uvm_test_top")) begin
uvm_report_fatal("TTINST",
"An uvm_test_top already exists via a previous call to run_test", UVM_NONE);
#0; // forces shutdown because $finish is forked
end
$cast(uvm_test_top, factory.create_component_by_name(test_name,
"", "uvm_test_top", null));
if (uvm_test_top == null) begin
msg = testname_plusarg ? {"command line +UVM_TESTNAME=",test_name} :
{"call to run_test(",test_name,")"};
uvm_report_fatal("INVTST",
{"Requested test from ",msg, " not found." }, UVM_NONE);
end
end
if (m_children.num() == 0) begin
uvm_report_fatal("NOCOMP",
{"No components instantiated. You must either instantiate",
" at least one component before calling run_test or use",
" run_test to do so. To run a test using run_test,",
" use +UVM_TESTNAME or supply the test name in",
" the argument to run_test(). Exiting simulation."}, UVM_NONE);
return;
end
begin
if(test_name=="")
uvm_report_info("RNTST", "Running test ...", UVM_LOW);
else if (test_name == uvm_test_top.get_type_name())
uvm_report_info("RNTST", {"Running test ",test_name,"..."}, UVM_LOW);
else
uvm_report_info("RNTST", {"Running test ",uvm_test_top.get_type_name()," (via factory override for test \"",test_name,"\")..."}, UVM_LOW);
end
// phase runner, isolated from calling process
fork begin
// spawn the phase runner task
phase_runner_proc = process::self();
uvm_phase::m_run_phases();
end
join_none
#0; // let the phase runner start
wait (m_phase_all_done == 1);
// clean up after ourselves
phase_runner_proc.kill();
l_rs = uvm_report_server::get_server();
l_rs.report_summarize();
if (finish_on_completion)
$finish;
endtask
其他
- 关于本文,您有什么想法均可在评论区留言交流。
- 自身能力不足,如有错误还请多多指出!