芯路恒电子技术论坛

 找回密码
 立即注册
热搜: 合集
查看: 9229|回复: 4

verilog语法中信号位宽常见问题解析

[复制链接]
  • TA的每日心情
    开心
    2021-12-31 09:03
  • 71

    主题

    78

    帖子

    976

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    976
    发表于 2021-8-6 18:01:33 | 显示全部楼层 |阅读模式
    很多同学在Verilog中定义多位宽变量时,会有许多疑问,现在把一些常见疑问进行罗列解答:1、位宽不能为变量,在程序生成代码时,位宽需为定值。例如:我们有如下错误位宽定义:

    9.png
    如上图,图中的变量cnt2的位宽cnt,被定义为了变量,并且在always语句中进行了赋值操作,进行编译时,编译器对cnt2的定义行(23)报错。
    那是不是说明位宽定义必须为纯数字呢?事实上不是,实际运用过程中,位宽被定义为参数的情况,还是比较常见的。

    50.jpg
    例如在OV5640摄像头的rgb初始化table中,对输出的寄存器初始化参数,将位宽定义为参数形式,能更好的保持程序的扩展应用性。

    2、位宽的选择,要以够用为标准,过多的位宽会占用过多的FPGA逻辑资源。例如:在led闪烁实验中,我们将计数器cnt的值位宽从[24:0]修改为[124:0]

    10.jpg

    11.jpg

    可以看到,在资源使用统计报告中,消耗的逻辑资源和寄存器数量,均随位宽的使用增加。

    3、仿真中,如果定义的位宽大于源文件中的位宽,则仿真输出的数据会变成蓝色波形,多出的位为高阻态。

    60.jpg

    61.jpg

    如上图,当仿真的位宽大于源程序位宽时,整个输出的数据会呈现特别颜色(默认为蓝色)。多出的位宽,会以Z的形式显示。可以通过这种方法,确定是否位宽定义过大。

    4、在多层级的复杂工程中,如果数据通过模块传递时,中途有某一层级位宽忘记定义,则在这一级以后驱动的数据,位宽均默认为1位有效,并且编译器不会报错。例如,我们制造一个经过四级传递的计数器控制led闪烁实验来说明问题。经过了四级传递。正常情况下,计数器的值能够从底层正常传递到顶层,并传递给仿真或外设(此处以led为例)。

    90.jpg

    91.jpg

    但是,在中途传递过程中,有一级cnt的位宽忘记写了,如果没有仿真,则看起来一切正常,并且编译能够通过了,但是上板子就是不能正常运行。通过仿真,能够找到问题的根源在于位宽不正常,从底层到顶层传递过程中,位宽在中途其中一层,定义不正常。情况如下:

    92.jpg

    93.jpg
    从宏观来看,位宽异常导致led闪烁的功能没有实现。仿真图如下:

    94.jpg

    这一方面说明了位宽定义的重要性,二方面说明了仿真的重要性。所以,对于传递信号,特别是地址、数据信号,一定要记得对对位宽进行定义。

    5、在有符号数的表示过程中,最高位为符号位,如果进行有符号位运算,则应当在确定好的位宽后,再加1,保证符号位的正确表达。例如:我们做一个简单的减法运算如下:
    81.jpg

    82.jpg

    80.jpg

    从上述案例中可以看到,如果对输出结果的位宽定义不足,没有考虑到符号位的存在,则不但无法获取正确结果,甚至连得到结果的绝对值都是错误的。如c和d,虽然[3:0]表示的四位位宽能装下数字11,但是如果作为有符号数运算没有考虑多放符号位位宽,则结果错误。所以遇到这种情况,应该如e和f一样,至少多放一个位宽,以保证符号位的充分表达。






    eg_4.rar

    15.41 KB, 下载次数: 335

    eg_3.rar

    15.8 KB, 下载次数: 344

    eg_2.rar

    18.9 KB, 下载次数: 345

    eg_1.rar

    7.12 KB, 下载次数: 342

    eg_5.rar

    8.09 KB, 下载次数: 399

    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-2-24 10:16
  • 428

    主题

    811

    帖子

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    16107
    QQ
    发表于 2021-8-7 11:56:18 | 显示全部楼层
    标题改为:verilog语法中信号位宽常见问题解析,是否更加准确精炼和直击目标。

    很多同学在使用verilog进行变量定义时(描述是否恰当?改为在Verilog中定义多位宽变量时,是否更为合理),会有许多疑问,现在把一些常见疑问进行罗列解答:
    1、位宽不能为变量,在程序生成代码时,位宽为定值。(什么意思?没看懂,请补充说明)
    2、位宽的选择,要以够用为标准,过多的位宽会占用过多的FPGA逻辑资源。(请举例说明)
    3、仿真中,如果定义的位宽大于源文件中的位宽,则仿真输出的数据会变成蓝色波形,多出的位为高阻态。(请举例说明)
    4、在多层级的复杂工程中,如果数据通过模块传递时,中途有某一层级位宽忘记定义,则在这一级以后驱动的数据,位宽均默认为1位,并且编译器不会报错。(如何去查看,这个问题是有警告的,通过rtl视图也可以查看)
    5、在有符号数的表示过程中,最高位为符号位,如果进行有符号位运算,则应当在确定好的位宽后,再加1,保证符号位的正确表达。(此项是否确定,有没有案例证明)
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-2-24 10:16
  • 428

    主题

    811

    帖子

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    16107
    QQ
    发表于 2021-8-9 20:27:15 | 显示全部楼层
    帖子开头一句话,我给了修改建议,暂未发现修改。

    第二点,确定是呈线性增加,不是指数?你只列举了2种情况,相当于坐标系中2个点,你拟合得到的函数是根本不可靠的。

    第三点,这建议用原色图,否则无法看到你说的蓝色现象等。

    第4点,使用的例子不恰当,不了解这个工程,不完全对着这个工程源码看很难和你的文字描述对应上,建议重写一个非常简单的代码案例来做演示,并想办法在信号名命名时候就能体现其所在的层级。


    第5点,使用例子不恰当,c和d都只有1位,1位数据谈正负,太没意义了,建议用8位或以上的数据做例子。


    另外,请将使用参数形式定义位宽的方法写在帖子里,不明白的可以先学习max发在群里的那个链接。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-9 15:31
  • 0

    主题

    2

    帖子

    15

    积分

    新手入门

    Rank: 1

    积分
    15
    发表于 2021-8-26 12:16:46 | 显示全部楼层
    位宽为变量的表示形式:A[base_addr+:Width]  base_addr为起始地址,+/-表示方向,Width为位宽,例 i=1,A[8*i-:8]就是A[8:1],A[8*i+:8]就是A[15:8]
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-31 09:03
  • 71

    主题

    78

    帖子

    976

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    976
     楼主| 发表于 2021-8-26 15:34:20 | 显示全部楼层
    盛志超 发表于 2021-8-26 12:16
    位宽为变量的表示形式:A  base_addr为起始地址,+/-表示方向,Width为位宽,例 i=1,A[8*i-:8]就是A[8:1], ...

    您说的这种情况,是位宽为固定参数的情况吧?这种情况编译器可以接受。但是编译器无法接受一种位宽为赋值寄存器的形式。在程序的不同阶段(典型如状态机的不同状态)下,如果位宽被赋予了不同的值,这种情况,是不能被编译器编译的。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|Archiver|芯路恒电子技术论坛 |鄂ICP备2021003648号

    GMT+8, 2024-11-22 04:44 , Processed in 0.121594 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

    快速回复 返回顶部 返回列表