fft的vhdl实现

  • 所谓的FDRSE就是带同步复位置位时钟使能的d触发器。可以用来做多路数据稳定对齐。

N点基-2 FFT算法的实现方法(http://blog.163.com/tianyake@yeah/blog/static/749331412010979109623/)

从图4我们可以总结出对于点数为N=2^L的DFT快速计算方法的流程:

   0.旋转因子存储问题

由于WN的对称特性,第二象限为第一象限的实部取反,第三象限为虚实皆取反,第四象限为虚部取反,所以只需要存储第一象限即可,而且由于可约性,后几级旋转皆可以由第一级变换得到。

   1.对于输入数据序列进行倒位序变换。

该变换的目的是使输出能够得到X(0)~X(N-1)的顺序序列,同样以8点DFT为例,该变换将顺序输入序列x(0)~x(7)变为如图4的x(0),x(4),x(2),x(6),x(1),x(5),x(3),x(7)序列。(此处倒位序实际上是二进制坐标翻转即可,原因与fft的基2有关,若为基4则为四进制的翻转

 3.浮点到定点转换需要注意的关键问题
事实上大多嵌入式系统中进行离散傅里叶变换一般都应该采用定点方式。对于使用蝶形运算的fft我们不能采用这种简单的放大旋转因子转为整数计算的方式。因为fft是一个非对称迭代过程,假设我们对旋转因子进行了放大,根据蝶形流图我们可以发现其最终的结果是,不同的输入被放大了不同的倍数,对于第一个输入x(0)永远也不会放大。举一个更加形象的例子,还是以图4为例。从图中可以看出右侧的X(0)可以直接用下式表示:

FFT原理与实现 - kanku - kanku的博客


从上式我们可以看到不同输入项所乘的旋转因子个数(注意这里是个数,就算是wn^0,也被考虑进去了,因为在没有放大时wn^0等于1,放大后所有旋转因子指数模均不为1,因此需要考虑)。这就导致输入不平衡,运算结果不正确。经查阅相关资料,比较妥善的做法是,首先对所有旋转因子都放大2^Q倍,Q必须要大于等于L,以保证不同旋转因子的差异化。旋转因子放大,为了保证其模为1,在每一次蝶形运算的乘积运算中我们需要将结果右移Q位来抵消这个放大,从而得到正确的结果。之所以采用放大倍数必须是2的整数次幂的原因也在于此,我们之后可以通过简单的右移位运算将之前的放大抵消,而右移位又代替了除法运算,大大节省了时间。

  4.计算过程中的溢出问题
最后需要注意的一个问题就是计算过程中的溢出问题。在实际应用中,AD虽然有12位的位宽,但是采样得到的信号可能较小,例如可能在0~8之间波动,也就是说实际可能只有3位的情况。这种情况下为了在计算过程中不丢失信息,一般都需要先将输入数据左移P位进行放大处理,数据放大可能会导致溢出,从而使计算错误,而溢出的极限情况是这样:假设我们数据位宽为D位(不包括符号位),AD采样位数B位,数字放大倍数P位,旋转因此放大倍数Q位,FFT级联运算带来的最大累加倍数L位。我们得到:

FFT原理与实现 - kanku - kanku的博客
假设AD位宽12,数据位宽32,符号位1位,因此有效位宽31位,采样点数N,那么我们可以得到log2(N)+P+Q<=19,假设点数128,又Q>=L可以得到放大倍数P<=5。
即放大倍数P<=数据有效位宽-log2(采样点数)-AD采样位宽-旋转因子放大倍数(因为定点运算,Q>=log2(采样点数)),其中log2(采样点数)表示级联运算最大累加倍数,因为每一级最多累加后多一位。

猜你喜欢

转载自www.cnblogs.com/ryekeey/p/9242698.html