"parameter" 和 "localparam" 之间的区别
Difference between "parameter" and "localparam"
我正在用 Verilog 编写一个项目并想使用 parameter
在我的模块中定义一些参数。但是当我阅读一些源代码时,有时会使用 localparam
而不是 parameter
。
它们有什么区别?
通常,localparam
(添加到 Verilog-2001 标准中)背后的想法是保护 localparam
的值免受最终用户意外或不正确的重新定义(不同于 parameter
值,此值不能通过参数重定义或通过 defparam
语句修改)。
基于 IEEE 1364-2005(第 4.10.2 章):
Verilog HDL local parameters are identical to parameters except that they cannot directly be modified by defparam statements or module instance parameter value assignments. Local parameters can be assigned constant expressions containing parameters, which can be modified with defparam statements or module instance parameter value assignments.
此外,在 SystemVerilog 中(IEEE 1800-2012(第 6.20.4 章)):
Unlike nonlocal parameters, local parameters can be declared in a generate block, package, class body, or compilation-unit scope. In these contexts, the parameter keyword shall be a synonym for the localparam keyword.
Local parameters may be declared in a module’s parameter_port_list. Any parameter declaration appearing in such a list between a localparam keyword and the next parameter keyword (or the end of the list, if there is no next parameter keyword) shall be a local parameter. Any other parameter declaration in such a list shall be a nonlocal parameter that may be overridden.
如果您想了解有关此主题的更多信息,我建议您阅读 Clifford E. Cummings 论文“New Verilog-2001 Techniques for Creating Parameterized Models (or Down With `define and Death of a defparam!)”。
最小示例
这是邱先生提到的一个例子。
在 RAM 中,内存大小是字和地址大小的函数。
所以如果父模块指定了字和地址大小,它应该也不能指定内存大小。
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 给出了预期的错误。
我正在用 Verilog 编写一个项目并想使用 parameter
在我的模块中定义一些参数。但是当我阅读一些源代码时,有时会使用 localparam
而不是 parameter
。
它们有什么区别?
通常,localparam
(添加到 Verilog-2001 标准中)背后的想法是保护 localparam
的值免受最终用户意外或不正确的重新定义(不同于 parameter
值,此值不能通过参数重定义或通过 defparam
语句修改)。
基于 IEEE 1364-2005(第 4.10.2 章):
Verilog HDL local parameters are identical to parameters except that they cannot directly be modified by defparam statements or module instance parameter value assignments. Local parameters can be assigned constant expressions containing parameters, which can be modified with defparam statements or module instance parameter value assignments.
此外,在 SystemVerilog 中(IEEE 1800-2012(第 6.20.4 章)):
Unlike nonlocal parameters, local parameters can be declared in a generate block, package, class body, or compilation-unit scope. In these contexts, the parameter keyword shall be a synonym for the localparam keyword.
Local parameters may be declared in a module’s parameter_port_list. Any parameter declaration appearing in such a list between a localparam keyword and the next parameter keyword (or the end of the list, if there is no next parameter keyword) shall be a local parameter. Any other parameter declaration in such a list shall be a nonlocal parameter that may be overridden.
如果您想了解有关此主题的更多信息,我建议您阅读 Clifford E. Cummings 论文“New Verilog-2001 Techniques for Creating Parameterized Models (or Down With `define and Death of a defparam!)”。
最小示例
这是邱先生提到的一个例子。
在 RAM 中,内存大小是字和地址大小的函数。
所以如果父模块指定了字和地址大小,它应该也不能指定内存大小。
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 给出了预期的错误。