为什么输出不是通过接口时钟模块驱动的?

时间:2013-09-27 22:29:14

标签: interface verilog system-verilog

在下面的示例中,我尝试在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

1 个答案:

答案 0 :(得分:4)

在驱动或采样时钟块信号时使用@(my_interface.cb)以外的任何其他阻塞事件是非常危险的。代码行为方式的原因是由于14.16节同步驱动器中的此声明:

  

驱动器语句可以在不是的时间执行   与它的计时事件同时发生。此类驱动声明应   执行没有阻塞,但应执行其驱动操作,如同   他们在下一个时钟活动时已经执行了。

在你的例子中,你的两个驱动器语句在同一个循环中结束,最后写入获胜。

因此规则只是使用@(my_interface.cb)来阻止正在驱动或采样时钟块信号的进程。这包括不使用wait(cb.signal)而是使用@(cb iff(cb.signal))