defineでなくparameterを使う

[] [] []


defineでなくparameterを使う」

RTL記述中の定数を可変にしておきたいときや、数値でなく名前で表記したいときがある。

1RTL記述を汎用にするため、ビット幅を可変にする

2)シミュレーション時間を短縮するために、長いカウンタ周期を短くする

3)ステートマシンの状態をしめす定数を、数値でなく名前で表記する

このようなときVerilogでは定数をマクロにする方法とparameterにする方法があるが、マクロは危険なので使わない方がよい

なぜなら、マクロは、

・ソースファイル内のどこでもdefineでき、defineした以降はずっと有効になる(その後に読み込んだソースファイルに対しても有効になる)。つまりコンパイルする順序に依存する。

・もし複数のソースファイルでたまたま同じ名前のマクロが存在していると、意図しないdefineが使われてしまう危険がある。

・なのでソースファイルの先頭でそのファイル内で使うマクロはすべてdefineすべきだが、抜けていてもコンパイルエラーにならないので気がつかない。

・マクロは単なる文字列置換なので、計算式を間違えやすい。

 例) define M N+1 , define K 2*M と書くとK=2*(N+1)でなくK=2*N+1と解釈される

// マクロの定義

`define MSB 15

`define PERIOD 4'd15

module my_module

   ...

×reg[`MSB:0] a_reg; // ビット幅

   ...

×if(counter_reg==`PERIOD) // カウンタ周期

   ...

endmodule

◇◇

一方、parameterは、

・モジュール内のみで有効なので安全である。もし宣言せずに使えばコンパイルエラーになって気づく。

・上位モジュールから下位モジュールごとに異なる値を設定することもできる。

・上位から設定されたくなければlocalparamにすればよい。

・テストベンチからFPGA内部に階層パスを指定して設定(defparam)することができる

parameterは単なる文字列置換ではなく、値として計算される。

 例) M=N+1, K=2*Mと書くとK=2*(N+1)と解釈される

// テストベンチから階層パスを指定して値を設定する

module tb;

defparam top.sub_0.PERIOD=4'd8;

top top(...);

...

endmodule

// 上位モジュールから下位モジュールに値を設定する

module top(...);

sub #(.MSB(15),.PERIOD(4'd10)) sub_0(...);

sub #(.MSB(15),.PERIOD(4'd15)) sub_1(...);

...

endmodule;

// 下位モジュール

module sub #(parameter MSB=7,PERIOD=4'd8) // デフォルト値

  ...

localparam NUM=100; // 外に見せないものはlocalparamにする

 ...

reg[MSB:0] a_reg;   // ビット幅

   ...

if(counter_reg==PERIOD) // カウンタ周期

   ...

endmodule

()parameter値を設定する#記号はディレイを表す#と同じだが意味は無関係


[] [] []