【前端设计】尝试一文搞懂verilog parameter的全部细节

文章详细介绍了Verilog中参数的定义方式,包括类型、位宽、名称和值的属性,以及如何根据显式声明和隐式声明规则确定参数的属性。通过实例展示了不同参数定义的结果,并讨论了lint检查时的处理策略。
摘要由CSDN通过智能技术生成

这里是尼德兰的喵·芯片设计相关文章,欢迎您的访问!

如果文章对您有所帮助,期待您的点赞收藏!

让我们一起为成为芯片前端全栈工程师而努力!

一个参数的标准定义呢应该是这样的:

parameter type range name = value;

也就是说一个标准的参数呢是有以下四个属性的:type类型,range位宽/区间,name名字和value数值。实际操作中呢,除了名字和数值其他两个是可以省略的,比如下面这些参数定义方法都是可以编译的:

parameter P0 = 5;
parameter P1 = 3'd5;
parameter P2 = -5;
parameter P3 = 1.5;
parameter P4 = P0 + P1;
parameter signed [15:0]   P5 = -7;
parameter unsigned [15:0] P6 = -7;
parameter [15:0] P7 = -7;
parameter [15:0] P8 = 2'd1;
parameter real P9 = 3e7;
parameter realtime P10 = 10;
parameter unsigned [63:0]P11 = $signed(-2);
parameter signed[31:0]P12 = $unsigned(-2);
parameter P13 = $unsigned(-2);
parameter [31:0]P14 = -2;

顺便我将这些参数的打印结果也放一下:

P0 = 'b101 = 'd5 = 'f5.000000
P1 = 'b101 = 'd5 = 'f5.000000
P2 = 'b11111111111111111111111111111011 = 'd-5 = 'f-5.000000
P3 = 'b1 = 'd1 = 'f1.500000
P4 = 'b1010 = 'd10 = 'f10.000000
P5 = 'b1111111111111001 = 'd-7 = 'f-7.000000
P6 = 'b1111111111111001 = 'd65529 = 'f65529.000000
P7 = 'b1111111111111001 = 'd65529 = 'f65529.000000
P8 = 'b1 = 'd1 = 'f1.000000
P9 = 'b1110010011100001110000000 = 'd30000000 = 'f30000000.000000
P10 = 'b1010 = 'd10 = 'f10.000000
P11 = 'b1111111111111111111111111111111111111111111111111111111111111110 = 'd18446744073709551614 = 'f18446744073709551616.000000
P12 = 'b11111111111111111111111111111110 = 'd-2 = 'f-2.000000
P13 = 'b11111111111111111111111111111110 = 'd4294967294 = 'f4294967294.000000
P14 = 'b11111111111111111111111111111110 = 'd4294967294 = 'f4294967294.000000

那么我们就来分析分析这些参数定义方式的四个属性分别是什么。判定参数的属性时,遵循两个大的基本原则(就是说特殊情况除外的那种原则上说):

1.如果有显性声明,则以显性声明为准;

2.如果没有声明type和range,则以value的type和range为准;

一个与大规则2相违背的小规则:

1.如果参数有指定range,但没有type,则它的符号默认为unsigned,并且range和符号都不会被后面的声明所覆盖;

规则其实并不乱,咱们一起来看一下 。

parameter P0 = 5;
打印:
P0 = 'b101 = 'd5 = 'f5.000000

这是我们最常用的写法了,此时P0的属性由后面的5来决定。而5本身是int型数据,因此P0的属性为:type = signed,range = [31:0],value = 5。

parameter P1 = 3'd5;
打印:
P1 = 'b101 = 'd5 = 'f5.000000

与P0很接近,只不过此时3'd5指明了数据类型为unsigned,数据位宽为3bit,因此P1的属性为:type = unsigned,range = [2:0],value = 5。其实这种情况下signed和unsigned并不太区分,甚至我感觉很多时候是和编译器和lint检查软件有关系。

那么我们改一下,

parameter P2 = -5;
parameter [15:0] P7 = -7;
打印:
P2 = 'b11111111111111111111111111111011 = 'd-5 = 'f-5.000000
P7 = 'b1111111111111001 = 'd65529 = 'f65529.000000

这两个放一起看,一个等于-5一个等于-7,value的属性其实是一样的,但是看打印结果也能看出来P2是有符号数而P7是无符号数,为什么呢?注意小规则1:

1.如果参数有指定range,但没有type,则它的符号默认为unsigned,并且range和符号都不会被后面的声明所覆盖;

显然P7就符合这种情况,因此P7是无符号数,P2是有符号数。

parameter P3 = 1.5;
打印:
P3 = 'b1 = 'd1 = 'f1.500000

设计代码中很少有这种参数,所以我觉得吧看看结果就好了( • ̀ω•́ )✧能编译,能不能综合我就不知道了,感兴趣的自行探究下吧。

parameter P4 = P0 + P2;
打印:
P4 = 'b1010 = 'd10 = 'f10.000000

parameter中是可以包含运算的,像这种就是运算得出结果后在遵循之前的规则,因此P4的属性为:type = unsigned,range = [31:0],value = 10。

parameter signed [15:0]   P5 = -7;
parameter unsigned [15:0] P6 = -7;
打印:
P5 = 'b1111111111111001 = 'd-7 = 'f-7.000000
P6 = 'b1111111111111001 = 'd65529 = 'f65529.000000

P5和P6很好的说明了,显性定义的type是不会被后面的value所覆盖的,P5的属性:type = signed,range = [15:0],value = -7,P6的属性:type = unsigned,range = [15:0],value = 65529。

parameter [15:0] P8 = 2'd1;
打印:
P8 = 'b1 = 'd1 = 'f1.000000

这个地方不要被打印蒙蔽哈,因为我用的是%0b/d/f的方式所以打印时会截掉没有的位宽。

parameter real P9 = 3e7;
parameter realtime P10 = 10;
打印:
P9 = 'b1110010011100001110000000 = 'd30000000 = 'f30000000.000000
P10 = 'b1010 = 'd10 = 'f10.000000

这种real、realtime型在设计中也很少写,不建议过多关注。real数据类型支持的语法显然在参数定义时也是可以支持的。

parameter unsigned [63:0]P11 = $signed(-2);
parameter signed[31:0]P12 = $unsigned(-2);
parameter P13 = $unsigned(-2);
parameter [31:0]P14 = -2;
打印:
P11 = 'b1111111111111111111111111111111111111111111111111111111111111110 = 'd18446744073709551614 = 'f18446744073709551616.000000
P12 = 'b11111111111111111111111111111110 = 'd-2 = 'f-2.000000
P13 = 'b11111111111111111111111111111110 = 'd4294967294 = 'f4294967294.000000
P14 = 'b11111111111111111111111111111110 = 'd4294967294 = 'f4294967294.000000

这四个对比着看,很有意思。P11和P12都能看出,显性声明优先级最高。P13没有显性声明听value的规则,value是无符号数那P13也是无符号数。P14只有range没有type,那type就固定为unsigned,不听value的了。

OK所有关于参数的细节就说完了,在进行lint检查时有时参数会造成一些这也不对那也不对的干扰,那么如果你很确认自己的设计没有风险的话,可以在rule.tcl中将check_static_value关闭,那么spyglass就不会对parameter的lint违规进行检查了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

尼德兰的喵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值