3

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

模拟输出是:

# 1 data:z
# 12 data:z
# 16 data:0
# 36 data:0

我想了解为什么在上面的示例中data从未1出现过?我可以通过替换来解决这个问题#10@(my_interface.cb);但我不知道为什么这个修复有效。

EDA Playground 上的代码和结果:http ://www.edaplayground.com/s/4/198

4

1 回答 1

4

在驱动或采样时钟块信号时使用除@(my_interface.cb) 之外的任何其他阻塞事件是非常危险的。您的代码如此行为的原因是因为第 14.16 节同步驱动中的这条语句:

驱动器语句可能在与其时钟事件不一致的时间执行。此类驱动语句应在没有阻塞的情况下执行,但应执行它们的驱动动作,就好像它们已在下一个时钟事件发生时执行一样。

在您的示例中,您的两个驱动器语句最终在同一个周期中驱动,最后写入获胜。

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

于 2013-09-29T08:07:48.930 回答