0

SystemVerilog の 2012 ルール 4.7 がどのように実装されているかについて、私はまだ少し混乱しています。規則では、次のような状況で次のように規定されています。

module test;
  logic a;
  integer cnt;

  initial begin
    cnt = 0;
    #100;
    a <= 0;
    a <= 1;
    a <= 0;
    a <= 1;
    a <= 0;
  end

  always @(posedge a)
    begin
      cnt <= cnt + 1;
    end
endmodule

すべての割り当ては非ブロッキング割り当てキューでスケジュールされ、順番に実行する必要があります。最後の値が勝ちます。ここまでは、すべてクリアです。

次に何が起こるかは、すべてのシミュレーターで同じではありません。iverilog および Modelsim (少なくとも Vivado 2016/3 エディション) は、'a' に1 つのイベントを作成し、これにより cnt がインクリメントされます。これは、カミングス氏が SNUG 2000 で示した動作とも一致しているようです。

ただし、VCS は中間値を除外し、最後の値のみを適用します。ちなみに、これは実際のフリップフロップの動作方法でもあります。

この場合、これは純粋に仮説的な議論ではなく、シミュレーション結果が異なります。また、iverilog/modelsim の動作がバグを引き起こす可能性があり、フロップはトグルしますが、波形に値の変化は見られないため、検出が非常に困難です。

もう 1 つのポイントは次のとおりです。iverilog/modelsim が正しい場合、なぜ2 つではなく1 つのイベントを作成するのでしょうか?

編集:追加のメモ。

上記の例は、実際にはあまり意味がありません。より現実的なケースは

always @(posedge clk)
  begin
    clk2 <= 1'b1;
    if (somecondition)
      clk2 <= 1'b0;
  end

always @(posedge clk2, negedge rst_n)
  begin
    if (!rst_n)
      q <= 1'b0;
    else
      q <= ~q;
end

これは完全に合法であり、実際のハードウェアではグリッチは発生しません。最初の always は実際には論理的に同一です

always @(posedge clk)
  begin
    if (somecondition)
      clk2 <= 1'b0;
    else
      clk2 <= 1'b1;
  end

ただし、ModelSim で最初のバージョンをシミュレートすると、q が clk2 定数 0 で喜んでトグルすることがわかります。これはデバッグの悪夢です。

4

1 に答える 1

1

最後の質問は簡単に説明できます。シミュレーターがイベントを 1 つだけ作成するわけではありません。最初のイベントのみが @(posedge) をスケジュールしてalwaysプロセスを再開し、他のイベントは NBA リージョンで発生してから、常にブロックが次のアクティブなイベントで実行を再開します。領域。

他のシミュレーターの動作を正当化することはできません。実際のハードウェアでは同じフリップフロップに複数の割り当てを行うことは許可されていないため、類推はそれほど単純ではありません。時間指定なしの説明を使用して、時間が経過することなく複数の (@posedge の) 説明を取得することができます。したがって、フィルタリングはそのコーディング スタイルを妨げます。

于 2016-11-11T17:24:59.250 に答える