パラメータ
CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 11/90。
同じ `module` のコピーを多数作成して、さまざまな場所で使用できます。これを**複数のインスタンス(multiple instances)**と呼びます。同じコードを何度も繰り返して書く代わりに、1度書いて必要な回数だけ再利用します。各インスタンスは、チップ上のそのハードウェアの個別のコピーとなります。
しかし、各コピーを異なるものにしたい場合はどうすればよいでしょうか?例えば、8ビットcounter、16ビットcounter、32ビットcounterがそれぞれ1つずつ必要な場合です。parameterを使用しない場合、3つの別々のmoduleを記述する必要があります。
パラメーター(parameter)によってこの問題が解決されます。
パラメータは、インスタンスを作成する際に設定できる定数值です。これにより、モジュールの各コピーを異なる設定にすることができます。
パラメータの宣言
module counter #(
parameter WIDTH = 8
)(
input clk,
output reg [WIDTH-1:0] count
);
always @(posedge clk) count <= count + 1;
endmodule#(parameter WIDTH = 8) は、WIDTH という名前のパラメータをデフォルト値 8 で定義します。
パラメータを宣言する際、モジュール名のすぐ後かつポートリストの前に # シンボルを使用します。この # は、これ以降にモジュールを構成するパラメータのリストが続くことを Verilog に伝えます。モジュールにパラメータがない場合は、# を完全に省略します。
parameterの使用
parameterは定数が必要な任意の場所で使用できます:
reg [WIDTH-1:0] data; // ベクトルサイズ
count <= count + 1; // 任意の幅で動作
assign out = data[WIDTH-1]; // MSBの位置パラメータのオーバーライド (Overriding Parameters)
モジュールを使用する際、パラメータの値を変更することができます:
// デフォルト幅(8ビット)
counter u1 (.clk(clk), .reset(reset), .count(count1));
// 16ビットにオーバーライド
counter #(.WIDTH(16)) u2 (.clk(clk), .count(count2));Multiple Parameters
複数のパラメータ(`parameter`)を持つことができます:
module fifo #(
parameter DEPTH = 16,
parameter WIDTH = 8
)(
input clk, wr_en, rd_en,
input [WIDTH-1:0] data_in,
output [WIDTH-1:0] data_out
);
reg [WIDTH-1:0] memory [0:DEPTH-1];
endmoduleLocalparam
localparam も同様ですが、外部からオーバーライド(再定義)することはできません:
module example;
localparam STATE_IDLE = 2'b00;
localparam STATE_RUN = 2'b01;
localparam STATE_STOP = 2'b10;
// These values are fixed inside this module
endmodule変更すべきではない定数には localparam を使用します。
チャレンジ
デフォルト値 4 を持つ WIDTH という名前の parameter を追加してください。
手順:
WIDTHという名前のparameterを追加する- そのデフォルト値を
4に設定する parameterはmodule名の後の#( )の中に記述する
自分で試してみよう
module counter #(
// ここにデフォルト4のパラメータWIDTHを追加
)(
input clk,
input reset,
output reg [WIDTH-1:0] count
);
endmoduleこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。