「Verilog合成でのノンブロッキング割り当て、殺すコーディングスタイル!」を読みました。クリフォードカミングスによる。彼は、次のコード(12ページ、簡略化)は、教科書でよく使用されるフリップフロップの正しい実装であると述べています。この文書は最優秀論文賞を受賞したので、その主張は真実だと思います。
module ff (q, d, clk)
output q;
input d, clk;
reg q;
always @(posedge clk)
q = d;
endmodule
これらのフリップフロップを2つ以上直列に接続した場合に、なぜこれが正しく機能し続けるのかを知りたいです。言う
module two_ffs (q, d, clk)
input d, clk;
output q;
wire tmp;
ff firstff (tmp, d, clk);
ff secondff (q, tmp, clk);
endmodule
私の見方では、tmpの値がsecondffによって使用される前に更新される可能性があるため、2つではなく1つのフリップフロップになります。誰かが基準のどの部分が起こり得ないと言っているか教えてもらえますか?どうもありがとう。
[そのようなコードを書くことを考えたことはありません。コーディングスタイルが貧弱で意味が自明でない場合でも、ブロック/非ブロックの動作を理解したいだけです]
後で追加:
私は今、その論文が正しくない可能性が高いと思います。1364-2201Verilog標準のセクション5「SchedulingSemantics」では、何が起こるかについて説明しています。特に、68ページのセクション5.6.6「ポート接続」では、単方向ポートは連続割り当てとまったく同じであると述べています。同様に、継続的な割り当ては、常にすべてに敏感なブロックです。つまり、以下の私の例でのffの2つのインスタンス化は、複数のalways句を持つモジュールと同等であり、誰もが同意するだろうということです。
Clive Cummingsが質問に答えた後に追加されました:
規格のセクション5から抜粋した上記のステートメントは、更新イベントのタイミングのみを参照しており、一部の継続的な割り当てと常にブロックの間の文字通りの同等性を意味するものではないことを指摘してくれたCCに感謝します。それでも、一部のシミュレーター(Icarus Verilogなど)が「フリップフロップ」でブロッキングと非ブロッキングの割り当てを使用して異なるシミュレーション結果を生成する理由を説明していると思います。[より大きな例では、ブロッキング割り当てで2つの明らかなffが得られ、非ブロッキング割り当てで正しい5つが得られました。]他のシミュレーター(たとえば、デフォルトオプションまたはCverを備えたModelsim)は、どの形式でも同じ結果を生成するようです。割り当てが使用されます。