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

phase.raise.objection (phase); seq=new(); 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。


二、结合你的代码逐行解析

systemverilog 复制代码
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 发给 driver,driver 驱动 DUT,可能需要等几十、几百甚至几千个时钟周期。
  • 所以必须在它前面 raise_objection,否则仿真会在时间 0 就结束,sequence 根本跑不完。

4. phase.drop_objection(phase);

  • sequence 跑完后,撤销之前的 objection。
  • 此时 objection 计数器减 1。
  • 如果这是最后一个 objection,UVM 就会结束当前 phase,进入下一个 phase。
  • 同样,标准写法是 phase.drop_objection(this);。

三、为什么说它们"极其重要"?

1. 没有 raise/drop,仿真会瞬间结束

UVM 的 run_phase 默认行为是:

如果没有任何 objection 被 raise,run_phase 会在时间 0 立即结束。

也就是说,如果你写:

systemverilog 复制代码
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 结束,进入下一个 phase
  • raise_objection 相当于"拉住刹车";
  • drop_objection 相当于"松开刹车";
  • 只有所有"刹车"都松开,phase 才会结束。

3. 多组件并行时的同步作用

一个测试平台里可能有多个组件同时 raise objection:

  • test 里启动 sequence;
  • scoreboard 里等待比对完成;
  • monitor 里等待采集完最后一笔数据。

只要任何一个组件还持有 objection,run_phase 就不会结束。这保证了所有组件都能把自己该干的事干完。


四、标准写法示例

systemverilog 复制代码
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 里用 objection build_phase 是 function phase,不消耗时间,objection 无效,也不该用
raise 了忘记 drop 仿真会一直卡住,直到超时(phase_done 超时)
drop 了没 raise UVM 会报 warning/error,objection 计数器不能为负
用 new() 创建 sequence 不推荐,应该用 type_id::create(),否则无法被 factory override
传参传 phase 而不是 this 语法允许,但标准写法是传 this,便于调试和追踪 objection 来源

六、一句话总结

raise_objection 是"等等我还没干完",drop_objection 是"我干完了,可以走了"。

它们决定了 run_phase 什么时候结束,是 UVM 仿真时间推进的核心控制机制。没有它们,run_phase 会在时间 0 直接结束,sequence 根本跑不起来。所以它们非常重要,而且是每个 UVM 验证工程师必须掌握的基础。

相关推荐
叶子野格11 小时前
《FPGA基本知识累积:看开发指南要懂的术语》
学习·fpga开发
傻童:CPU13 小时前
vivado中ILA出现no connect
fpga开发
松小白song1 天前
【硬核排错实录】FPGA DDS 波形卡死:寄存器有值但正弦 / 三角 / 自定义波形完全不输出(双通道失效终极解决)
fpga开发
星夜离尘561 天前
UART偶发乱码:波特率分频误差之外,还要算采样漂移
fpga开发·uart
hexiaoyan8271 天前
271-基于JFM7VX690T36 的四路40Gbps的PCIeX8 全国产化卡
fpga开发·软件无线电处理平台·硬件加速器·jfm7vx690t36·全国产化卡·7vx690t36
Terasic友晶科技2 天前
答疑解惑|Agilex 5如何指定Boot Core及设定Core的运行频率?
fpga开发·hps·terasic·cortex-a55·cortex-a76·boot core
辰丁电子2 天前
allegro入门教程-菜单栏Route
fpga开发·pcb工艺·pcb·layout·allegro软件
吉他英雄一里2 天前
FPGA工具篇--ILA
fpga开发
鸥梨菌Honevid2 天前
UVM sequence-driver 通信模型(详细讲解)
fpga开发