ターゲットボードとしてVerilog言語とZedboardを使用しています。
私の知る限り、forループを合成できます。合成ツールは、forループを、ループの展開などの重複した命令のシーケンスとして変換します。
たとえば、
for ( i = 0; i < 4; i=i+1) begin mem[i] = i; end will be translated to mem[0] = 0; mem[1] = 1; mem[2] = 2; mem[3] = 3;
したがって、私が知る限り、リソースが複数の同じ目的のゲートを推測できる場合は、forループを使用できます。
ただし、Verilogでの生成は複数のインスタンスを意味するだけでなく、forループと同じ複数の命令を意味するために使用できます。
生成はモジュールの複数のインスタンスのみを意味し、forループは使用できないことを理解していますその目的のために。
では、生成+ forループと単にforループの違いは何ですか?どちらもループ展開のように機能すると思います。目立った違いはありますか?違いがない場合、ループ展開を誘発するのに好ましいコーディングスタイルはどれですか?
コメント
- わかりやすくするために、' s:ほのめかします、あなたは推測します。例えばVerilog / VHDLでRAMを暗示すると、合成ソフトウェアはそのRAMをVerilog / VHDLから推測します。非常によくある間違いで、学ぶ価値があります。
回答
Verilogのforループは、特定の条件下で完全に合成できます。
- ループ内で任意の手続き型ステートメントを使用できます(例:if-else)。
- ループの数は事前に決定されている必要があります。
- 制限式は、ループ変数と定数またはパラメーターのいずれかとの比較である必要があります。
- ステップ割り当てでは、ループ値を一定量ずつインクリメントする必要があります。
- 各ループの同じ変数に異なる値を割り当てることができます(たとえば、ループ変数からインデックスを計算します)。
- 合成の目的で、ループが評価されます。ゼロ時間で–つまり、カウンターを作成しようとすると、最終的な値しか表示されません。
手続き型ブロックでforループを使用する場合でも、使用する場合でも、同じルールが適用されます。生成ブロックで。
手続き型ブロックinitial
およびalways
で実行する場合は、forを使用できます。ループして配列内の要素を変更します(例とまったく同じです)。または、同じ値を複数回変更することもできます。例:
for (idx = 0; idx < 4; idx=idx+1) begin a = a + b[idx]; c = c + 2; //You can change more than one variable in a for loop end
この例では、結果として得られるハードウェアは、4つの配列インデックスからの値を合計する加算器のチェーンになります。
重要なことは、手続き型forループで新しい変数やモジュールを作成できないことです。このルールは、forループだけでなく、一般に手続き型ブロックに適用されます(つまり、手続き型ブロックで変数を宣言することはできません)。
一方、Generateブロックでは、変数の作成とモジュールのインスタンス化が可能です。つまり、generateブロックでは、generateforループを使用してモジュールを推測できます。これが唯一の違いです。
forループを生成するには、genvar
をループ変数(つまり、各ループをカウントするために使用する値)として使用する必要があります。 forループにも名前を付ける必要があります。
for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName
この名前は、ループでインスタンス化するハードウェアの前に付けられます。したがって、bob
というインスタンスを作成すると、上記のループでインスタンスが作成されます。
loopName[0]|bob loopName[1]|bob loopName[2]|bob loopName[3]|bob
これにより、複数のインスタンスが作成されます。一意の名前を持つインスタンス。
forループの生成と手続き型の両方で、おっしゃるようにループの展開が実行されます。違いは、単にそれらをどのように使用できるかです。手続き型は、手続き型ブロックで使用できます(メモリの初期化など)。 Generateは、generateブロックでのみ使用できます。
これらは便利であり、推奨されます。一方が他方を置き換えることはできません。
コメント
- 生成を考える別の方法は、一種のプリプロセッサ、つまりVerilogコンパイラです' 'を含むブロックをインスタンス化するポイントで、生成ブロック内の処理を実行します'生成-'実行時に発生しません(手続き型ループとは異なります)
- @Taniwha手続き型ループはありません'実行時にも実行されます。これらはコンパイラによって展開されます。最終的にはすべてハードウェアになります。また、'プリプロセッサと生成ステートメントを混同しないでください。そうではありません。同じ概念-Verilogには、if-elseタイプのステートメントを含むプリプロセッサがあります。
- @TomCarpenterすばらしい回答に感謝します。生成forループを除くすべてのポイントを理解できました。 begin:something をforループの直前に追加する必要があるようですが、モジュールのインスタンス化でどのように機能するかを理解できません。 loopNameは変数ですか、それとも単なる文字列ですか? また、[1]から[4]でインデックスを作成する方法。
- @JaeHyukLee
loopName
は、インスタンス名やシグナル名などの単なるテキストです。 - @ TomCarpenter-コンパイラによって異なります-'ゲートをコンパイルしている場合は、はい、展開されます。'シミュレーション用のコードをコンパイルしていない可能性が高いです(免責事項、私は' Verilogコンパイラを作成しました)