参赛队名:0 ERROR 队伍编号:CICC1957
本篇主要介绍定点数表示实数的方法以及定点数在硬件上的运算验证
32位单精度浮点数:
32位的单精度浮点数为例,IEE754标准规定,一个flaot类型的浮点数X可以表示为
其中,S为符号位,1表示负数,0表示正数;M表示尾数,有0-22位共23位组成,可以表示0~1内的小数,精度为2^(-23),例如,M为23’b110_0000_0000_0000_0000_0000时,表示为十进制小数0.75( 2^(-1)+2^(-2) )。E是指数,为了能够表示负指数、IEEE754标准中规定浮点数的实际指数为E-127。从32位浮点数编码结构上来看,浮点数能够表示一个很大范围能的实数,且能保证较高的有效数字(注意,此处值得是有效数字,而不是有效小数位)。
32位定点数:
定点数表示方法和整数的二进制表示方法类似,仅让后续的固定几位表示小数。以Q15精度(最后15位二进制数表示小数)为例:
32’b0000_0000_0000_0010_1101_0000_0000_0000在Q15精度下可以表示为十进制实数5.625。从Q15精度定点数结构上来看,Q15精度能够保证15位二进制小数精度,结构上与整数的表示法类似(也可以表示负数)。
从结构上来看,浮点数有这很多定点数所不具备的优势,例如,数值范围广、相对精度大。但是,浮点数需要采用额外的编码方式,整数与浮点数做运算时,还需要将整数转化为浮点数才能运算。此外,在FPGA中,并不能直接支持浮点数运算,需要自己设计相应的浮点数运算逻辑单元(或者寻找相关IP),其次,浮点数的运算时间相对于同位宽的定点数要长许多。
相比之下,在数值范围较小(相对于浮点数)、精度要求不那么高的运算中,可以利用定点数加速运算。
我们先看两个8位的Q4精度的小数:
8’b0101_1010,该二进制数值可以表示为十进制Q4精度小数5.625(二进制表示101.1010)。
8’b0001_1011,该二进制数值可以表示为十进制Q4精度小数1.6875(二进制表示为1.1000)。
为了方便说明,下面以二进制的算术运算讲述,对上述两个数值做运算:
1. 对于加法运算:
0101.1010 + 0001.1011
= 0111.0101,即7.3125
由此可以看出,Q4精度小数的加法运算与整数的加法一样,可以直接套用整数加法,这个加法是可以直接有综合工具完成的。减法也与加法类似。
2. 对于乘法运算
0101.1010 * 0001.1001
= 0000_1001.0111_1110,即9.4921875。
由此可以看出,Q4精度小数的乘法运算与整数乘法运算也类似。但值得注意的是,两个Q4精度小数相乘后,小数位扩充到了8位,为了防止溢出,整数位也得相应的进行扩充。结果变成了一个Q8精度的定点数、同时整数位扩充到8位。这与整数的乘法运算类似。两个Q4精度的定点数乘法可以看做两个Q0精度整数相乘的结果乘上2^(-8)。除法的思路也和乘法类似,但是,在FPGA实现中,不建议使用除法,通常除法运算较慢,将严重影响时序。
4 FPGA中定点数乘法运算
高版本的综合工具已经支持有符号整数运算的综合,我们仅需要在RTL代码的对应数据中加入 signed关键词,Vivado就能将后续有符号数运算综合成相应电路(与C语言不同,Verilog规定,无符号数与有符号数运算,会将有符号数视为无符号数)。以下述RTL代码所示有符号Q15定点数乘法为例。
编写相应的testbench后,在Vivado仿真工具进行验证,可以将按需求将数据格式设置为无/有符号的定点数格式,此处设计为Q15精度的有符号格式,结果也为Q15精度,舍弃了后15位小数。
以76ns处为例,threshold_i为0.00161743,与sigma_val_i相乘后,结果与85ns处算出0.04821777,精度在4位小数左右,Q15精度实数乘法运算满足预期。