我尝试了一些代码,应该阻止,直到移动到一个新的模拟时间步长(类似于等待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).一位模拟器告诉我,这是因为没有安排其他事件.
所有模拟器都表现出相同的行为,因此必须有一些我缺少的东西.谁能解释一下发生了什么?
问题是wait (!e.triggered);何时e.triggered从1变为零.它必须在无法安排任何内容的区域中进行更改,因此无论是在当前时隙结束时更改,还是在下一个时隙的开头都不可观察.因此,wait会挂起等待当前时间段的结束,这个时间段永远不会到来.
我认为最接近你要找的是#1step.这将阻止最小的模拟精确时间步长.但我必须相信,有一种更好的方法来编码你想要的东西,而不必知道时间是否在推进.