描述
在verilog代码设计时使用算术运算符与乘法搭配使用出现计算错误
原因
由于数据位宽设置不当导致
错误案例
wire signed [13:0] w01;
wire signed [23:0] s01;
reg signed [24:0] m01;
reg signed [25:0] a1;
// 24 + 14 - 13 = 25
m01 <= (w01 * s01) >>> 13;
m02 <= (w02 * s02) >>> 13;
a1 <= m01 + m02;
仿真
在此处运算时,我们似乎设计好了数据位宽,看起来好像没有错误,但是看仿真结果
计算
m01 = (s01 * w01) >>> 13 = (3202 * 68270) >>> 13 = 218600540 >>> 13 = 26684
显然与结果不符合
修改一
将m01的数据位宽与乘法结果位宽匹配. 即m01的位宽应该时w01的位宽加上s01的位宽, 即reg signed [37:0] m01;
仿真
此处可以看出仿真结果与手算结果一致
修改二
先使用m01,m02等将结果线先存储起来, 在进行加法运算时将数据算术缩小
// 定义位宽.以及其signed属性
wire signed [13:0] w01;
wire signed [23:0] s01;
reg signed [37:0] m01;
reg signed [15:0] a1;
// 乘法处理
m01 <= w01 * s01;
m02 <= w02 * s02;
// 加法处理, 加完后算术运算符缩小
a1 <= (m01 + m02) >>> 13;
仿真结果
验证
m01 = w01 * s01 = 3202 * 68270 = 218,600,540
m02 = w02 * s02 = 3762 * -39900 = -150,103,800
a1 = m01 + m02 = (218,600,540 -150,103,800) >>> 13 = 68,496,740 >>> 13 = 8361
计算结果和仿真结果一致
总结
以上两种修改方法目的在于进行位宽匹配,因此在使用运算符的过程中,需要谨慎位宽,防止数据溢出
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体