定点DSP芯片的数值表示基于2的补码表示形式。每个16位数用1个符号位、i个整数位和 15-i 个小数位来表示。因此,二进制数 00000010.10100000 表示的值为2 1 +2 -1 +2 -3 =2.625 ,这个数可用Q8格式(8个小数位)来表示,其表示的数值范围为-128~+127.996。也就是说,一个Q8定点数的小数精度为1/2 8 =0.004。
虽然特殊情况(如动态范围和精度要求)必须使用混合表示法,但是更通常的是全部以Q15格式表示的小数或以Q0格式表示的整数来工作。这一点对于主要是乘法和累加的信号处理算法而言特别现实,即小数乘以小数得小数,整数乘以整数得整数。当然,乘积累加时可能会出现溢出现象,在这种情况下,程序员应当了解数学里面的物理过程以注意可能的溢出情况。下面讨论乘法、加法和除法的DSP定点运算。
两个定点数相乘的规则是:如果两个被乘数的格式分别是Qx和Qy,则乘法的结果将为Q(x+y)格式,即Qx × Qy=Q(x+y)。
下面分三种情况进行讨论。
1.小数乘小数
Q15×Q 15=Q 30
【例3.10】 0.5×0.5 = 0.25。
两个Q15的小数相乘后得到一个Q30的小数,即有两个符号位。一般情况下相乘后得到的满精度数不必全部保留,只需保留16位单精度数。由于相乘后得到的高16位不满足15位的小数精度要求(Q14),所以为了达到15位精度,须将乘积左移一位,以得到Q15精度。
2.整数乘整数
【例3.11】 17×(–5)= –85。
3.混合表示法
许多情况下,在运算过程中为了既满足数值的动态范围又保证一定的精度,就必须采用Q0与Q15之间的表示法。例如,数值1.2345,显然用Q15无法表示,而若用Q0表示,则最接近的数是1,精度无法保证。因此,数1.2345最佳的表示法是Q14。
【例3.12】1.5×0.75 = 1.125。
Q14的最大值不大于2,因此,两个Q14数相乘得到的乘积不大于4。
一般地,若一个数的整数位为i位,小数位为j位,另一个数的整数位为m位,小数位为n位,则这两个数的乘积为(i+m)位整数位和(j+n)位小数位。这个乘积的最高16位可能的精度为(i+m)整数位和(15–i –m)小数位。
但是若事先了解数的动态范围,就可以增加数的精度。例如,程序员了解到上述乘积不会大于1.8,就可以用Q14数表示乘积,而不是理论上的最佳情况Q13。
定点加法是一个比较复杂的过程。首先,必须保证两个加数用相同的Q值表示;其次,程序员或者允许存放加法结果的寄存器有足够的高位以适应位的增长,或者必须准备好解决加法的溢出问题。下面结合BlackfinDSP通过实例来加以说明。
【例3.13】 两个16位正数相加,结果用16位表示。
设有两个16位正整数r0.l = 0x6000,r5.h = 0x3000。将这两个16位整数相加,结果放到16位寄存器中:
第一个加法的结果是 r7.l=0x9000。由于溢出没有保护,两个正数相加,结果超过 16位的最大值0x7FFF,发生溢出,得到一个不正确的负数。
第二个加法的结果是 r7.h=0x7FFF。由于溢出进行了保护,两个正数相加,结果超过16位的正最大值0x7FFF,溢出保护为正最大值,即0x7FFF。
【例3.14】 两个16位负数相加,结果用16位表示。
设有两个16位负整数r0.l = 0xe5a4,r4.h = 0x8a5a。将这两个16位整数相加,结果放到16位寄存器中:
第一个加法的结果是 r5.l=0x8000。由于溢出进行了保护,两个负数相加,结果超过16位的负最大值0x8000,溢出保护为负最大值,得到的加法结果为0x8000。
第二个加法的结果是 r5.h=0x6ffe。由于溢出没有保护,两个负数相加,结果超过 16位的负最大值0x8000,发生溢出,得到一个不正确的正数。
当然,如果加法的结果不溢出,则加与不加溢出保护得到的结果是一样的。
如果两个16位操作数相加的结果用32位数表示,则结果就不会发生溢出。例如:r4=a1.l+a1.h;
1.除法运算的基本原理
与乘法运算和加法运算相比,DSP除法运算是更加复杂的过程。DSP除法运算通常包含一系列的移位和条件减法运算。由于数据在寄存器中以二进制形式存储,所以DSP要进行的除法为二进制除法。二进制除法和十进制除法在实现原理上大致相同。下面先以一个十进制除法为例说明除法过程。
考虑下面的除法运算:
55/4=13.75
在计算之前,由于算法不能处理大于10的结果,所以要保证分子不能大于分母的10倍,即先将分母乘以10,然后计算:
55/40≈1.375
得到除法结果后再乘以10,就得到正确的结果了。
接下来,采用条件减的方法来计算 55/40:先重复地利用分子减去分母,直到结果为小于分母的数或0,执行的减法次数就是商的整数部分;然后把余数乘以10,再重复操作,可逐次得到商的小数部分。
(1)计算商的整数部分:
55-40=15,执行减法次数为1,分子小于分母,停止减;
得到整数部分的值为1;
余数为15。
(2)计算商的小数部分的第1位:
余数乘以10,得到150;
150- 40 =110,执行减法次数为1,分子大于分母,继续减;
110- 40 =70,执行减法次数为2,分子大于分母,继续减;
70- 40 =30,执行减法次数为3,分子小于分母,停止减;
得到小数部分的第1位3;
余数为30。
(3)计算商的小数部分的第2位:
余数乘以10,得到300;
300- 40 =260,执行减法次数为1,分子大于分母,继续减;
经过总共7次减,得到余数20,分子小于分母,停止减;
得到小数部分的第2位7。
(4)计算商的小数部分的第3位:
余数乘以10,得到200;
200- 40 =170,执行减法次数为1,分子大于分母,继续减;
经过总共5次减,得到余数0,停止减;
得到小数部分的第3位5。
经过上述运算,最终得到的结果是1.375。
2.DSP二进制除法的实现过程
在二进制除法中,计算过程与十进制除法是相同的。根据算法要求,必须保证被除数不能大于除数的2 倍(这是因为基数是2)。因此,对于上述例子,要对除数乘以8,这相当于将除数左移3 位,因此即将进行的运算即为
55/32=1.71875
下面以使用16位累加器为例,其运算过程是:先将被除数放在累加器的高8位,再用高8位减32,最后将除法结果存放在商寄存器中(初值为0)。具体运算过程如例3.15所示。
【例3.15】 55/32的二进制除法过程。
(1)累加器高8位减32。
够减,则商寄存器的bit15位置为1,结果为
(2)余数左移1位,再减32。
够减,则商寄存器的bit14位置为1,结果为
(3)余数左移1位,再减32
不够减,则商寄存器的bit13位置为0,结果为
(4)余数再左移1位,再减32。
够减,则商寄存器的bit12位置为1,结果为
(5)余数左移1位,再减32。
够减,则商寄存器的bit11位置为1,结果为
(6)余数左移1位,再减32。
够减,则商寄存器的bit10位置为1,结果为
最终,商寄存器的值为1101 1100 0000 0000,这是一个无符号数,Q值为15,即小数点位于bit15与bit14之间,这个值等于1.71875,因此有
需要指出的是,上述除法算法的条件是:分子、分母均为无符号的正整数;计算前,要保证分子不大于分母的2倍。