除了使用同时触发的命名事件外,有没有办法询问模拟是否在@(posedge clk)
事件?
使用以下代码,我可以确保我只在时钟的位置上做事:
module tb;
bit clk;
always #2 clk = ~clk;
event pos_clk;
always @(posedge clk)
-> pos_clk;
initial begin
// stuff happens
@(posedge clk);
$display("[%0d] @(posedge clk)", $time());
// control is passed asynchronously to some task
// - since it's already at a posedge, it doesn't need to wait
some_task();
// other stuff happens
#1;
$display("[%0d] #1", $time());
// control is passed asynchronously to some task
// - since it's not at a posedge, it needs to catch the next one
some_task();
$finish();
end
task some_task();
wait (pos_clk.triggered);
$display("[%0d] wait (pos_clk.triggered)", $time());
// do relevant stuff
endtask
endmodule
如果没有额外的命名事件,还有其他方法吗?
答案 0 :(得分:2)
这是##0
构造的作用(参见 14.11循环延迟:1800-2012 LRM的## 部分)。您必须定义默认时钟块,这意味着您的任务必须在module
或interface
module tb;
bit clk;
always #2 clk = ~clk;
default clocking cb @(posedge clk)
endclocking
initial begin
// stuff happens
@(cb) // when using clocking blocks, only use the clocking event
$display("[%0d] @(posedge clk)", $time());
// control is passed asynchronously to some task
// - since it's already at a posedge, it doesn't need to wait
some_task();
// other stuff happens
#1;
$display("[%0d] #1", $time());
// control is passed asynchronously to some task
// - since it's not at a posedge, it needs to catch the next one
some_task();
$finish();
end
task some_task();
##0;
$display("[%0d] wait (pos_clk.triggered)", $time());
// do relevant stuff
endtask
endmodule
我的建议是不要做任何事情并找出一种方法来保持some_task
的同步激活。