关于 event.triggered 用法的困惑

Confusion regarding usage of event.triggered

我正在尝试一些应该阻塞的代码,直到移动到新的模拟时间步长(类似于在 e 中等待 sys.tick_start)。

我尝试编写一个函数来执行此操作:

  task wait_triggered();
    event e;
    `uvm_info("DBG", "Waiting trig", UVM_NONE)
    -> e;
    $display("e.triggered = ", e.triggered);
    wait (!e.triggered);
    `uvm_info("DBG", "Wait trig done", UVM_NONE)
  endtask

它背后的想法是我触发了一些事件,这意味着当控件到达带有 wait(!e.triggered) 的行时,它的 triggered 字段将为 1。此行应在下一个时间段解锁,届时 triggered 将被清除。

为了测试这一点,我添加了一些其他消耗模拟时间的线程:

fork
  wait_triggered();

  begin
    `uvm_info("DBG", "Doing stuff", UVM_NONE)
    #1;
    `uvm_info("DBG", "Did stuff", UVM_NONE)
  end
join
#1;
$finish(1);

我看到消息做事做事,但是等待触发完成从来没有来了。模拟也在到达 finish(1) 之前停止。一个模拟器告诉我这是因为没有安排更多的事件。

所有模拟器都表现出相同的行为,所以一定有我遗漏的地方。谁能解释一下这是怎么回事?

e.triggered 从 1 变为零时,问题出在 wait (!e.triggered); 上。它必须在一个什么都不能调度的区域发生变化,所以它是在当前时隙结束时发生变化,还是在下一个时隙开始时发生变化是不可观察的。因此 wait 将挂起等待当前时间段的结束,而该时间段永远不会到来。

我认为最接近您要查找的内容是 #1step。此块用于最小仿真精度时间步长。但我必须相信有一种更好的方法来编写您想要的代码,而不必知道时间是否在推进。