"参数"和"localparam"之间的区别

Vu *_*ang 20 verilog

我正在用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会出现预期的错误.