ブロッキング割り当てとノンブロッキング割り当てVerilogの違い


15

私がこのページを読んでいたのは、http://www.asic-world.com/verilog/verilog_one_day3.htmlで、次のものに出くわしたときです。

通常、フリップフロップをリセットする必要があるため、クロックが0から1(ポーズ)に移行するたびに、リセットがアサートされているかどうかを確認し(同期リセット)、通常のロジックを続行します。よく見ると、組み合わせロジックの場合、割り当てに「=」があり、順次ブロックには「<=」演算子があります。「=」は割り当てをブロックし、「<=」はブロックしない割り当てです。「=」は、begin / end内でコードを順番に実行しますが、ノンブロッキングの「<=」は並行して実行されます。

ブロッキングの割り当てが並列であるのに対し、ノンブロッキングの割り当ては順次であると確信していました。結局のところ、常にブロックの外側にあるassignステートメントでブロック割り当てを行うことができ、それらはすべて並行して実行されます。これは間違いですか、それともalwaysブロック内の動作は異なりますか?また、常にブロック内で動作が異なる場合、非ブロック割り当てを常時ブロック外で行うことはできますか?

回答:


21

ブロッキング割り当てが並列であるのに対して、ノンブロッキング割り当ては連続的であるとかなり確信していました。

ブロック割り当ては、完了するまで次のステートメントの実行をブロックするため、ブロック割り当ては「連続して」実行されます。したがって、次のステートメントの結果は、完了する最初のステートメントに依存する場合があります。

非ブロッキング割り当ては、同時に発生する割り当てを記述するため、並行して実行されます。2行目のステートメントの結果は、1行目のステートメントの結果に依存しません。代わりに、2行目は1行目がまだ発生していないかのように実行されます。


では、assignステートメントについてはどうでしょうか?彼らは自分たちだけのクラスにいますか?
ボイドスター

4
はい、assignステートメントは常にブロックの外側で発生し、通常は組み合わせ(非ラッチ)ロジックを記述するために使用されます(一部の例外を除き、常にブロックはシーケンシャルロジックを記述します)。私の知るassign限り、LHSの値が変更されると、ステートメントは常に「並行して」実行されます。
ザフォトン

さて...私は、Verilogが最もエレガントに設計された言語ではないという印象を受け始めています。これは、Cの学習のようになります。
ボイドスター

1
Verilogは、すでに存在するハードウェアを「記述する」ように設計されています。ハードウェアを設計(合成)するための言語として使用することはハックです。
のフォトン

4
Verilogの「C言語の学習」が問題になる場合は、VHDLをご覧ください。一部の人々はどちらか一方に対してかなり強い好みを持っています。一部の人にとっては、VHDLは冗長すぎるだけです。私にとっては、考え抜かれた方がずっといいです。(例えば、シグナル/変数の割り当てのセマンティクスは、ブロッキング/ノンよりもはるかに明確です)。stackoverflow.com/questions/13954193/…およびsigasi.com/content/vhdls-crown-jewelあなたはそれを好むか嫌うかもしれません。しかし、一見の価値があります。
ブライアンドラモンド

6

assign文は「ブロック」でも「非ブロック」でもなく、「連続」です。assignステートメントの出力は、その入力の指定された関数と常に等しくなります。「ブロック」と「非ブロック」の割り当ては、常にブロック内にのみ存在します。

ブロッキング割り当ては、処理されるとすぐに有効になります。ノンブロッキング割り当ては、現在の「時間差」の処理の最後に行われます。

alwaysブロックを使用して、組み合わせロジックまたはシーケンシャルロジックをモデル化できます(systemverilogには、これを明示するためにalways_combとalways_ffがあります)。組み合わせロジックをモデル化する場合、通常は=を使用する方が効率的ですが、通常は重要ではありません。

シーケンシャルロジックをモデル化する場合(例:常に@(posedge clk))、通常は非ブロッキングの割り当てを使用します。これにより、「クロックエッジ前の状態」の観点から「クロックエッジ後の状態」を決定できます。

連続的な常時ブロックでのブロッキング割り当てを「変数」として使用すると便利な場合があります。これを行う場合、2つの重要なルールがあります。

  1. 割り当てられている常時ブロックの外部から、常時常時ブロック内のブロッキング割り当てで設定されたregにアクセスしないでください。
  2. 同じregにブロッキングとノンブロッキングの割り当てを混在させないでください。

これらの規則を破ると、合成エラーが発生したり、シミュレーションと合成の動作に違いが生じたりする可能性があります。


「「割り当てられた常時ブロックの外部から、順次常時ブロック内のブロッキング割り当てで設定されたregにアクセスしないでください。」」説明してください。
user125575

異なる連続したAlwaysブロックには、順序が定義されていません。したがって、常にブロックから別の常にブロックへのブロック割り当てで「reg」セットを読み取ると、予測できない動作が発生します。
ピーターグリーン

そして、シミュレーションで動作しているように見えても、合成ツールはそれを見て「ノープ」と言う必要があります。これらの中間変数にローカルregを使用し、それらが読み込まれる前に常にすべてのクロックで割り当てられるようにして、「ストレージ」が暗示されないようにします。
グレゴ

IIRCは、少なくともクォーターでは、エラーではなく警告のみと見なされます。
ピーターグリーン

5

用語の割り当てをブロックするには、単語ので、人々を混乱させるブロックは、時系列のロジックを示唆するように思われます。しかし、合成ロジックではすべてが並列に動作するため、これは意味しません

おそらく、より混乱を招くことのない用語は即時割り当てであり、これにより、組み合わせロジックの中間結果が、遅延された割り当てを持つ可能性のある不透明なメモリ要素(クロック付きレジスタなど)への入力から区別されますます。

法的観点から見ると、すべてうまく機能しています。実際、シーケンス内であっても=ブロッキング(時系列)操作であると考えることができalways_combます。ただし、この場合、時系列と並列の区別はまったく違いはありません。always_comb、命令シーケンスが安定状態に収束するまでブロックが繰り返されるように定義されているこれは、ハードウェア回路が行うことです(タイミングを満たす場合)要件)。

Verilog(特にSystemVerilog)の合成可能なサブセットは、必要なイディオムがわかれば非常にシンプルで使いやすいです。言語のいわゆる行動要素に関連する用語の巧妙な使用をすり抜ける必要があります。


行動(コーディングスタイルRTLと比較して)、ブロッキングと非ブロッキングの区別が関連することができます。場合によっては、合成ツールが動作コンポーネント設計から機能的に同等のRTLを推測できる場合があります。
-nobar

もちろん、特にブロック内のステートメントに適用可能なSystemVerilog の手続き型モードは、(時系列)ブロック割り当てを排他的に使用します。これはテストベンチの設計には役立ちますが、通常はRTL仕様には役立ちません。initialprogram
nobar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.