Forループとともにverilogでgenerateを使用する理由を理解しようとしています。
Generateとforループを一緒に使用する:
reg [3:0] temp;
genvar i;
generate
for (i = 0; i < 3 ; i = i + 1) begin:
always @(posedge sysclk) begin
temp[i] <= 1'b0;
end
end
endgenerate
Forループのみを使用する:
reg [3:0] temp;
genvar i;
always @(posedge sysclk) begin
for (i = 0; i < 3 ; i = i + 1) begin:
temp[i] <= 1'b0;
end
end
私は2つのスニペットが基本的に同じ結果、つまり値0に等しいtemp [0]からtemp [10]を生成することを考えています。この場合、generateステートメントを使用することで見られる違い/利点は何ですか?
一般に、forループの生成とforループの通常の主な違いは、forループの生成が反復ごとにインスタンスを生成することです。つまり、yourの例では、常に3つのブロックがあります(通常のループの場合の1つのブロックとは対照的に)。
requires generateのコードの良い例は次のとおりです。
module A();
..
endmodule;
module B();
parameter NUM_OF_A_MODULES = 2; // should be overriden from higher hierarchy
genvar i;
for (i=0 i<NUM_OF_A_MODULES; i=i+1) {
A A_inst();
}
endmodule;
この例では、通常のforはNUM_OF_A_MODULESインスタンスを作成する作業を実行できません。
yourの例では、両方の方法で必要な結果を得ることができます。 (いくつかの小さなバグを修正する限り:))
generate
なしの例では、i
はgenvar
ではなくinteger
でなければなりません。それ以外の場合は、ツールセットでサポートされているIEEE Std 1364のバージョンに応じて両方が有効です。 generateコンストラクトはIEEE規格1364-2001で追加され、generate
/endgenerate
キーワードが明示的に必要です。 IEEE Std 1364-2005では、generate
を使用する場合は、一致するendgenerate
を持たなければならないという唯一の要件でオプションになりました。
IEEE Std 1364-2005またはSystemVerilog(IEEE Std 1800)を使用する場合、暗黙的宣言と明示的宣言のどちらのコーディングスタイルを優先するかは問題です。 Explicitには、下位比較可能という利点があります。
生成ブロックは、パラメーターを介してthenモジュールの物理構造を変更するときに役立ちます。たとえば、ネガエッジまたはポーズクロックを選択し、1つのみを有効にする場合:
if ( param_use_pos == 1) begin : use_pos
always @(posedge sysclk) begin
...
end
end
else begin : use_neg
always @(negedge sysclk) begin
...
end
end
物理構造を変更しない場合、通常は、常にブロック内でforループおよびif-elseステートメントを使用することをお勧めします。両方のアプローチで同じものを合成できますが、RTLシミュレーションを実行する場合、非生成ブロックアプローチは通常、より高速にシミュレーションします。これは、シミュレータが通常1つのNビット操作をN 1ビット操作よりも速く処理できるためです。合成も同じ結果です
// faster :: 1 always block, simulator can optimize the for loop
always @(posedge sysclk) begin
for (i = 0; i < 3 ; i = i + 1) begin
temp[i] <= 1'b0;
end
end
// slower :: creates 4 always blocks, harder for the simulator to optimize
genvar i;
generate // optional if > *-2001
for (i = 0; i < 3 ; i = i + 1) begin
always @(posedge sysclk) begin
temp[i] <= 1'b0;
end
end
endgenerate // match generate