以下是关于 UVM 中 uvm_test
的详细解释、核心功能、适用场景、使用方法以及一个完整的代码示例:
uvm_test
是 UVM(Universal Verification Methodology)中的一个基类,继承自 uvm_component
,用于表示验证环境中的测试用例。它是 UVM 测试平台的顶层组件,负责以下任务:
uvm_env
)。每个具体的测试用例都通过派生 uvm_test
的子类来实现,使得不同的测试可以复用相同的验证环境结构。
功能 | 说明 |
---|---|
环境构建 | 在 build_phase 中实例化 uvm_env 和其他组件。 |
配置管理 | 通过 uvm_config_db 设置全局配置(如虚拟接口、参数)。 |
测试序列控制 | 在 run_phase 中启动具体的测试序列(uvm_sequence )。 |
仿真时间控制 | 使用 raise_objection 和 drop_objection 控制仿真开始和结束。 |
uvm_test
子类实现自动化回归测试。从 uvm_test
派生一个子类,并注册到 UVM 工厂。
class my_test extends uvm_test;
`uvm_component_utils(my_test) // 注册到工厂
my_env env; // 验证环境实例
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
在 build_phase
中实例化 uvm_env
并配置全局参数。
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = my_env::type_id::create("env", this); // 创建环境实例
// 通过配置数据库传递虚拟接口
uvm_config_db#(virtual dut_interface)::set(this, "env.agent*", "vif", dut_if);
endfunction
在 run_phase
中启动具体的测试序列。
virtual task run_phase(uvm_phase phase);
my_sequence seq;
phase.raise_objection(this); // 开始仿真
seq = my_sequence::type_id::create("seq");
seq.start(env.agent.sequencer); // 启动序列到指定的sequencer
phase.drop_objection(this); // 结束仿真
endtask
class my_transaction extends uvm_sequence_item;
rand bit [31:0] data;
`uvm_object_utils(my_transaction)
function new(string name = "my_transaction");
super.new(name);
endfunction
endclass
class my_sequence extends uvm_sequence#(my_transaction);
`uvm_object_utils(my_sequence)
task body();
my_transaction tx;
repeat(5) begin
tx = my_transaction::type_id::create("tx");
start_item(tx);
assert(tx.randomize());
finish_item(tx);
end
endtask
endclass
class my_driver extends uvm_driver#(my_transaction);
`uvm_component_utils(my_driver)
virtual dut_interface vif;
task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
vif.drive(req.data); // 驱动数据到DUT接口
seq_item_port.item_done();
end
endtask
endclass
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_agent agent;
function void build_phase(uvm_phase phase);
agent = my_agent::type_id::create("agent", this);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env env;
function void build_phase(uvm_phase phase);
env = my_env::type_id::create("env", this);
// 配置虚拟接口
uvm_config_db#(virtual dut_interface)::set(this, "env.agent*", "vif", dut_if);
endfunction
task run_phase(uvm_phase phase);
my_sequence seq;
phase.raise_objection(this);
seq = my_sequence::type_id::create("seq");
seq.start(env.agent.sequencer);
phase.drop_objection(this);
endtask
endclass
module top;
dut_interface dut_if();
dut my_dut(.clk(dut_if.clk), .data(dut_if.data)); // DUT实例化
initial begin
// 将虚拟接口传递给测试类
uvm_config_db#(virtual dut_interface)::set(null, "uvm_test_top.env.agent*", "vif", dut_if);
run_test("my_test"); // 启动测试
end
endmodule
sequencer
。sequencer
获取事务并驱动到 DUT 接口。agent
和其他组件。uvm_test
的作用:作为测试用例的入口,管理验证环境的构建和测试流程。uvm_config_db
动态配置环境,提升代码复用性。通过此示例,可以看出 uvm_test
在 UVM 验证环境中扮演着“总指挥”的角色,协调各个组件完成完整的验证任务。