test位于启动环境组件构建的层次顶部(top of the hierarchical)。它还负责测试平台配置和激励生成过程。根据验证计划中提到的设计特征和功能,编写测试。用户定义的测试类源自uvm_test。
9.1 uvm_test class hierarchy
类声明:
virtual class uvm_test extends uvm_component
测试包括env类,配置,sequencer启动sequence。建议用一个包含所有测试台设置(包括环境类实例、创建配置等)的基础测试,并且可以从基础测试中扩展根据验证测试计划进行的各种测试,以避免在每个测试中重复相同的代码。派生测试还可以根据测试需求设置配置。
9.2 Steps to write a test case
- 创建一个从 uvm_test 扩展的用户定义测试类,并将其注册到工厂中。
- 根据需求声明环境、sequence句柄和配置对象。
- 编写标准 new() 函数。由于test是一个 uvm_component,new() 函数有两个参数:字符串名称和 uvm_component 父类/parent。
- 实现 build_phase 以创建env实例、sequence类并在可配置数据库中设置可配置对象。
- 实现 run_phase在特定的sequencer上启动sequence,伴随着raise/drop提起/撤销objection。
9.2.1 UVM Test example
class my_test extends uvm_test;
env env_o;
base_seq bseq;
`uvm_component_utils(my_test)
// constructor
function new(string name = "my_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env_o = env::type_id::create("env_o", this);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
bseq = base_seq::type_id::create("bseq");
repeat(10) begin
#5; bseq.start(env_o.agt.seqr);
end
phase.drop_objection(this);
`uvm_info(get_type_name, "End of testcase", UVM_LOW);
endtask
endclass
9.3 Execution of the test
test执行是一项耗时的活动,需要运行 代表DUT 功能的一个或多个序列。在执行测试时,它会在 build_phase 中构建完整的 UVM 测试平台结构,并在 run_phase 中借助sequence执行耗时的活动。必须在 UVM 工厂中注册tests,否则仿真将以 UVM_FATAL 终止(未找到测试)。
9.3.1 run_test() task
run_test 是在 uvm_root 类中声明的全局任务,负责运行测试用例。
声明:
virtual task run_test (string test_name = "")
1. run_test 任务启动按预定义顺序执行phases的phasing 机制。
2. 它在测试平台顶部的初始块中调用,并接受 test_name 作为字符串。
例子:
// initial block of tb_top
initial begin
run_test("my_test");
end
3. 将参数传递给 run_test 任务会导致在执行不同测试时重新编译。为了避免这种情况,UVM 提供了一种使用 +UVM_TESTNAME 命令行参数的替代方法。在这种情况下,run_test 任务不需要在测试平台top的初始块中传递任何参数。
// initial block of tb_top
initial begin
run_test();
end
// Passing command line argument to the simulator
<other options> +UVM_TESTNAME = my_test
4. 所有phase执行完毕后,run_test 最后调用 $finish 任务退出仿真器。