在FPGA中,经常使用定点数表示小数,在进行各种运算时,定点数的位宽会发生变化,并且需要在适当地时候对数据的位宽进行截取。
运算要求和引起的位宽变化
假设存在两个数A、B,假定A位宽为m,小数位宽为a,B位宽为n,小数位宽为b。
无符号数加法:A+B,需要先将A和B的小数点对齐,再将整数位和小数位都扩展至较大的位宽,最终结果的位宽为拓展后的位宽+1。
有符号数加法:A+B,无需注意A、B符号位,可直接相加,同样需要先将A和B的小数点对齐,再将整数位和小数位都扩展至较大的位宽,最终结果的位宽为拓展后的位宽+1。
无符号数减法:A-B,需要先将A和B的小数点对齐,再将整数位和小数位都扩展至较大的位宽,最终结果的位宽为拓展后的位宽+1。
有符号数减法:A-B,无需注意A、B符号位,可直接相减,同样需要先将A和B的小数点对齐,再将整数位和小数位都扩展至较大的位宽,最终结果的位宽为拓展后的位宽+1。
无符号数乘法:A*B,无需对齐,无需注意A、B符号位,可直接相乘,最终结果的位宽为m+n。
有符号数乘法:A*B,无需对齐,无需注意A、B符号位,可直接相乘,最终结果的位宽为m+n-1。其实最终结果位宽原本为m+n,其中包含两位符号位,当符号位为10和01时,表明运算结果溢出,符号位为00和11时,去掉最高位
位宽截取
在乘法运算中,会成倍的增加位宽,因此在FPGA算法实现的过程中,常常需要对数据的位宽进行截取,常用的位宽截取方法有以下几种。
2.1 截断(tu)
2.2 四舍五入
“舍入”舍入到最邻近的可表示数字。如果出现结值,则舍入:
将正数朝正无穷方向舍入到最邻近的可表示数字。
将负数朝负无穷方向舍入到最邻近的可表示数字。
因此:
负值样本会引入小的负偏置。
对于具有均匀分布的正值和负值的样本,不会引入偏置。
对正值样本引入小的正偏置。
使用verilog编程时,假设要将m位数据截断为n位数据,需要将要截断的数据+{符号位取反,m-n-1{符号位}}再右移m-n位。以verilog为例,假定一64位有符号数要截断为一32位有符号数,程序如下。
reg signed [31:0] dataout;
wire signed [63:0] datain;
always@(posedge clk)begin
dataout <= (datain + {~datain[63],31{datain[63]}}) >> 32;
end
十进制 |
定点化 |
二进制 |
舍入后二进制 |
定点化 |
十进制 |
-22 |
-1.375 |
1_1110_1010 |
1_1111_0000 |
-1 |
-16 |
-24 |
-1.5 |
1_1110_1000 |
1_1110_0000 |
-2 |
-32 |
-26 |
-1.625 |
1_1110_0110 |
1_1110_0000 |
-2 |
-32 |
22 |
1.375 |
0_0001_0110 |
0_0001_0000 |
1 |
16 |
24 |
1.5 |
0_0001_1000 |
0_0010_0000 |
2 |
32 |
26 |
1.625 |
0_0001_1010 |
0_0010_0000 |
2 |
32 |
2.3 收敛
“收敛”向最邻近的可表示值舍入,并将结值向最邻近的偶数舍入。它消除了由于舍入造成的偏置。但这可能会引入溢出。
具体实现以后再写
例子:
十进制 |
定点化 |
二进制 |
舍入后二进制 |
定点化 |
十进制 |
-16 |
-0.5 |
1_1111_0000 |
0_0000_0000 |
0 |
0 |
-22 |
-1.375 |
1_1110_1010 |
1_1111_0000 |
-1 |
-16 |
-24 |
-1.5 |
1_1110_1000 |
1_1110_0000 |
-2 |
-32 |
-26 |
-1.625 |
1_1110_0110 |
1_1110_0000 |
-2 |
-32 |
16 |
0.5 |
0_0001_0000 |
0_0000_0000 |
0 |
0 |
22 |
1.375 |
0_0001_0110 |
0_0001_0000 |
1 |
16 |
24 |
1.5 |
0_0001_1000 |
0_0010_0000 |
2 |
32 |
26 |
1.625 |
0_0001_1010 |
0_0010_0000 |
2 |
32 |
2.4 向上取整 向下取整目前用不到 以后再写
位宽溢出文章来源:https://www.toymoban.com/news/detail-428741.html
在编程时,当等号右侧位宽大于左侧数据位宽时,无论是否有符号,无论小数位数是多少,均截取最高位。截取时,若右侧结果未超过左侧所能表示的范围,则正数的高位均为0,负数的高位均为1,截取后不会影响结果。但当右侧结果超过左侧所能表示的范围时,则会导致结果出现错误。文章来源地址https://www.toymoban.com/news/detail-428741.html
到了这里,关于【FPGA】定点数 数据位宽 运算 位宽截取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!