UVM phase、objection 与 end-of-test
更新时间:2026-10-01。已有 UVM 组件与 phase 和 objection 机制,本文聚焦一个高频痛点:仿真要么提前结束、要么永远不结束。
本文要回答的问题
- 各 phase 谁先执行,run_phase 和 12 个 sub-phase 什么关系?
- objection 为什么能决定仿真何时停?
- 想“所有在途事务排空再结束”怎么做?
一、phase 执行序
- 自上而下:build_phase 沿组件树从根向叶执行(父要先建好子才能配置)。
- 自下而上:connect/end_of_elaboration 等从叶向根执行。
- run_phase:耗时任务,所有组件并发运行。
- run_phase 与
reset/configure/main/shutdown四个任务型 sub-phase 并行二选一(同一组件不应同时用),sub-phase 提供按阶段的顺序控制。
二、objection 决定结束
组件/序列在开始活动时 raise_objection,完成后 drop_objection。当某 phase 的所有 objection 都撤销且经过 drain time,该 phase 结束;所有 phase 完成后仿真退出。没 raise 任何 objection,平台可能在零时间直接结束(激励还没发就停)。
task run_phase(uvm_phase phase);
phase.raise_objection(this);
vseq.start(env.vsqr); // 真实活动
phase.drop_objection(this);
endtask三、drain 与 phase_ready_to_end

phase.set_drain_time(this, 200ns):drop 后再等固定时间,收完延迟响应。phase_ready_to_end(phase):在即将结束时回调,若 scoreboard 还有未匹配事务,可临时再 raise,排空后再 drop,杜绝“提前收尾漏掉结果”。
四、常见坑
- objection raise 太晚(在某个延时之后),仿真在它 raise 前就被判结束。
- drop 后没 drain,延迟到达的输出没被比较。
- 异常分支提前 return 没 drop(永不结束)或重复 drop。
- run_phase 和 sub-phase 混用造成顺序混乱。
- 只在 sequence 里控制,组件 phase 已结束导致停止无效。
小结
build 自上而下、connect 自下而上,run 并发;objection 是结束阀门,drain time 与 phase_ready_to_end 保证排空再结束。下一篇 UVM 工厂机制与环境派生。
总结
精确控制仿真何时结束靠 phase + objection:build_phase 自顶向下执行(父先建子才能配置)、connect 等自底向上、run_phase 所有组件并发,且 run_phase 与 reset/configure/main/shutdown 四个 sub-phase 是并行二选一、不应混用。objection 是结束阀门——开始活动时 raise_objection、完成后 drop_objection,某 phase 所有 objection 撤销并经过 drain time 该 phase 才结束;不 raise 任何 objection,平台可能零时间直接结束(激励还没发就停),所以要尽早 raise。想“所有在途事务排空再结束”,用 set_drain_time 固定等待延迟响应,或重写 phase_ready_to_end 在即将结束时检查 scoreboard 残余事务、未排空就临时再 raise。常见故障是 raise 太晚、drop 后没 drain 漏比延迟输出、异常分支没 drop 导致永不结束。