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 同期ドライブのこのステートメントによるものです。

ドライブ ステートメントは、そのクロッキング イベントと一致しない時間に実行される可能性があります。このようなドライブ ステートメントは、ブロックせずに実行されますが、次のクロッキング イベントの時点で実行されたかのように、ドライブ アクションを実行する必要があります。

あなたの例では、2 つのドライブ ステートメントが同じサイクルで運転を終了し、最後の書き込みが優先されます。

したがって、ルールは、@(my_interface.cb) を使用して、クロッキング ブロック信号を駆動またはサンプリングしているプロセスをブロックすることだけです。これには、wait(cb.signal) を使用せず、代わりに @(cb iff (cb.signal)) を使用することが含まれます。

于 2013-09-29T08:07:48.930 に答える