RTL硬件实现是不能用浮点数计算的,必须要转换成整数才可以,所以任何算法在做硬件实现之前都要经过定点化这一步,定点化做的好,不仅可以简化逻辑,还可以节省不少硬件资源,下面介绍几种常用的定点化方法。
1. 借助2^n定点
这种最常见的就是把小数变成整数,假设有个浮点数3.14,对该小数进行8bit定点,则计算过程为:
四舍五入的结果为804,3.14进行8bit定点后的结果为804,804是一个10bit的数,其中整数部分的“3”占2 bit位宽,小数部分占了8 bit位宽,此时量化精度为1/(2^8)=1/256=0.0039。量化误差为:
量化误差小于量化精度的一半,就可以认为是无损,在实际做题中,只要在转为定点数时,转换后的小数小于0.5就认为是无损量化。
总结一下小数定点的两个公式,假设小数为x,指定量化位宽为n bit,则定点计算公式为:
量化精度为1/(2^n),量化误差的计算公式为:
到这里大家可能会有疑惑,为什么硬件会选择用2^n来做小数的定点而不是用100或者200这样的数值呢?这是因为硬件做移位操作特别容易,假设两个小数2.15×3.29,两个数据都做8 bit定点分别为:
四舍五入取整数后为550×842=463100,乘完后的结果有16 bit的精度,如果只需要8 bit的精度,硬件就可以直接把463100右移8位,相当于除以256,最后的结果是1808。如果要做四舍五入,则(463100+128)再右移8位即可,此时的128相当是分母一半,也就是0.5的定点。
所以小数转定点使用2^n是为了给硬件移位方便。
2. 除法定点
一般在RTL实现的时候如果遇上除法,都是直接使用写好的除法器模块。如果分母是固定的,则可以把除法转换成乘法来节省除法器资源。比如x/25这种,分子是变化的,但是分母一直是固定的值,这种就需要把除法转换成乘法来做,具体做法如下:
其中(2^n)/25是一个固定的系数,而分母上的2^n可以通过移位实现,这样就把一个除法计算转换成了乘法+移位的操作,达到了节省除法器的目的。
如果要求除法器的精度为8bit,则x/25定点后的结果就是:
如果x的值为111,则(10×111)>>8=4(“>>”是右移8bit的意思,等同于除以256后向下取整),当然如果除法的后面还有其他操作,比如(x/25)×18,那8 bit的移位可以挪到乘法后再做,比如((10×111×18)>>8)=78,如果先移位8bit再乘18则变成了((10×111)>>8)×18=72,前后相差了6,这个6就是除法器精度带来的好处。