verilog~generate文とfor文による連続モジュールの生成
皆さんお久ぶりです。keymaleです。久しぶりの投稿です。他の記事でdividerの生成方法や、moduleからのパラメータの受け渡し、if文の使い方などを書いてきました。今回はmoduleを複数一気に生成し、かつそのmoduleに受け渡すパラメータや変数、逆に受け取る変数や信号を別々に扱う方法を紹介したいと思います。最新記事で浮動小数の扱い方も紹介してます。
今回使う関数はgenerate 文と for 文です。for 文はC言語などでの使い方とそんなに変わりません。generate 文とfor 文を使って、以前作成したdividerのmoduleを一気に6個生成します。かつその6個のdividerは1,2,3,4,5,6分周をそれぞれ担うような形を作っていきたいと思います。
それでは早速コードを見ていきましょう。
parameter num = 6;
wire [num-1:0]div_out;
generate
genvar k;
for (k = 0; k < num; k = k + 1)
begin:generate_divider
divider #(
.div_number (k+1)
)divider1(
.div_in (clk),
.div_out (div_out[k])
);
end
endgenerate
順番に見ていきましょう。まず、
parameter num = 6;
これはいくつmoduleを生成するかをparameterで宣言しています。
wire [num-1:0]div_out;
これはdividerの出力を6bitのワイヤで表現しています。
generate
この文より下に生成するmoduleの記述をしていきます。
genvar k;
これはgenerate文内で使う変数をgenvarで宣言し、kという変数として定義しています。
for (k = 0; k < num; k = k + 1)
ここからがfor文です。かっこの中は(変数の初期値;変数の終わりの条件;変数の変化の条件)のように記述していきます。今回はk=0から1づつ増えて、numつまり6未満までとしていますので、0,1,2,3,4,5のkという表現となります。
begin:generate_divider
begin:の後にgenerate文の宣言名を記載してくだい。今回ははgenerate_dividerとしていますが、本当に何でもいいです。
divider #(
.div_number (k+1)
)divider1(
.div_in (clk),
.div_out (div_out[k])
);
ここの記述は普通にmoduleを呼び出す記述をしてください。これで、for文の数だけmoduleが生成されます。ただし今回はdividerの分周数を1づつ変えたいため、divi_numberのパラメータにk+1、div_outの出力をmoduleごとに変えるため、div_out[k]としています。
end
endgenerate
for文のendとgenerate文のend表現を行います。for文はendですが、generate文はendgenerateで」ある点に注意してください。
こうして作成したverilogファイルをmodelsimで確認してみましょう。
div_outの[0]~[5]がそれぞれ1,2,3,4,5分周に対応しており、clkを分周していることがわかるかと思います。
以上で無事generate文を使いこなすことができました。
最後まで見てくださってありがとうございます。
ご意見ご感想お待ちしております。
-
前の記事
verilog~module内パラメーターの階層間受け渡し 2018.11.25
-
次の記事
verilog PWM moduleの作成、IP化 Quartus 2019.05.13
コメントを書く