0

2つの質問

  1. システム Verilog 2012 リファレンス ガイドには、ブロックalways_combのクロッキング リファレンスがないため、シーケンシャル ロジックのコーディングへの参照があります。always_combalways_comb

ここに画像の説明を入力

  1. Synopsys Verdi でシステム Verilog アサーションを使用しているときに、プロパティが満たされた後、半分または 1 クロック サイクル後に緑の矢印 (アサートされたプロパティが満たされていることを示す) が起動される可能性はありますか?

ありがとう

4

1 に答える 1

4

質問 1 について。ノンブロッキング割り当ては、必ずしもシーケンシャルな動作を意味するわけではありません。ブロッキング/ノンブロッキング代入はシミュレーション構造です。理解を深めるために、小さな例を見てみましょう。

module some_gate(
  input logic a,
  input logic b,
  output logic c,
  output logic d
);

  // c is 'a or b'
  // d is 'a and c'
endmodule

2 つの入力信号と 2 つの出力信号があります。複合ゲートをモデル化します。

従来の Verilog スタイルでは、次のように記述します。

always @(a or b) begin
  c = a || b;
  d = a && c;
end

これは、aまたはが変化するたびに、とbの値を計算することを意味します。に対してブロッキング代入を使用したため、ここで計算した値は の計算に「伝播」されます。これは基本的に、 で記述されたロジックを のロジックの後に連鎖させたことを意味します。cdcddc

これは、小さなテストベンチを使用してテストできます。

module test; 
  logic a, b, c, d;

  some_gate dut(.*);

  always @(a or b or c or d)
    $display("[%0d] a = %b, b = %b, c = %b, d = %b", $time(), a, b, c, d);

  initial begin
    #1 a = 1;
    #1 b = 1;
    #1 a = 0;

    #1 $finish();
  end  
endmodule

これをシミュレートすると、次のようになります。

[1] a = 1, b = x, c = x, d = x
[1] a = 1, b = x, c = 1, d = 1
[2] a = 1, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 0

これは、表示プロセスが変数の変更ごとに 1 回トリガーされるためです。は からにa変更されますが、まだ更新されていません。次に、同じ時間ステップで更新されます。後で、 を変更しますが、これはまたはの変更をトリガーしません。その後、同じタイム スライスで再度変更し、更新されます。x1ccdbcdad

センシティビティ リストを指定しなければならないのは少し冗長です。なぜなら、組み合わせロジックが必要であることがわかっている場合は、代入の右側にある何かが変更されるたびにプロセスを再トリガーする必要があるからです。これがalways_comb目的です。

always_combセンシティビティ リストを削除するだけで、を使用してコードを書き直すことができます。

always_comb begin
  c = a || b;
  d = a && c;
end

このコードを実行すると、同じ出力が得られます。

[1] a = 1, b = x, c = x, d = x
[1] a = 1, b = x, c = 1, d = 1
[2] a = 1, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 0

次に興味深い部分です。always_comb非ブロッキング割り当てを使用して、まったく同じ回路をモデル化できます。

always_comb begin
  c <= a || b;
  d <= a && c;
end

ただし、このコードを実行すると、わずかに異なる出力が生成されます。

[1] a = 1, b = x, c = x, d = x
[1] a = 1, b = x, c = 1, d = x
[1] a = 1, b = x, c = 1, d = 1
[2] a = 1, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 1
[3] a = 0, b = 1, c = 1, d = 0

最初のタイム ステップでは、1 つではなく 3 つのプリントがあることに注意してください。ここで何が起こるかを詳しく見てみましょう。まず、 を変更aしますが、cまだd更新されていません。第二に、c更新されdますが、同じままです。これは、 の非ブロッキング代入が原因で、cd「古い」値が「見える」ことになりcます。3 番目に、c公式に更新された後、ツールは更新をスケジュールdし、最初の時間ステップの最後の印刷を確認します。残りは前の場合と同じです。

always_comb割り当ての右側で何かが変更されるたびに再トリガーされる前の段落を思い出してください。ここでのトリックは、これalways_combが実際には次のように動作することです。

always @(a or b or c) begin
  c <= a || b;
  d <= a && c;
end

これは非標準の Verilog ですが、同じロジックをモデル化します。c機密リストに明示的に追加されていることに注意してください。これを省略すると、ラッチを説明することになります。このスタイルは、間違いやすい (つまり、センシティビティ リストに中間ロジック ノードを追加するのを忘れる) ため、お勧めできません。

ここで重要なポイントは、ブロッキング代入またはノンブロッキング代入は、順次ロジックまたは組み合わせロジックを記述しないということです。コードからどの論理回路が推論されるかを制御するのは、コンテキスト全体 (つまり、いつ実行されるかを決定するセンシティビティ リスト) です。

完全なコード例はEDAPlaygroundで入手できます。

質問 2 について。これはツール固有のものであり、これに関するフォーラムではありません。ベンダーの Web サイトでこれを確認する必要があります。

于 2016-12-21T07:42:39.393 に答える