1. 概述
1.1 定义与目的
UVM Phase是UVM验证方法学的核心调度机制,它将验证平台的构建、运行和清理过程划分为多个有序的阶段。每个phase都有特定的职责和执行顺序,确保验证环境的各个组件能够协调工作。
1.2 主要作用
- 同步机制:保证所有组件在同一阶段完成相应操作
- 自动化流程:自动调用各phase方法,减少手动控制
- 标准化:提供统一的验证环境生命周期管理
2. Phase的分类
2.1 按执行方式分类
- 函数Phase:同步执行,不消耗仿真时间
- 包括:build_phase, connect_phase等
- 特点:快速执行,无时间延迟
- 任务Phase:异步执行,可消耗仿真时间
- 包括:run_phase, reset_phase等
- 特点:可包含延时语句,支持并发执行
2.2 按功能范畴分类
- 构建阶段:环境组建和连接
- 运行阶段:测试用例执行
- 清理阶段:结果收集和报告
3. 所有Phase详解
3.1 构建阶段
build_phase
- 功能:组件实例化和配置
- 执行顺序:自顶向下(父组件→子组件)
- 典型操作:创建子组件、获取配置
build_phase在验证环境为常用的phase,如下为举例:
class my_driver extends uvm_driver;
`uvm_component_utils(my_driver)
virtual interface my_if vif;
int driver_id;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 获取虚拟接口
if (!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
`uvm_error("NOVIF", "Virtual interface not set")
// 获取配置参数
if (!uvm_config_db#(int)::get(this, "", "driver_id", driver_id))
driver_id = 0;
// 创建子组件
seq_item_port = new("seq_item_port", this);
endfunction
endclass
connect_phase
- 功能:组件间端口连接
- 执行顺序:自底向上(子组件→父组件)
- 典型操作:TLM端口连接、analysis port连接
connect_phase在验证环境为常用的phase,如下为举例:
class my_env extends uvm_env;
my_agent agent;
my_scoreboard sb;
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
// 连接 monitor 到 scoreboard
agent.monitor.item_collected_port.connect(sb.item_fifo.analysis_export);
// TLM 连接
agent.driver.seq_item_port.connect(agent.sequencer.seq_item_export);
endfunction
endclass
end_of_elaboration_phase
- 功能:最终环境调整
- 执行顺序:自底向上
- 典型操作:环境完整性检查、最终配置
在验证环境常在此phase打印验证环境的拓扑结构,如下为举例:
function void test_case::end_of_elaboration_phase(uvm_phase phase);
`uvm_info("test_case","test_case end_of_elaboration_phase called!",UVM_LOW)
uvm_root::get().print_topology();
endfunction
3.2 启动阶段
start_of_simulation_phase
- 功能:仿真开始前准备
- 执行顺序:自底向上
- 典型操作:打印初始状态、设置初始值
3.3 运行阶段
核心任务Phase
run_phase:主要的测试逻辑执行- 与12个标准run phase并行执行
- 通常用于实现主要测试场景
run_phase在验证环境为常用的phase,如下为举例:
class my_driver extends uvm_driver;
task run_phase(uvm_phase phase);
phase.raise_objection(this);
`uvm_info("DRIVER", "Driver run_phase started", UVM_MEDIUM)
forever begin
seq_item_port.get_next_item(req);
drive_transaction(req);
seq_item_port.item_done();
end
phase.drop_objection(this);
endtask
task drive_transaction(my_transaction tr);
// 驱动信号到 DUT
vif.valid <= 1'b1;
vif.data <= tr.data;
@(posedge vif.clk);
vif.valid <= 1'b0;
endtask
endclass
12个动态Phase
pre_reset_phase
- 功能:复位开始前的准备工作
- 典型操作:确保时钟稳定、保存复位前状态、初始化复位监控
reset_phase
- 功能:执行复位操作
- 典型操作:断言复位信号、验证复位状态、检查寄存器复位值
post_reset_phase
- 功能:复位结束后的清理工作
- 典型操作:释放复位信号、验证复位释放、准备配置阶段
pre_configure_phase
- 功能:配置开始前的准备工作
- 典型操作:准备配置数据、验证配置环境、初始化配置序列
configure_phase
- 功能:执行系统配置
- 典型操作:配置寄存器、设置工作模式、验证配置结果
post_configure_phase
- 功能:配置结束后的清理工作
- 典型操作:验证配置完整性、检查系统状态、准备主测试阶段
pre_main_phase
- 功能:主测试开始前的准备工作
- 典型操作:初始化测试序列、设置激励参数、启动监控组件
main_phase
- 功能:执行主要测试功能
- 典型操作:运行测试场景、生成业务流量、执行功能验证
post_main_phase
- 功能:主测试结束后的清理工作
- 典型操作:完成未决事务、停止激励生成、收集最终数据
pre_shutdown_phase
- 功能:关闭开始前的准备工作
- 典型操作:初始化关闭流程、保存关键信息、准备资源清理
shutdown_phase
- 功能:执行系统关闭操作
- 典型操作:停止所有进程、执行安全关闭、验证关闭状态
post_shutdown_phase
- 功能:关闭结束后的最终工作
- 典型操作:验证完全关闭、执行最终检查、准备仿真结束
4. Phase的执行机制
4.1 执行顺序规则
- 自顶向下:build_phase(父→子)、final_phase
- 自底向上:除build_phase和final_phase的phase
- 同级组件:无固定顺序,不应依赖执行顺序
通过一个简单的验证环境来说明,验证环境框图如下:
上图红色框内为build_phase的顺序,可以看出顺序为test_case1->my_env->my_agent->my_driver,base_sequencer,从上层到下层;蓝色框内为connect_phase,顺序为:my_driver,base_sequencer->my_agent->my_env->test_case1。
4.2 任务Phase的并行性
- 所有任务phase并行执行
- run_phase与12个标准run phase同时运行
- 需要通过phase_ready_to_end机制协调结束
phase_ready_to_end 是 UVM 中一个高级的 objection 控制机制,用于在 phase 准备结束但尚未结束时进行最后的协调和清理。
4.3 phase跳转
- 使用
jump()方法可在特定条件下跳转phase - 谨慎使用,可能破坏验证环境稳定性
phase.jump(target_phase);
限制条件
- 只能在任务 phase 中调用
- 不能跳转到已经执行过的 phase 组
- 不能跳转到其他 domain 的 phase
- 需要所有相关组件都支持跳转
如下为一个phase跳转举例,在main_phase中判断是否需要再次进行复位,如果需要,跳转到reset_phase再执行一次。
task test_case1::reset_phase(uvm_phase phase);
`uvm_info("test_case1", "test_case1 reset_phase called!",UVM_LOW)
phase.raise_objection(this);
`uvm_info("test_case1", "Applying system reset", UVM_MEDIUM)
#100; // 模拟复位时间
`uvm_info("test_case1", "Reset completed", UVM_MEDIUM)
phase.drop_objection(this);
endtask
task test_case1::main_phase(uvm_phase phase);
phase.raise_objection(this);
`uvm_info("test_case1", "test_case1 main_phase called!",UVM_LOW)
`uvm_info("test_case1", "Starting main operations", UVM_MEDIUM)
#200;
if (!need_second_reset) begin
need_second_reset = 1;
`uvm_warning("MAIN", "Detected condition requiring second reset - jumping to reset_phase")
// 关键跳转代码
phase.drop_objection(this);
phase.jump(uvm_reset_phase::get());
return; // 跳转后立即退出当前 phase
end
`uvm_info("test_case1", "Continuing normal operation after second reset", UVM_MEDIUM)
phase.raise_objection(this);
endtask
5. Objection 机制
5.1 核心概念
Objection 机制控制任务 Phase 的执行时间,防止仿真提前结束。
virtual task run_phase(uvm_phase phase);
phase.raise_objection(this); // 开始保护
#100; // 执行任务
phase.drop_objection(this); // 结束保护
endtask
5.2 使用位置
- Test 中:控制整个测试生命周期
- Sequence 中:控制序列执行时间
- 避免在:Driver、Monitor、Scoreboard 中使用
// Test 中控制
virtual task run_phase(uvm_phase phase);
phase.raise_objection(this);
main_seq.start(sequencer); // 启动序列
phase.drop_objection(this);
endtask
5.3 一个比喻说明objection机制
把 UVM Phase 比作一场会议:
- raise_objection -> 有人举手:"我还有话要说"
- drop_objection ,> 放下手:"我说完了"
- Phase 结束 -> 当所有人都放下手时,会议结束
如果有人一直举着手不放下,会议就永远无法结束!
// 就像这样:
virtual task meeting(uvm_phase phase);
phase.raise_objection(this); // 举手发言
present_my_ideas(); // 发表观点
phase.drop_objection(this); // 放下手结束
endtask
这样既保证了每个人都能充分发言,又能在完成后及时结束会议。
6. Phase的调试方法
# 查看phase执行详情
+UVM_PHASE_TRACE
+UVM_OBJECTION_TRACE
6.1 +UVM_PHASE_TRACE
作用:开启 UVM Phase 执行的详细跟踪信息
输出内容:
- 每个 Phase 的开始和结束时间
- Phase 执行的层次结构
- Phase 跳转和状态变化
- 执行顺序和依赖关系
使用场景:
- 调试 Phase 执行顺序问题
- 分析 Phase 跳转行为
- 理解 UVM 调度机制
示例输出: UVM_INFOuvm_phase.svh(1403) @ 0: reporter [PH/TRC/SCHEDULED] Phase 'common.build' (id=190) Scheduled from phase common UVM_INFO uvm_phase.svh(1124) @ 0: reporter [PH/TRC/STRT] Phase 'common.build' (id=190) Starting phase UVM_INFOuvm_phase.svh(1381) @ 0: reporter [PH/TRC/DONE] Phase 'common.build' (id=190) Completed phase
6.2 +UVM_OBJECTION_TRACE
作用:开启 Objection 机制的详细跟踪信息
输出内容:
- Objection 的提起和丢弃时间点
- Objection 计数器的变化
- 关联的组件和描述信息
- Phase 结束的条件判断
使用场景:
- 调试仿真挂起问题
- 分析 Objection 使用是否正确
- 追踪 Objection 生命周期
示例输出: UVM_INFO @ 400000: main_objection [OBJTN_TRC] Object uvm_test_top raised 1 objection(s): count=1 total=1 UVM_INFO @ 400000: main_objection [OBJTN_TRC] Object uvm_top added 1 objection(s) to its total (raised from source object uvm_test_top): count=0 total=1 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_test_top dropped 1 objection(s): count=0 total=0 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_test_top all_dropped 1 objection(s): count=0 total=0 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (dropped from source object uvm_test_top): count=0 total=0 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (all_dropped from source object uvm_test_top): count=0 total=0