Verilogでの組み合わせ回路の説明
2019年1月6日、SteveArar博士
この記事では、条件演算子を使用して組み合わせ真理値表を記述する方法を調べることにより、Verilogで組み合わせ回路を記述するための手法を紹介します。また、Verilogの「always」ブロックを使用して組み合わせ回路を記述する方法も示します。「always」ブロックは、デジタル回路を記述するためのさらに簡単なソリューションを提供します。
前回の記事では、Verilogの「assign」キーワードを使用して継続的な割り当てを実行する方法について説明しました。このような割り当ては常にアクティブであり、デジタル回路のゲートレベルの記述を取得するために使用できます。たとえば、ANDゲートを説明する次のコードでは、右側が継続的に評価され、結果がout1ネットに出力されます。
Verilogには条件演算子(?:)があり、このような割り当てを行う前に条件を確認できます。構文は次のとおりです。
「conditional_expression」が評価されます。 trueの場合、「value_if_true」が「signal_name」に割り当てられます。 trueでない場合、「signal_name」は「value_if_false」を取得します。例として、次のコードについて考えてみます。
「sel」がtrueの場合、a&bは「out1」に割り当てられます。そうでない場合、「out1」はa | bを取得します。したがって、上記のコードは2対1マルチプレクサの機能を実装しています。このコードの概念的な実装は、以下の図1に示すようになります。
条件付き代入を使用すると、従来のコンピュータープログラミング言語に見られる「if」ステートメントの機能を備えているため、特定の回路をより抽象的な説明にすることができます。条件演算子は、ネストされた形式で使用して、より複雑な回路を実装できます。例1では、これらの詳細について説明しています。
条件演算子(?:)を使用して、次の真理値表で4対2のプライオリティエンコーダを記述します。
このプライオリティエンコーダのVerilogコードを以下に示します。
7行目から10行目は別として、コードには前の記事で説明した基本的な言語要素が含まれています。それでは、これらの行を見てみましょう。
2’b11、2’b10、2’b01という用語は、2ビットの2進数を表すVerilog表記を指します。一般に、最初の数字( ‘bの前)はビット数を指定します。文字bは、数値が2進数であることを示します。 ‘bの後の数字は、数値の値を示します。したがって、2’b01は値01の2ビット2進数を表すVerilog表記であり、3’b100は値100の3ビット2進数を表します。
7行目は、条件演算子で入力x [3]のMSBをチェックします。 x [3] =1の場合、条件はtrueと評価され、2’b11がyに割り当てられます(割り当てられた値は真理値表から取得されます)。 x [3] =0の場合、条件はfalseと評価され、コロン(:)の後の式がyに割り当てられます。コロンの後の式は、それ自体が別の条件演算子である8行目のコードです。
8行目の2番目の条件演算子は、入力の2番目に重要なビットx [2]を調べて、2'b10をyに割り当てるか、コロンの後の式を割り当てるかを決定します。これも別の条件演算子(9行目)である必要があります。評価されます。 yに割り当てられた値が指定された真理値表と一致することを確認できます。
入力の少なくとも1ビットがロジックハイの場合、真理値表の有効な出力(v)はロジックハイになります。 11行目は、入力のビットにビットごとのOR演算子(|)を適用することにより、この説明を示しています。上記のコードのザイリンクスISEシミュレーションを図2に示します。
条件式は、真の式が見つかるまで連続して評価されることに注意してください。この真の式に対応する割り当てが実行されます。その結果、先に評価された式は、次の式に比べて優先度が高くなります。これは、理論的には、マルチプレクサ(図4)などのバランスの取れた構造よりも、条件付き演算子の方が優先ネットワーク(図3)の実装に適していることを意味します。
前回の記事では、VHDLの同時割り当てに関する同様の議論が明らかになっています。
任意の組み合わせ回路をいくつかの基本的な論理ゲート(AND、OR、NOTなど)に分解し、「assign」ステートメントを使用してこれらのゲートを記述できます(ゲートレベルの記述)。前のセクションで説明した条件演算子を使用して、いくつかの組み合わせ回路をより抽象的な方法で記述することもできます(コンピュータープログラミング言語の「if」ステートメントと同様)。ただし、さらに強力なソリューションがあります。Verilogの「always」ブロックを使用することです。
「always」ブロック内に、順番に実行される手続き型ステートメントを含めることができます。さらに、「always」ブロックは、「if」や「case」ステートメントなどの抽象言語構造をサポートします。
人間の推論にはシーケンシャルな性質があり、抽象的な記述に依存しているため、「always」ブロック内で使用可能な抽象言語構造とともに順次実行機能を使用すると、回路の機能をより簡単に記述することができます。私たちは通常、低レベルの論理ゲートではなく、アルゴリズムの高レベルの方法で考えます。 「always」ブロックは、デジタル回路を記述するためのより簡単なソリューションを提供します。 HDLがシーケンシャルステートメントに基づく記述をサポートする理由の詳細については、私の記事「シーケンシャルVHDLステートメントの概要」を参照してください。
「always」ブロックの簡略化された構文を以下に示します。
sensitive_listは、「always」ブロック内のシーケンシャルステートメントをいつ実行するかを指定します。たとえば、「always」ブロックを使用して図5の回路を説明することを検討してください。
aまたはbのいずれかが変更されると、出力が変更される可能性があります。つまり、aとbの両方が「always」ブロックの感度リストに含まれている必要があります。一般に、組み合わせ回路の場合、すべての入力信号を感度リストに含める必要があります。
これで、ビットごとのAND演算子を使用して、回路(a&b)の機能を記述し、結果を出力に割り当てることができます。 「always」ブロック内には、ブロッキング割り当て(=)と非ブロッキング割り当て(<=)の2種類の割り当てがあります。ブロッキング割り当てを使用して、次のコードを取得します。
ブロッキング割り当てと非ブロッキング割り当ての違いは何ですか?
ブロッキング割り当てを使用すると、右側が評価され、すぐにout1に割り当てられます。したがって、3行目が実行されると、コードの次の行に進む前にout1がすぐに更新されます。 「ブロック割り当て」という名前は、左側が更新されるまで次の行がブロックされることを強調しています。
非ブロッキング割り当てでは、右側の式が評価されますが、「always」ブロックの最後に到達するまで、左側の変数には適用されません。ブロッキングまたは非ブロッキングの割り当ての選択は、初心者にとって混乱を招く可能性があり、それらの不適切な使用は、望ましくない機能につながる可能性があります。たとえば、ブロッキング割り当てを使用してフリップフロップを推測すると、競合状態が発生する可能性があります。
この入門記事では、これ以上詳しく説明せず、潜在的な落とし穴を回避するために1つの簡単なガイドラインのみに固執します。組み合わせ回路のコードを作成するときは、ブロッキング割り当てを使用します。したがって、リスト1の「always」ブロックはANDゲートを説明するために使用されます。
前回の記事では、Verilogの「ワイヤ」データ型について理解しました。このデータ型は、FPGAデザインの物理ワイヤを表します。 「always」ブロック内では、Verilog標準では「ワイヤ」に値を割り当てることはできません。代わりに、「reg」データ型を使用します。 「reg」という名前はやや紛らわしいですが、「reg」がデザインの物理ストレージ要素につながる場合とそうでない場合があることに注意してください。次のコードは、「always」ブロックを使用した図5のVerilog記述です。出力データ型は、手続き型の割り当てから値を取得するため、「reg」である必要があることに注意してください。
この記事では、Verilog条件演算子について理解しました。この演算子のネストされた形式を使用して、プライオリティエンコーダーを記述しました。次に、組み合わせ回路を説明するために、より強力な言語構造である「always」ブロックに触れました。今後の記事では、「always」ブロックを使用して順序回路を実装する方法について説明します。この記事では、条件演算子を使用して組み合わせ真理値表を記述する方法を調べることにより、Verilogで組み合わせ回路を記述するための手法を紹介します。
assign out1 =a&b;
assign [signal_name] =[conditional_expression]? [value_if_true]:[value_if_false];
assign out1 =(sel)? (a&b):( a | b);
例1:ネストされた条件演算子
モジュールPrio_4_to_2(入力ワイヤ[3:0] x、出力ワイヤ[1:0] y、出力ワイヤv); y =x [3]を割り当てますか? 2'b11:x [2]? 2'b10:x [1]? 2'b01:2'b00; v =(x [3] | x [2] | x [1] | x [0])を割り当てますか? 1'b1:1'b0;エンドモジュール
図2。 上記のコードからのザイリンクスISEシミュレーション。
図3。 優先ネットワーク。
図4。 入力間に優先順位がないn対1マルチプレクサ。
Verilogの手順書
例2:「常に」ブロックステートメント
常に@(sensitive_list)はsequential_statementsを開始します。終了
図5。 Circuit_1
常に@(a、b)begin out1 =a&b; end
module Circuit_1(入力ワイヤa、入力ワイヤb、出力reg out1);常に@(a、b)begin out1 =a&b;エンドモジュールの終了
埋め込み