关于event.triggered的使用的困惑

Tud*_*imi 3 system-verilog

我尝试了一些代码,应该阻止,直到移动到一个新的模拟时间步长(类似于等待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
Run Code Online (Sandbox Code Playgroud)

它背后的想法是我触发一些事件,这意味着triggered当控制到达线时,它的字段将变为1 wait(!e.triggered).该行应在下一个时隙中解除阻塞,何时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);
Run Code Online (Sandbox Code Playgroud)

我看到消息做东西做过的东西,但Wait trig done永远不会到来.模拟也在到达之前停止finish(1).一位模拟器告诉我,这是因为没有安排其他事件.

所有模拟器都表现出相同的行为,因此必须有一些我缺少的东西.谁能解释一下发生了什么?

dav*_*_59 6

问题是wait (!e.triggered);何时e.triggered从1变为零.它必须在无法安排任何内容的区域中进行更改,因此无论是在当前时隙结束时更改,还是在下一个时隙的开头都不可观察.因此,wait会挂起等待当前时间段的结束,这个时间段永远不会到来.

我认为最接近你要找的是#1step.这将阻止最小的模拟精确时间步长.但我必须相信,有一种更好的方法来编码你想要的东西,而不必知道时间是否在推进.