文章目录
概要
UVM Objection 机制是实现验证平台同步的核心机制,它通过raise_objection和drop_objection操作控制测试的生命周期,确保所有组件完成必要的操作后才结束测试。以下从原理、实现到应用场景进行深度解析。
一、基本原理
1. 核心概念
-
Objection:测试阶段的 “通行证”,用于声明某个组件需要继续运行
-
Phase:UVM 将验证流程划分为多个阶段(如 build、run、report)
-
Objection 计数器:每个 phase 维护一个计数器,当计数为 0 时 phase 结束
2. 关键规则
- Raise:组件调用phase.raise_objection(this)声明需要继续运行
- Drop:组件完成任务后调用phase.drop_objection(this)释放通行证
- 超时机制:可设置超时时间防止测试卡死
- 层次控制:子组件的 objection 自动归属于当前 phase
二、UVM 仿真流程的基本原理
- UVM 仿真由多个阶段组成(如 build_phase, run_phase 等)。 run_phase
是一个时间消耗阶段,主要用于驱动事务和执行测试逻辑。 仿真默认会在所有组件的 run_phase 执行结束后,自动进入下一个阶段。
如果需要延长 run_phase(如等待事务完成或某些测试行为完成),可以通过 objection 机制 来实现。
1、raise_objection
用于通知 UVM 仿真框架:当前组件或测试类需要延长仿真时间。
每次调用 raise_objection,都会增加 UVM 仿真的活动计数。
2、drop_objection
用于通知 UVM 仿真框架:当前组件或测试类的任务已完成。
每次调用 drop_objection,都会减少 UVM 仿真的活动计数。
当活动计数减少到 0 时,UVM 仿真会结束当前阶段,进入下一个阶段。
三、核心 API
// 在某个phase中声明需要更多时间
virtual task my_task(uvm_phase phase);
phase.raise_objection(this, "Reason for raising"); // 提升objection
// 执行任务...
phase.drop_objection(this, "Reason for dropping"); // 降低objection
endtask
// 设置超时(防止测试卡死)
phase.phase_done.set_timeout(timeout_value); // 单位为时间单位
// 检查objection状态
phase.phase_done.get_objection_count(); // 获取当前计数
phase.phase_done.was_set_by(obj); // 检查某个对象是否提升过objection
四、 使用场景
1、阻止仿真提前结束:
如果没有任何 objection,UVM 的 run_phase 会立即结束。
使用 raise_objection 可以延长仿真时间。
2、协调多个组件的任务:
不同组件可能需要在不同时间完成任务。
raise_objection 和 drop_objection 可以确保所有组件的任务完成后再结束仿真。
3、管理测试流程:
在测试类中,使用 objection 机制来控制事务生成、数据验证等阶段的生命周期。
五、应用场景实例
1. Sequence 控制测试时长
class my_sequence extends uvm_sequence #(my_transaction);
`uvm_object_utils(my_sequence)
virtual task body();
uvm_phase phase = get_starting_phase();
if (phase != null)
phase.raise_objection(this, "Running sequence");
// 生成事务...
repeat (10) begin
`uvm_do(req)
end
if (phase != null)
phase.drop_objection(this, "Sequence completed");
endtask
endclass
2. Monitor 确保数据捕获完成
class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor)
virtual task run_phase(uvm_phase phase);
phase.raise_objection(this, "Monitoring DUT");
forever begin
// 捕获事务...
capture_transaction();
end
// 注意:实际应用中需要有终止条件
phase.drop_objection(this, "Monitoring stopped");
endtask
endclass
3. Scoreboard 等待所有比较完成
class my_scoreboard extends uvm_scoreboard;
`uvm_component_utils(my_scoreboard)
int transactions_to_check = 100;
virtual task main_phase(uvm_phase phase);
phase.raise_objection(this, "Scoreboard checking");
// 等待所有事务比较完成
wait(transactions_to_check == 0);
phase.drop_objection(this, "All checks completed");
endtask
virtual function void write(my_transaction t);
// 处理事务并比较
check_transaction(t);
transactions_to_check--;
endfunction
endtask
六、Objection 机制的实现原理
1. 内部计数器与状态机
- 每个 phase 维护一个计数器:
当调用raise_objection时,计数器递增
当调用drop_objection时,计数器递减
当计数器归零时,phase 进入关闭流程
2. 异步与同步处理
异步阶段(如 run_phase):所有组件并行提升 / 降低 objection
同步阶段(如 build_phase):按层次顺序执行,objection 机制不适用
3. 跨阶段通信
可通过uvm_event或uvm_barrier实现阶段间同步
避免在一个 phase 中控制另一个 phase 的 objection
七、最佳实践与常见问题
1. 最佳实践
-
明确责任:每个组件只负责自己的 objection
-
避免嵌套:在同一 phase 中不要多次 raise/drop
-
设置超时:关键 phase 设置合理超时时间
-
统一接口:通过基类封装 objection 操作
2. 常见问题及解决方案
八、高级应用:自定义同步点
通过继承uvm_phase_done类,可实现自定义同步逻辑:
class my_phase_done extends uvm_phase_done;
`uvm_object_utils(my_phase_done)
// 添加自定义状态变量
int special_count = 0;
function new(string name = "my_phase_done");
super.new(name);
endfunction
// 重写can_proceed方法
virtual function bit can_proceed();
// 只有当special_count也为0时才允许phase继续
return (super.can_proceed() && special_count == 0);
endfunction
endclass
// 在phase中使用自定义phase_done
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_phase_done my_done;
virtual function void build_phase(uvm_phase phase);
my_done = my_phase_done::type_id::create("my_done");
phase.phase_done = my_done; // 替换默认的phase_done
endfunction
endclass
九、总结
掌握 Objection 机制是构建稳定、高效 UVM 验证环境的关键。通过合理使用该机制,可以确保测试流程按预期执行,同时避免常见的同步问题。