パラメータ
CoddyのVerilogジャーニー「基礎」セクションの一部。レッスン 11/90。
同じモジュールのコピーをたくさん作成し、さまざまな場所で使うことができます。これは**複数のインスタンス**と呼ばれます。同じコードを何度も書く代わりに、一度だけ書いて、必要なだけ再利用します。それぞれのインスタンスは、チップ上にあるそのハードウェアの個別のコピーです。
しかし、それぞれのコピーを異なるものにする必要がある場合はどうでしょうか?たとえば、8ビットカウンター、16ビットカウンター、32ビットカウンターをそれぞれ1つずつ作る場合です。パラメーターがなければ、モジュールを3つ別々に書く必要があります。
パラメーターを使えば、この問題を解決できます。
パラメーターは、インスタンスを作成するときに設定できる定数値です。モジュールのコピーごとに異なる設定を行えます。
パラメータの宣言
module counter #(
parameter WIDTH = 8
)(
input clk,
output reg [WIDTH-1:0] count
);
always @(posedge clk) count <= count + 1;
endmodule#(parameter WIDTH = 8)は、デフォルト値が8のWIDTHというパラメーターを定義します。
パラメーターを宣言するときは、モジュール名の直後、ポートリストの前に#記号を使います。#は、後に続くものがモジュールを設定するパラメーターのリストであることをVerilogに伝えます。モジュールにパラメーターがない場合は、#を省略するだけです。
パラメーターの使用
定数が必要な場所ならどこでも、パラメーターを使用できます。
reg [WIDTH-1:0] data; // ベクトルのサイズ
count <= count + 1; // 任意のビット幅で動作
assign out = data[WIDTH-1]; // MSBの位置パラメーターの上書き
モジュールを使用するときは、パラメーターの値を変更できます。
// デフォルトの幅 (8 ビット)
counter u1 (.clk(clk), .count(count1));
// 16 ビットに上書き
counter #(.WIDTH(16)) u2 (.clk(clk), .count(count2));複数のパラメータ
複数のパラメータを指定できます:
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];
endmoduleローカルパラメータ
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というパラメーターを追加します。
やること:
WIDTHという名前のパラメーターを追加します- デフォルト値を
4に設定します - パラメーターはモジュール名の後の
#( )内に置きます
自分で試してみよう
module counter #(
// ここにデフォルト値が4のパラメータ WIDTH を追加する
)(
input clk,
input reset,
output reg [WIDTH-1:0] count
);
endmoduleこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
基礎のすべてのレッスン
自分で練習してみよう: Verilogオンラインコンパイラ