在下面的示例中,我尝试在data
上提示my_interface
输出。但是,data
始终为0。
interface my_interface(
input clock,
output data);
clocking cb @(posedge clock);
output data;
endclocking
endinterface // my_interface
module test;
logic clock;
wire data;
my_interface my_interface(.*);
initial begin
clock = 0;
#1 $display("%0d data:%0d", $time, data);
#10;
my_interface.cb.data <= 1;
#1 $display("%0d data:%0d", $time, data);
@(my_interface.cb);
my_interface.cb.data <= 0;
#1 $display("%0d data:%0d", $time, data);
#20 $display("%0d data:%0d", $time, data);
$finish();
end
always #5 clock = ~clock;
endmodule
sim输出是:
# 1 data:z
# 12 data:z
# 16 data:0
# 36 data:0
我想了解上面示例中为什么data
永远不会1
?
我可以通过将#10
替换为@(my_interface.cb);
来解决此问题,但我不知道为什么此修复有效。
EDA游乐场的代码和结果:http://www.edaplayground.com/s/4/198
答案 0 :(得分:4)
在驱动或采样时钟块信号时使用@(my_interface.cb)以外的任何其他阻塞事件是非常危险的。代码行为方式的原因是由于14.16节同步驱动器中的此声明:
驱动器语句可以在不是的时间执行 与它的计时事件同时发生。此类驱动声明应 执行没有阻塞,但应执行其驱动操作,如同 他们在下一个时钟活动时已经执行了。
在你的例子中,你的两个驱动器语句在同一个循环中结束,最后写入获胜。
因此规则只是使用@(my_interface.cb)来阻止正在驱动或采样时钟块信号的进程。这包括不使用wait(cb.signal)而是使用@(cb iff(cb.signal))