玩转parameter与localparameter,这篇文章就够了【Verilog高级教程】

芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字verifier星球
四社区联合力荐!近500篇数字IC精品文章收录
【数字IC精品文章收录】学习路线·基础知识·总线·脚本语言·芯片求职·EDA工具·低功耗设计Verilog·STA·设计·验证·FPGA·架构·AMBA·书籍

在这里插入图片描述

一、写在前面

本专栏为作者在 【数字IC手撕代码】 【数字IC笔试面经分享】 【数字IC工具解析】 以外开设的第四个独立专栏,旨在学习并提供有关Verilog硬件描述语言中非基础性的高阶语法特性知识,因本身专栏的独特定位,因此作者并不会涉及基础Verilog语言如阻塞式非阻塞赋值,过程块,数据类型等内容;同时受限于作者知识有限,本专栏也不会涉及System Verilog的相关内容,若按照IEEE的相关标准来看,本专栏将会聚焦Verilog-2005,即“IEEE Std 1364™-2005”以及之前的有关内容,提供相关的IC设计领域语法特性。以下为Verilog的进阶框图,有更多学习需求的读者可以检索相关英文标准进行学习。
在这里插入图片描述

二、什么是parameter

在IEEE Standard2005中,parameter处于第四章“Data Types”的第十节,parameter是Verilog数据类型中的一种,不过与常规的reg或wire不同,parameter不是变量,而是常量
parameter因其常量特性,无法在仿真的过程中进行修改,不过在编译的时候,我们可以使用defparam对其进行修改。

三、如何声明parameter

parameter可以被声明为integer,real,realtime,time四种类型
也可以在parameter后加上signed使其变为有符号数
甚至可以声明parameter的位宽或者使用表达式来计算它的实际值
以下的例子对于声明parameter来说都是合法的。

parameter msb = 7; // defines msb as a constant value 7
parameter e = 25, f = 9; // defines two constant numbers
parameter r = 5.7; // declares r as a real parameter
parameter byte_size = 8,
byte_mask = byte_size - 1;
parameter average_delay = (r + f) / 2;
parameter signed [3:0] mux_selector = 0;
parameter real r1 = 3.5e17;
parameter p1 = 13'h7e;
parameter [31:0] dec_const = 1'b1; // value converted to 32 bits
parameter newconst = 3'h4; // implied range of [2:0]
parameter newconst = 4; // implied range of at least [31:0]

四、如何修改parameter的值

4.1 defparam语句修改parameter值

如果想修改已经定义好的parameter的值,我们可以使用defparam语句来进行修改,以下两个module,在子模块中A和B同时被声明为了位宽为3,大小为2的paramter常量,这个值在顶层模块中通过defparam的索引,最终同时被修改为了3.1415并进行了打印

module foo(a,b);
real r1,r2;
parameter [2:0] A = 3'h2;
parameter B = 3'h2;
initial begin
r1 = A;
r2 = B;
$display("r1 is %f r2 is %f",r1,r2);
end
endmodule // foo
module bar;
wire a,b;
defparam f1.A = 3.1415;
defparam f1.B = 3.1415;
foo f1(a,b);
endmodule // bar

4.2 例化端口时修改parameter的值

除了defparam以外,我们还可以通过端口例化的形式进行修改,以下的module是一个省略了具体逻辑功能的SRAM模块,通过“#”在端口声明的parameter变量可以在例化的时候进行修改

module myram #(
    parameter WORD_SIZE = 1,
    parameter ADDR_SIZE = 1
) (
    input wire [ADDR_SIZE-1:0] addr,
    inout wire [WORD_SIZE-1:0] data,
    // ...
);
module myram_tb;
    myram #(
        .ADDR_SIZE(2),
        .WORD_SIZE(2)
    ) top (
        /* wires */
    )

五、parameter与localparameter的区别

谈到parameter,一个不可能回避的问题就是区分parameter与localparameter。他们的区别如下
parameter可以用于参数传递,因此它在顶层模块中可以被defparam修改
localparam不可以用于参数传递,所以它在顶层模块中不能被defparam修改
根据他们的特点,一般在module内部进行状态机的声明的时候,我们更多的选择localparam,而在涉及到位宽可变的IP设计时,我们会选择使用parameter变量

六、往期【Verilog】高级教程文章

  • 9
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张江打工人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值