1.应用场景
一般情况下我们使用FPGA处理数据时都是非常喜欢使用并行处理+流水线结构的,但是如果工程占用的乘法器、加法器资源量过多,导致资源不够用时,就需要考虑折叠的设计方案了,将多个相同的运算单元经过时分复用控制,使用一个运算单元来完成。当然这样做会导致处理速度变慢,但是能起到节省运算资源的作用,虽然当前很少用折叠的方案,但既然学了那就记录一下吧。
2.折叠方法
我直接上自己设计的例子吧,别的地方的理论方面都是清一色的二阶滤波器的例子,这个电路虽然很典型,但是对于我在学习的过程中理解起来非常痛苦,在看我的例子之前要先了解折叠公式这些基本概念
这里以1x4乘以4x1矩阵为例,输出的结果是
a0xb0+a1xb1+a2xb2+a3xb3
2.1图上标号解释
( s1 | 0 ) ( s1 | 1 ) ( s1 | 2 ) ( s1 | 3 )
这几个是表示乘法器在折叠之后的折叠顺序,实际上可以随便标,只是在最后实现电路以及控制输入的时候需要一一进行对应。
同理( s2 | 0 ) ( s2 | 1 ) ( s2 | 2 )是加法器的执行顺序,也是可以随便标志。
然后就是红色的数字1、2、3、4、5、6、7了,这个就是为了写折叠公式用的,没什么实际意义,非要解释的话就是给这几个运算单元起个名字吧。
2.2折叠公式参数理解
先上公式吧。
按照那些清一色的规矩,定义乘法器后面默认延时2个时钟(也就是Pu=2),加法器后面默认延时1个时钟(也就是Pu=1);原电路中乘法器有4个,加法器有3个,那在算数据流发送端为乘法器时,N=4,同理在算数据流发送端为加法器时,N=3。
而W(e)是在原始电路中,数据流发送端到接收端需要几个时钟延时,其结果就是几。
最后就是v和u了,v其实就是上面定义的接收端的计算顺序,比如发送端是1,接收端是5
则DF(1->5)=4(1)-2+0-0=2
当然这些结果需要有一个条件,那就是D(U->v)应当大于等于0才可以进行折叠,其实原始电路的乘法器与加法器之间是没有寄存器延时的,但是没有寄存器延时的电路通过折叠公式计算有负数,所以不成立,只有加一级流水线才可以进行折叠。
2.3画出折叠后电路
之后就可以根据计算出的这些顺序画出折叠后的电路了。
这里举第一个式子的例子,DF(1->5)=4(1)-2+0-0=2。
意思就是乘法器0的结果,需要延时4个clk(乘法器基本单元有两个延时,加上式子算出的延时共4个),才将数据宋到加法器中进行处理,其余使用类似的思路。
从时钟的角度来看,就是第一个clk,计算a0xb0,第二个clk,a1xb1,接着总共花费了四个clk将乘法计算完毕,并依次存入后面的寄存器中,然后在第5个clk的时候,因为乘法器0(这里乘法器0指( s1 | 0 ),以下相同)的结果延时4个clk已经到达加法器输入端,乘法器1的结果延时3个clk到达加法器的输入端,正好计算a0xb0+a1xb1(这个时候的加法器的编号应该是( s2 | 0 ));然后在第六个clk的时候,乘法器2的结果经过三个clk到达加法器,乘法器3的结果经过2个clk到达加法器,得到a2xb2+a3xb3(这个加法器编号是( s2 | 1 ));最后就是加法器0的结果经过两个clk到达加法器2,加法器1的结果经过一个clk到达加法器2,计算出最终的结果。
3.最后分析
通过看最后的时序分析,可以发现通过折叠后设计的电路计算效率非常的高,而且如果合理设计控制器的话,用该电路完成一组8x8的向量乘只需要9个clk就可以了。