Menu
Coddy logo textTech

パラメータ

CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 11/90。

同じモジュールのコピーを多数作成し、それらを異なる場所で使用することができます。これは**マルチインスタンス**と呼ばれます。同じコードを何度も繰り返し書く代わりに、一度だけ書いて、必要な回数だけ再利用します。各インスタンスは、チップ上のそのハードウェアの個別のコピーです。

しかし、それぞれのコピーを異なるものにする必要がある場合はどうすればよいでしょうか?例えば、1つの8ビットカウンタ、1つの16ビットカウンタ、そして1つの32ビットカウンタといった具合です。パラメータがない場合、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), .reset(reset), .count(count1));

// 16ビットにオーバーライド
counter #(.WIDTH(16)) u2 (.clk(clk), .reset(reset), .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

localparam は似ていますが、外部から上書きすることはできません:

module example;
  localparam STATE_IDLE = 2'b00;
  localparam STATE_RUN = 2'b01;
  localparam STATE_STOP = 2'b10;
  // これらの値はこのモジュール内で固定されています
endmodule

変更すべきでない定数には localparam を使用します。

challenge icon

チャレンジ

デフォルト値が 4WIDTH という名前のパラメータを追加してください。

手順:

  1. WIDTH という名前のパラメータを追加する
  2. そのデフォルト値を 4 に設定する
  3. パラメータはモジュール名の後の #( ) 内に記述する

チートシート

パラメータを使用すると、コードを書き換えることなく、モジュールインスタンスを異なる設定に構成できます。

パラメータの宣言

module counter #(
  parameter WIDTH = 8  // default value
)(
  input clk,
  output reg [WIDTH-1:0] count
);
  always @(posedge clk) count <= count + 1;
endmodule

インスタンス化におけるパラメータの上書き

counter u1 (.clk(clk), .count(count1));          // uses default (8)
counter #(.WIDTH(16)) u2 (.clk(clk), .count(count2)); // overridden to 16

複数のパラメータ

module fifo #(
  parameter DEPTH = 16,
  parameter WIDTH = 8
)( ... );

Localparam (上書き不可能な定数)

localparam STATE_IDLE = 2'b00;
localparam STATE_RUN  = 2'b01;

モジュールの外部から変更してはならない内部定数には、localparamを使用します。

自分で試してみよう

module counter #(
  // ここにデフォルト値4のパラメータWIDTHを追加してください
  
)(
  input clk,
  input reset,
  output reg [WIDTH-1:0] count
);

endmodule
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

基礎のすべてのレッスン