我正在用Verilog编写一个项目,并希望用来parameter
在我的模块中定义一些参数.但是,当我阅读一些源代码时,localparam
有时会使用而不是parameter
.
他们之间有什么区别?
Qiu*_*Qiu 30
通常,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))中:
与非局部参数不同,可以在生成块,包,类主体或编译单元范围中声明局部参数.在这些上下文中,parameter关键字应该是localparam关键字的同义词.
可以在模块的parameter_port_list中声明本地参数.在localparam关键字和下一个参数关键字(或列表的末尾,如果没有下一个参数关键字)之间的此类列表中出现的任何参数声明都应是本地参数.此类列表中的任何其他参数声明都应是可以覆盖的非本地参数.
如果你想了解更多关于这个主题的信息,我建议你使用Clifford E. Cummings论文" New Verilog-2001创建参数化模型的技巧(或者用于定义和死亡的defparam! ").
小智 5
最小的例子
这是邱提到的一个例子.
在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.
...
Run Code Online (Sandbox Code Playgroud)
在父模块上,这很好:
module myram_tb;
myram #(
.ADDR_SIZE(2),
.WORD_SIZE(2)
) top (
/* wires */
)
Run Code Online (Sandbox Code Playgroud)
但这应该是一个错误:
module myram_tb;
myram #(
.ADDR_SIZE(2),
.WORD_SIZE(2),
.MEM_SIZE(2)
) top (
/* wires */
)
Run Code Online (Sandbox Code Playgroud)
iverilog
不会失败,我相信这是一个错误:https://github.com/steveicarus/iverilog/issues/157
Incisive会出现预期的错误.