verilog~generate文とfor文による連続モジュールの生成
初めに
今回はmoduleを複数一気に生成し、かつそのmoduleに受け渡すパラメータや変数、逆に受け取る変数や信号を別々に扱う方法を紹介したいと思います。
generate文とfor文
今回使う関数は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文を使いこなすことができました。
最後まで見てくださってありがとうございます。
ご意見ご感想お待ちしております。
コメント
コメントを投稿