verilog中直接使用*,/符号进行数学计算时,位宽不匹配的截位问题

verilog中直接使用*,/符号进行数学计算时,位宽不匹配的截位问题

案例:

input  [31:0]          PWM_FREQ,           
input  [31:0]          PWM_Duty_cycle,     

reg [31:0]                 total_period_cycles; 
reg [31:0]                 high_period_cycles;  

total_period_cycles     <= (100_000_000 / PWM_FREQ)           ;
high_period_cycles      <= (total_period_cycles * PWM_Duty_cycle) / 1000000 ;

分析:

		当前,所有涉及到的信号均定义为32位宽。
   	   	high_period_cycles值计算的时候,涉及到了两级运算。先进行total_period_cycles *    PWM_Duty_cycle运算,在边界情况,本运算的值会超过32位。* 	
   	   	当按照图示无特殊处理时,由于  high_period_cycles 的赋值操作中又紧接着有一个除以 1000000,这将导致最终除法的结果值不会超过32位。因此,尽管乘法操作可能会产生一个64位的结果,但由于紧接着的除法操作,Vivado编译器在优化时会考虑到这一点,并可能将中间值保存为32位宽的数,以避免不必要的资源消耗;
  	   	当对(total_period_cycles * PWM_Duty_cycle) / 1000000    ;中的1000000进行位数约束的时候, 即64'd1000000 。编译器会保留所有的64位作为最终运算值进行下一步运算.因为如果  1000000 是一个64位的常量,那么反推乘法操作 total_period_cycles *PWM_Duty_cycle 的值至少也会存在64位宽。因此会把(total_period_cycles * PWM_Duty_cycle)默认优化成64位。***

结论

  1. 减少直接使用*、/的符号运算
  2. 避免在单个语句中进行多步运算
  3. 如果避免不了多步运算,运算中涉及到的常数需要规定位宽,这样编译器对于中间值也会自动匹配
  4. 每一步运算均要考虑溢出问题,当位宽未定义足时,编译器默认会截取低位数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值