分布式算法是一种专门针对于乘加运算的运算方法,与传统的算法相比,分布式算法可以极大地减少硬件规模,很容易实现流水线处理提高硬件的执行速度,也就是提高硬件系统运算速度,而这一点正是很多系统极力追求的目标。正如我们大家所知的那样,在FPGA设计中,通常情况下速度与硬件资源是不可以兼得的,分布式算法不仅可以节省硬件资源又可以提高运算速度。要实现这一目标,自然与其他算法有着本质的区别。
所谓分布式算法,就是指在完成乘加功能时通过将各输入数据每一对应位产生的运算结果预先进行相加形成相应的部分积,在对各部分积进行累加形成最终结果;而传统的算法则是等到所有乘积结果产生之后再进行相加,从而完成整个运算。但是分布式算法应用有一个限定的条件在于,每个乘法运算中必须有一个乘数为常数,这一要求在FIR滤波器中比较吻合。估计大家看到这里,仍然是云里雾里的,就像我刚接触时一样。
如何来理解分布式算法呢?这要从最基本的固定系数乘法运算说起。对于一个乘数是常数的运算,很容易想到用存储器来完成。存储器的运算速度比乘法器快得多,且又可以减少资源。比如 10xA 及100xA 、1000xA(A为3bit的补码数据)则可以构造两个存储器,其中A为存储器的寻地址信号,存储器的内容则为对应的乘法运算结果(用10进制来表示)
表1-a两个常系数乘法运算的存储器实现
输入信号(A)存储地址 | 10XA运算结果/存储内容 | 100xA运算结果/存储内容 | 1000xA运算结果/存储内容 |
000 | 0 | 0 | 0 |
001 | 10 | 100 | 1000 |
010 | 20 | 200 | 2000 |
011 | 30 | 300 | 3000 |
100 | -40 | -400 | -4000 |
101 | -30 | -300 | -3000 |
110 | -20 | -200 | -2000 |
111 | -10 | -100 | -1000 |
因此,乘数中一个为常数的乘法运算可采用查找表来实现,而FPGA的结构本身就是基于查找表接否(LUT)构建的。因此FPGA十分适合查找表来实现常系数乘法运算。FPGA分布式算法的基本思想即采用查找方法实现的结构形式。先来举个4个乘加运算的实例。如 10xA+20xB+30xC+40xD 其中A、B、C、D均是4位二进制补码数据。如果分别采用4个深度为16的存储器来实现4个乘法运算,再将运行结果相加得出输出,显然不会降低多少硬件资源。分布式算法高明之处在于,仍然只采用一个存储器即可实现乘加运算我们将运算形式进行逐位分解:
10xA+20xB+30xC+40xD= 10(-2^3A(3)+2^2A(2)+2A(1)+A(0))
+20(-2^3B(3)+2^2B(2)+2B(1)+B(0))
+30(-2^3C(3)+2^2C(2)+2C(1)+C(0))
+40(-2^3D(3)+2^2D(2)+2D(1)+D(0))
=-2^3(10A(3)+20B(3)+30C(3)+40D(3))
+2^2(10A(2)+20B(2)+30C(2)+40D(2))
+2(10A(1)+20B(1)+30C(1)+40D(1))
+(10A(0)+20B(0)+30C(0)+40D(0))
仔细分析,如果将A(3)B(3)C(3)D(3)组成的4位地址输入信号对应的存储器的输入内容,与将A(2)B(2)C(2)D(2)组成的4位地址输入信号的存储器内容只差2的整数倍次幂倍,在FPGA中可以通过位移来实现。对于上面的例子可以只构造一个深度为16的存储器查找表,通过4次查找表运算,3次移位运算以及一次4输入加法运算,即可完成乘加运算。因此对于长度为N的乘加运算,只需构造一个深度为N的存储器查找表,通过M(M为变量的数据长度)次查找运算、M-1次移位运算及1次M输入的加法运算即可完成乘加运算。这种运算结构极易实现流水线结构,且运算速度受限于加法与查找表的速度,与运算的数据长度无关,从而实现完美的“鱼与熊掌兼得”。