在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 6159|回复: 4

[原创] 小总结一下verilog的位宽与数据转换

[复制链接]
发表于 2016-3-4 08:51:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
昨天写某verilog的教学实例,又犯了常犯的错误,枉花了不少时间。
总结一下:

如果有以下定义:

wire signed [7:0] a;
wire signed [15:0] b;
wire signed [16:0] sum;
wire signed [23:0] prod;

关于数学运算的位宽:
  • 加乘等数学运算实现的位宽决定于操作数中位宽宽的那个,比如:
a + b ,  a * b 都是按16位实现的,如有溢出概不负责。
  • 如果是运算后立即赋值,而被赋值变量较宽,则按被赋值的变量宽度计算,比如:
sum = a + b; 是按17位实现的。


prod = a * b; 是按24位实现的。
都不会有溢出问题。
  • 但这么写,就悲剧了:
sum = {a + b}; 加法后没有立即赋值而是做了其它运算,这里以位拼接为例的,于是加法是按16位实现的,结果会溢出。

  • 同样,这样写也是悲剧的:
prod = (a * b) >>> 7; 本想要相乘后除以128,结果乘法是按16位实现的,会溢出,我就是错在这里,不是第一次了。

简便的解决办法是: prod = (24'sb1 * a * b) >>> 7; 放心综合器不会傻到多实现一个乘法器……


关于赋值:
  • real常量赋值给整形,是四舍五入的!比如:
a = 100 * 0.267; a最终是等于8'sd27的,所以我们不必画蛇添足写个+0.5或-0.5了。

  • 短有符号数赋值给长数(不管有无符号),是会填充符号位的,保证值的意义尽量不变,比如:
如果先有:a = -8'sd1或者a = 8'd255(注意两者对a来讲是无区别的);
b = a; 或直接写 b = -8'sd1; b最终都是等于-16'sd1的。

注意如果先有:wire [7:0] c = -8'd1;
在写:b = c; 和 b = -8'd1; 情况是不一样的!
在对c赋值时c已然变为8'd255,理解为 8'd0 - 8'd1(因为“-8'd1”代表的“无符号数-1”是不能理解的),前者是无符号数向长有符号数赋值时,自然是填充0,结果b为16'sd255。

而后者,应理解为一个减法运算后立即赋值,所以减法运算是按16位有符号进行的:16'sd0 - 8'd1,结果b为-16'sd1。
发表于 2016-3-4 17:58:33 | 显示全部楼层
回复 1# yifenqian


    好文章
发表于 2016-3-4 17:59:43 | 显示全部楼层
就是好文章!
发表于 2016-3-5 09:36:40 | 显示全部楼层
关于最后一点,个人的理解是:
a作为有符号数,在进行位数展宽时,按有符号数进行扩展,因此最终的b仍是-1,
c作为无符号数,扩展位宽时,按无符号的来,即高位补0,所以b最终为255.
发表于 2024-5-6 19:57:18 | 显示全部楼层
intA=-4'd12,RHS是无符号表达式,故按高位补零扩展,这样理解正确吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-19 00:19 , Processed in 0.021999 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表