首页 / 资讯中心 / 文章详情

UVM 中 raise_objection 与 drop_objection 的作用与重要性详解

UVM 中 raise_objection 与 drop_objection 的作用与重要性详解 ★ FEATURED ARTICLE
phase.raise.objection (phase); seqnew(); seq.start(e.sgr);phase.drop_objection(phase) ;其中raise和drop是什么作用是否重要在 UVM 的run_phase或其它消耗时间的 task phase中raise_objection和drop_objection是极其重要、不可或缺的机制。它们直接决定了仿真会不会“提前结束”以及各个组件之间的运行时间能否对齐。一、它们的作用是什么UVM 的 phase 机制尤其是run_phase及其子 phase靠objection反对/异议机制来判断“这个 phase 该不该结束”。raise_objection提起异议告诉 UVM 调度器“我现在正在干活比如启动 sequence、驱动激励这个 phase 还不能结束请等我。”drop_objection撤销异议告诉 UVM 调度器“我干完活了这个 phase 可以结束了如果别人也没有异议的话。”UVM 只有在所有组件都 drop 了 objection即没有任何 objection 被 raise之后才会结束当前 phase进入下一个 phase。二、结合你的代码逐行解析phase.raise_objection(phase); seq new(); seq.start(e.sgr); phase.drop_objection(phase);1.phase.raise_objection(phase);phase是当前运行的 phase 对象比如run_phase。raise_objection是uvm_phase类的方法。传入的参数phase注意标准写法通常是this即当前组件表示是谁提出了这个 objection。标准写法是phase.raise_objection(this);。这里传了phase本身语法上不报错但追踪 objection 来源时会有些奇怪。建议改成this。执行这行后UVM 的 objection 计数器加 1当前 phase 不会结束。2.seq new();创建一个 sequence 对象。注意这里用了new()而不是type_id::create()意味着这个 sequence 不走 factory不会被 override。如果想让 sequence 支持工厂覆盖应该用seq my_seq::type_id::create(seq);。这一步本身不消耗仿真时间只是分配内存。3.seq.start(e.sgr);start是uvm_sequence的方法。e.sgr是 sequencer 的句柄假设e是某个环境组件sgr是它里面的 sequencer。seq.start(e.sgr)会把 sequence 挂到 sequencer 上然后开始执行 sequence 的body()任务。这是一个消耗仿真时间的操作sequence 会通过start_item/finish_item把 item 发给 driverdriver 驱动 DUT可能需要等几十、几百甚至几千个时钟周期。所以必须在它前面raise_objection否则仿真会在时间 0 就结束sequence 根本跑不完。4.phase.drop_objection(phase);sequence 跑完后撤销之前的 objection。此时 objection 计数器减 1。如果这是最后一个 objectionUVM 就会结束当前 phase进入下一个 phase。同样标准写法是phase.drop_objection(this);。三、为什么说它们“极其重要”1. 没有 raise/drop仿真会瞬间结束UVM 的run_phase默认行为是如果没有任何 objection 被 raiserun_phase会在时间 0 立即结束。也就是说如果你写task run_phase(uvm_phase phase); seq new(); seq.start(e.sgr); endtask仿真会在时间 0 直接跳过run_phase你的 sequence 根本来不及跑DUT 也收不到任何激励。你会看到仿真“什么都没干就结束了”。2. 它们控制 phase 的结束时机UVM 的 phase 执行流程进入 run_phase ↓ 所有组件并行执行 run_phase 任务 ↓ 等待所有 objection 被 drop ↓ run_phase 结束进入下一个 phaseraise_objection相当于“拉住刹车”drop_objection相当于“松开刹车”只有所有“刹车”都松开phase 才会结束。3. 多组件并行时的同步作用一个测试平台里可能有多个组件同时 raise objectiontest里启动 sequencescoreboard里等待比对完成monitor里等待采集完最后一笔数据。只要任何一个组件还持有 objectionrun_phase就不会结束。这保证了所有组件都能把自己该干的事干完。四、标准写法示例class my_test extends uvm_test; uvm_component_utils(my_test) my_sequence seq; my_env e; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); e my_env::type_id::create(e, this); endfunction task run_phase(uvm_phase phase); // 1. 提起 objection阻止 phase 结束 phase.raise_objection(this); // 2. 创建并启动 sequence seq my_sequence::type_id::create(seq); seq.start(e.sgr); // 3. 撤销 objection允许 phase 结束 phase.drop_objection(this); endtask endclass注意顺序raise_objection必须在消耗时间的操作如seq.start之前drop_objection必须在消耗时间的操作之后如果中间有fork...join或异常要确保drop_objection一定被执行可以用try...finally或仔细控制流程。五、常见误区与注意事项误区说明在build_phase里用 objectionbuild_phase是 function phase不消耗时间objection 无效也不该用raise了忘记drop仿真会一直卡住直到超时phase_done超时drop了没raiseUVM 会报 warning/errorobjection 计数器不能为负用new()创建 sequence不推荐应该用type_id::create()否则无法被 factory override传参传phase而不是this语法允许但标准写法是传this便于调试和追踪 objection 来源六、一句话总结raise_objection是“等等我还没干完”drop_objection是“我干完了可以走了”。它们决定了run_phase什么时候结束是 UVM 仿真时间推进的核心控制机制。没有它们run_phase会在时间 0 直接结束sequence 根本跑不起来。所以它们非常重要而且是每个 UVM 验证工程师必须掌握的基础。
阅读完成 · 觉得有帮助?
咨询建站