interface - 为什么不通过接口(interface)时钟 block 驱动输出?

标签 interface verilog system-verilog

在下面的示例中,我试图在 my_interface 上脉冲输出 data。但是,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

最佳答案

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

It is possible for a drive statement to execute at a time that is not coincident with its clocking event. Such drive statements shall execute without blocking, but shall perform their drive action as if they had executed at the time of the next clocking event.

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

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

关于interface - 为什么不通过接口(interface)时钟 block 驱动输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19061075/

相关文章:

数组乘法的 Verilog For 循环

verilog - 无法理解 D 触发器代码中的错误

system-verilog - UVM RAL : Randomizing registers in a register model

java : advanced inheritance to jpa

c# - 如何确定类型是否实现了 C# 反射的接口(interface)

verilog - 我如何测量 gtkwave 中两个标记之间的时间?

system-verilog - 在UVM中重写后如何获取类句柄的属性?

arrays - 通过verilog中的模块传递数组

java - 覆盖接口(interface)中的方法是否有意义

php - 在 PHPUnit 上使用方法中的类型提示创建接口(interface)的 Mock 对象失败