Verilogを使用してプロジェクトを作成しており、parameter
を使用してモジュールのパラメーターを定義します。しかし、ソースコードを読み込むと、localparam
の代わりにparameter
が使用されることがあります。
それらの違いは何ですか?
一般に、localparam
(Verilog-2001標準に追加)の背後にある考え方は、localparam
の値を、エンドユーザーによる偶発的または誤った再定義から保護することです(parameter
値とは異なり、この値は、パラメーターの再定義またはdefparam
ステートメントでは変更できません。
IEEE 1364-2005(ch。4.10.2)に基づく:
Verilog HDLローカルパラメーターは、defparamステートメントまたはモジュールインスタンスパラメーター値の割り当てによって直接変更できないことを除いて、パラメーターと同じです。ローカルパラメーターには、パラメーターを含む定数式を割り当てることができます。これは、defparamステートメントまたはモジュールインスタンスパラメーター値の割り当てで変更できます。
さらに、SystemVerilogで( IEEE 1800-2012 (ch。6.20.4)):
非ローカルパラメーターとは異なり、ローカルパラメーターは、生成ブロック、パッケージ、クラス本体、またはコンパイル単位スコープで宣言できます。これらのコンテキストでは、パラメータキーワードはlocalparamキーワードの同義語でなければなりません。
ローカルパラメータは、モジュールのparameter_port_listで宣言できます。 localparamキーワードと次のパラメーターキーワード(または次のパラメーターキーワードがない場合はリストの最後)の間のそのようなリストに現れるパラメーター宣言は、ローカルパラメーターでなければなりません。そのようなリスト内のその他のパラメーター宣言は、オーバーライドされる可能性がある非ローカルパラメーターでなければなりません。
このトピックの詳細については、Clifford E. Cummingsの論文をお勧めします。「 パラメーター化されたモデルを作成するための新しいVerilog-2001テクニック(またはdefparamの定義と終了でダウン!) 「。
最小限の例
Qiuが言及した例を次に示します。
RAMでは、メモリサイズはワードサイズとアドレスサイズの関数です。
そのため、親モジュールがWordとアドレスサイズを指定している場合、メモリサイズも指定できないはずです。
module myram #(
parameter Word_SIZE = 1,
parameter ADDR_SIZE = 1
) (
input wire [ADDR_SIZE-1:0] addr,
inout wire [Word_SIZE-1:0] data,
// ...
);
localparam MEM_SIZE = Word_SIZE * (1 << ADDR_SIZE);
// Use MEM_SIZE several times in block.
...
そして、親モジュールでは、これは問題ありません:
module myram_tb;
myram #(
.ADDR_SIZE(2),
.Word_SIZE(2)
) top (
/* wires */
)
しかし、これはエラーになるはずです:
module myram_tb;
myram #(
.ADDR_SIZE(2),
.Word_SIZE(2),
.MEM_SIZE(2)
) top (
/* wires */
)
iverilog
は失敗せず、これはバグだと思います: https://github.com/steveicarus/iverilog/issues/157
Incisiveは予想通りエラーを出します。