文章目录
- 前言
- 一、什么是UVM中的测试用例(Test)?
- 二、如何理解UVM中的测试用例?
- 三、如何使用UVM中的测试用例?
- 四、实操代码示例
- 4.1代码结构
- 4.2 代码实现
- 4.2.1 a. 测试用例类的定义和实现
- 4.2.2 b. 测试环境的构建和配置
- 4.2.3 c. 测试序列的创建和启动
- 4.2.4 d. 仿真执行的顶层调用
- 4.3 代码的语法和功能分析
- 4.3.1 a. 测试用例类
- 4.3.2 b. 测试环境类
- 4.3.3 c. 测试序列类
- 4.3.4 d. 顶层Testbench
前言
之前在学习UVM时,测试用例是整个验证流程的起点,它负责控制整个测试的执行过程。
比如把测试用例比作一个导演,它负责指挥整个测试的演员(各个验证组件)按照剧本(测试流程)来表演。
接下来,使用测试用例需要按照一定的步骤来进行,比如创建测试类、实例化环境、启动测试序列等。
比如为什么要用uvm_component_utils宏,为什么要用build_phase和main_phase这些phase。
一、什么是UVM中的测试用例(Test)?
在UVM(Universal Verification Methodology)中,测试用例(Test)是用于验证设计单元(DUT)功能的顶层类。它继承自uvm_test,定义了测试的执行流程,包括初始化环境、启动测试序列、监视测试进度以及清理工作。
二、如何理解UVM中的测试用例?
- 组织测试流程:测试用例提供了一个框架,用于组织测试的执行流程,包括初始化、测试执行和结果分析等步骤。
- 管理测试组件:测试用例可以实例化和配置UVM环境中的各个组件,如agent、driver、monitor、scoreboard等。
- 启动测试序列:测试用例可以启动测试序列,生成激励信号,驱动DUT进行测试。
- 结果分析与报告:测试用例可以收集和报告测试结果,包括测试通过与否、覆盖率信息等。
三、如何使用UVM中的测试用例?
使用UVM中的测试用例需要以下几步:
- 创建测试用例类:创建一个继承自uvm_test的类,并在其中定义所需的组件和方法。
- 实例化环境:在build_phase中实例化UVM环境。
- 启动测试序列:在main_phase中启动测试序列。
- 结果分析与报告:在report_phase中分析测试结果并报告。
具体操作步骤:
以下是使用UVM测试用例的详细步骤:
- 步骤1:创建测试用例类
- 继承自uvm_test基类。
- 使用uvm_component_utils宏注册到UVM工厂。
- 步骤2:构建测试环境
- 在build_phase中创建并配置测试环境(Environment)。
- 通过uvm_config_db设置环境参数(如接口、配置对象等)。
- 步骤3:创建测试序列
- 定义测试序列类,继承自uvm_sequence。
- 在序列的body任务中实现具体的测试场景。
- 步骤4:启动测试序列
- 在测试用例的run_phase中创建并启动测试序列。
- 使用raise_objection和drop_objection控制仿真结束。
- 步骤5:顶层调用
- 在顶层Testbench中通过run_test启动测试用例。
- 使用uvm_config_db指定默认测试用例。
四、实操代码示例
以下是一个完整的UVM测试用例示例,验证一个简单的加法器(Adder)功能。
4.1代码结构
- 测试用例类:adder_test
- 测试环境类:adder_env
- 测试序列类:adder_sequence
- 顶层Testbench:启动测试用例
4.2 代码实现
4.2.1 a. 测试用例类的定义和实现
class adder_test extends uvm_test;
`uvm_component_utils(adder_test) // 注册到UVM工厂
adder_env env; // 测试环境实例
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = adder_env::type_id::create("env", this); // 创建测试环境
endfunction
virtual task run_phase(uvm_phase phase);
adder_sequence seq = adder_sequence::type_id::create("seq"); // 创建测试序列
phase.raise_objection(this); // 阻止仿真结束
seq.start(env.agent.sequencer); // 启动序列
phase.drop_objection(this); // 允许仿真结束
endtask
endclass
4.2.2 b. 测试环境的构建和配置
class adder_env extends uvm_env;
`uvm_component_utils(adder_env) // 注册到UVM工厂
adder_agent agent; // Agent实例
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
agent = adder_agent::type_id::create("agent", this); // 创建Agent
endfunction
endclass
4.2.3 c. 测试序列的创建和启动
class adder_sequence extends uvm_sequence#(adder_transaction);
`uvm_object_utils(adder_sequence) // 注册到UVM工厂
rand int num_transactions = 10; // 随机生成10笔交易
task body();
repeat (num_transactions) begin
`uvm_do(req) // 自动创建并发送transaction
end
endtask
endclass
4.2.4 d. 仿真执行的顶层调用
module top_tb;
initial begin
// 指定默认测试用例
uvm_config_db#(uvm_object_wrapper)::set(null, "uvm_test_top", "default_sequence", adder_test::get_type());
run_test("adder_test"); // 启动测试用例
end
endmodule
4.3 代码的语法和功能分析
4.3.1 a. 测试用例类
- uvm_component_utils:注册测试用例到UVM工厂,支持动态创建。
- build_phase:创建测试环境实例。
- run_phase:启动测试序列,并通过objection机制控制仿真结束。
4.3.2 b. 测试环境类
- adder_agent:Agent是UVM中的核心组件,负责驱动和监控DUT。
- build_phase:在构建阶段创建Agent实例。
4.3.3 c. 测试序列类
- uvm_sequence:用于生成测试激励。
- uvm_do宏:自动创建并发送transaction到Driver。
4.3.4 d. 顶层Testbench
- uvm_config_db:配置默认测试用例。
- run_test:启动UVM测试。