【发布时间】:2015-05-17 15:46:18
【问题描述】:
我正在使用 Verilog 编写一个项目,并希望使用 parameter 在我的模块中定义一些参数。但是当我阅读一些源代码时,有时会使用localparam而不是parameter。
它们有什么区别?
【问题讨论】:
标签: verilog
我正在使用 Verilog 编写一个项目,并希望使用 parameter 在我的模块中定义一些参数。但是当我阅读一些源代码时,有时会使用localparam而不是parameter。
它们有什么区别?
【问题讨论】:
标签: verilog
通常,localparam(添加到 Verilog-2001 标准)背后的想法是保护 localparam 的值不被最终用户意外或错误地重新定义(与 parameter 值不同,此值可以' 不能被参数重定义或defparam 语句修改)。
基于 IEEE 1364-2005(第 4.10.2 章):
Verilog HDL 本地参数与参数相同,只是它们不能通过 defparam 语句或模块实例参数值分配直接修改。局部参数可以赋值为包含参数的常量表达式,可以通过defparam语句或模块实例参数值赋值进行修改。
此外,在 SystemVerilog (IEEE 1800-2012 (ch. 6.20.4)) 中:
与非本地参数不同,本地参数可以在生成块、包、类主体或编译单元范围内声明。在这些情况下,参数关键字应是 localparam 关键字的同义词。
本地参数可以在模块的 parameter_port_list 中声明。任何出现在 localparam 关键字和下一个参数关键字(或列表末尾,如果没有下一个参数关键字)之间的列表中的参数声明都应该是本地参数。此类列表中的任何其他参数声明都应是可以被覆盖的非本地参数。
如果您想了解有关此主题的更多信息,我建议您阅读 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 给出了预期的错误。
【讨论】: