verilog~module内パラメーターの階層間受け渡し
こんにちは、お久しぶりです。Keymaleです。
今回は verilogのパラメータについて説明します。
以前の記事で説明したDividerを例にして進めようと思います。以下に以前紹介したdividerのプログラムを紹介します。
module divider(
input div_in,
output div_out
);
reg [7:0]div_number;
reg [7:0]cnt_p;
reg [7:0]cnt_n;
reg out_p;
reg out_n;
assign div_out = out_p ^ out_n;
initial begin
div_number = 8'd3;
cnt_p = 8'd1;
cnt_n = 8'd1;
out_p = 0;
out_n = 0;
end
always@(posedge div_in)begin
cnt_p <= cnt_n + 8'd1;
if(cnt_n == div_number)begin
cnt_p <= 8'd1;
out_p <= ~out_p;
end
end
always@(negedge div_in)begin
cnt_n <= cnt_p + 8'd1;
if(cnt_p == div_number)begin
cnt_n <= 8'd1;
out_n <= ~out_n;
end
end
endmodule
この中でdiv_numberをregで記述していますが、いろんな値に変えたいと思うとします。その時に、regのままでもいいのですが、わかりやすくするために
parameter div_number
と記述することができます。parameterは32bitのintで扱われます。
このままだったら別にparameterの良さがわからないと思います。
parameterの真価を発揮するのはmodule化した時です。module化した際に様々なdiv_numberのdividerを作りたくなった時には、上位階層から下位階層であるdividerのparameterをいじることができるのですが、少し工夫が必要です。
まず以下のようにparameterを記述する位置を変更しましょう。
module divider #(
paramter div_number = 5,
paramter div_test = 1
)
(
input div_in,
output div_out
);
reg [7:0]cnt_p;
reg [7:0]cnt_n;
reg out_p;
reg out_n;
assign div_out = out_p ^ out_n;
initial begin
cnt_p = 8'd1;
cnt_n = 8'd1;
out_p = 0;
out_n = 0;
end
always@(posedge div_in)begin
cnt_p <= cnt_n + 8'd1;
if(cnt_n == div_number)begin
cnt_p <= 8'd1;
out_p <= ~out_p;
end
end
always@(negedge div_in)begin
cnt_n <= cnt_p + 8'd1;
if(cnt_p == div_number)begin
cnt_n <= 8'd1;
out_n <= ~out_n;
end
end
endmodule
変化した場所はわかりましたか?moduleと宣言した後に変化場所があります。
今までは
module module名(
input input名,
output output名
);
として、このmodule宣言後のかっこで囲われた中でinput outputを宣言し、上位階層のmoduleとの信号の受け渡し部分になっていましたが、ここにさらにparameterの受け渡し部分を
module module名 #(
parameter paramter名
)(
input input名,
output output名
);
inputやoutput宣言の前にmodule名の後に#をつけてかっこ内にparameterを宣言することで、上位モジュールからここで宣言したparameterを操作することができます。また、上位モジュールで下位モジュールのparamterをいじらないときは、下位モジュールで宣言したparameter値が読み込まれるので、どっちにしろparameterの宣言はこの場所にしておいてよさそうです。何より、parameterをいろんなところで宣言するとわかりにくいので、module宣言の後に宣言すると決めておくといいでしょう。他にもdefparamで行う方法もあるようですが、私はこの方法を推奨します。
上位moduleからこのmoduleを呼び出すときは以下のように記述します。
divider #(
.div_number (8),
.div_test (0)
)divider1(
.div_in (clk),
.div_out ()
);
上記のようになります。一般的に書くと以下のようになります。
モジュール名 #(
.モジュール内でのパラメータ名 (パラメータ値)
)呼び出し階層でのモジュール名(
.モジュール内での信号名 (信号値)
);
パラメータ値には直接数字を入れてもいいですし、変数でも問題ないです。
以上でパラメータの階層間での受け渡しの説明を終わりにします。
最後まで見ていただいてありがとうございますした。
次回はfor文とgenerate文について説明したいと思います。
-
前の記事
verilog~divider(分周器)~奇数分周もできるよ 2018.11.15
-
次の記事
verilog~generate文とfor文による連続モジュールの生成 2018.12.16
コメントお待ちしております。