FFT硬件算法实现
采用FPGA实现FFT算法

采用FPGA实现FFT算法随着数字技术的快速发展,数字信号处理已深入到各个学科领域。
在数字信号处理中,许多算法如相关、滤波、谱估计、卷积等都可通过转化为离散傅立叶变换(DFT)实现,从而为离散信号分析从理论上提供了变换工具。
但DFT计算量大,实现困难。
快速傅立叶(FFT)的提出,大大减少了计算量,从根本上改变了傅立叶变换的地位,成为数字信号处理中的核心技术之一,广泛应用于雷达、观测、跟踪、高速图像处理、保密无线通信和数字通信等领域。
目前,硬件实现FFT算法的方案主要有:通用数字信号处理器(DSP)、FFT专用器件和现场可编程门阵列(FPGA)。
DSP具有纯软件实现的灵活性,适用于流程复杂的算法,如通信系统中信道的编译码、QAM映射等算法。
DSP完成FFT运算需占用大量DSP的运算时间,使整个系统的数据吞吐率降低,同时也无法发挥DSP软件实现的灵活性。
采用FFT专用器件,速度虽能够达到要求。
但其外围电路复杂,可扩展性差,成本昂贵。
随着FPGA发展,其资源丰富,易于组织流水和并行结构,将FFT实时性要求与FPGA器件设计的灵活性相结合,实现并行算法与硬件结构的优化配置,不仅可以提高处理速度,并且具有灵活性高。
开发费用低、开发周期短、升级简单的特点。
针对某OFDM系统中FFT运算的实际需要,提出了基于FPGA的设计来实现FFT算法,并以16位长数据,64点FFT为例,在Quartus Ⅱ软件上通过综合和仿真。
2 FFT原理及算法结构FFT是离散傅立叶变换(DFT)的快速算法。
对于N点离散的有限长时问序列x(n),其傅里叶变换为:完成N点的DFT需要N2次复数乘法和N(N-1)次复数加法。
点数大时,计算量也大,所以难以实现信号的实时处理。
FFT的基本思想是利用旋转因子WN的周期性、对称性、特殊性以及周期N的可互换性,将长度为N点的序列DFT运算逐次分为较短序列的DFT运算,合并相同项,大大减少了计算量。
LTE系统中混合基FFT算法分析与硬件实现

变换结果x[K】以公式(7)为根据对其进行索引变换以保证 得到正确的输出结果。
3.2 FFT处理器硬件实现过程中的关键部分
在LTE系统中,为了满足系统的设计性能,DFT或FFT
变换长度很长,动态范围为12到6144(根据传输块的不同而
有所不同)。如果对一种变换长度进行FFT设计,对另一种 变换长度也进行相同算法的FFT设计,则设计的情况很多.
i2Jr
公式中,%=e‘,N为DFT变换区间长度。
将时域输入信号索引n表示成:
’玎=彳,zl+B也modN』o≤啊≤Ⅳl一1
(1)
【0≤啦≤Ⅳ2—1
此时以N=15点的Cooley-Tukey算法FFT为例,考虑了逆 序重排的分步运算流程图如图1所示
X X X mⅥ≈
X
蚋州啦彤蝌
X
X 习q习
X
X
X q刀叼
盛焉“m彻一o c?mmunications
摘要:在LTE系统设计过程中.上行链路采用单载波频分
多址技术(SC—FDMA),下行链路采用正交频分多址技术
(OFDMA)。在用这两种技术实现LTE的过程中,都采用了
DFT或FFT的处理方法,而直接计算DFT的计算量太大。因
此本文通过对LTE系统中各种FFT算法进行了分析.重点对
此时的输入映射关系为:n=3nl+他』os玛s4 (6)
【0≤也≤2
输出映射关系为:k=k1+5k2 J0_<k1≤4
(7)
【0≤如≤2
二、FFT算法分析
2.1 Cooley-Tukey算法分析 离散傅立叶变换(DFT)将时域信息转换成频域信息。长 度为N的序列x(n)的离散傅立叶变换可写成:
LTE系统中混合基FFT算法分析与硬件实现

LTE系统中混合基FFT算法分析与硬件实现LTE系统是目前移动通信技术中使用最为广泛的一种制式,其核心技术之一就是基于正交频分复用(OFDM)的下行传输技术。
在LTE系统中,传输信号需要经过一系列的信号处理过程,其中包括基于快速傅里叶变换(FFT)的信号处理。
为了提高信号处理的效率和减少硬件复杂度,LTE系统中通常采用混合基FFT算法进行信号处理。
本文将对LTE系统中混合基FFT算法进行分析,并探讨其在硬件实现中的一些关键技术。
一、混合基FFT算法原理及优势混合基FFT算法是将传统的FFT算法与基于二进制分解的FFT算法相结合,通过在频域和时间域中同时进行基变换来实现信号处理。
混合基FFT算法的主要优势包括以下几点:1.减少计算量:传统的FFT算法需要进行复杂的分解和重组操作,计算量较大;而混合基FFT算法通过将基变换分解为不同基数的变换,可以减少计算量,提高算法的效率。
2.降低硬件复杂度:在硬件实现中,传统的FFT算法需要大量的存储器和计算单元来支持复杂的变换操作;而混合基FFT算法则可以通过简化的变换结构来降低硬件复杂度,减少硬件资源的消耗。
3.提高信号处理效率:混合基FFT算法可以同时在频域和时间域中进行基变换,实现信号处理的并行化,从而提高信号处理的效率和速度。
二、混合基FFT算法在LTE系统中的应用在LTE系统中,混合基FFT算法主要应用于下行链路的信号处理过程,包括信号的调制、编码、资源映射等操作。
通过混合基FFT算法,可以实现对下行传输信号的高效处理和快速解调,提高系统的数据传输速率和信号质量。
在LTE系统中,混合基FFT算法通常与信源编码、调制映射等技术结合使用,共同构成了完整的信号处理链路。
通过混合基FFT算法,可以对经过调制映射的信号进行快速变换和解调,实现对传输信号的快速解析和数据提取。
三、混合基FFT算法在硬件实现中的技术要点在LTE系统中,混合基FFT算法的硬件实现需要考虑以下几个关键技术要点:1.变换结构优化:混合基FFT算法的变换结构对算法的性能和硬件复杂度有着重要影响,需要设计优化的变换结构来降低计算量和资源消耗。
FFT 及其Python实现方法

FFT 及其Python实现方法FFT 及其Python实现方法快速傅里叶变换(Fast Fourier Transform,FFT)是一种高效的计算傅里叶变换的算法,广泛应用于信号处理、图像处理、数字滤波等领域。
本文将介绍FFT 的原理及其在Python中的实现方法,以帮助读者更好地理解和应用FFT算法。
一、傅里叶变换简介傅里叶变换是一种将信号从时域转换到频域的数学变换方法,通过将信号分解成不同频率的正弦波和余弦波的和来描述信号的频谱特性。
傅里叶变换的公式为:其中,X(k)表示频域的系数,x(n)表示时域的信号,N表示信号的长度。
二、FFT算法原理FFT算法是一种高效的计算傅里叶变换的算法,其基本思想是将一个N点的DFT(离散傅里叶变换)分解成多个较小规模DFT的和,从而降低计算复杂度。
FFT算法的核心是蝶形运算,通过将原始序列分成两部分,分别进行计算后再合并,从而实现快速的傅里叶变换。
三、Python库介绍在Python中,我们可以使用NumPy库来实现FFT。
NumPy是一个科学计算的基础库,提供了丰富的数学函数和数组操作工具,可以方便地进行FFT 计算。
四、FFT的Python实现步骤导入必要的库在使用NumPy实现FFT之前,我们需要导入相应的库,并加载我们要处理的信号。
以下是导入库和加载信号的示例代码:import numpy as npimport matplotlib.pyplot as plt# 加载示例信号t = np.arange(0, 1, 0.01)signal = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 10 * t) + np.random.randn(len(t))进行FFT计算在Python中,我们可以使用NumPy库中的numpy.fft.fft函数来实现FFT 计算。
以下是一个进行FFT计算的示例代码:# 进行FFT计算fft_result = np.fft.fft(signal)使用np.fft.fft函数,我们将信号作为输入,得到其FFT计算的结果。
FFT算法实现

C#实现FFT算法专业:通信与信息系统学号:姓名:2014年11月一、设计原理FFT 算法就是不断把长序列的DFT 分解成几个短序列的DFT ,利用上述周期性和对称性来减少DFT 的运算次数. FFT 算法基本上分为两大类:(1)时域抽取法FFT(Decimation In Time FFT,简称DIT —FFT). (2)频域抽取法FFT(Decimation In Frequency FFT,简称DIF —FFT). 时域抽取基2FFT 算法原理设输入序列长为N=2M(M 为正整数),将该序列按时间顺序的奇偶分解为越来越短的子序列,称为基2按时间抽取的FFT 算法。
若序列长度不满足条件N=2M ,可以加零补长使其达到 N=2M 。
算法步骤:第一步分组和变量置换:12,,1,0)()12(12)()2(2)(1,,1,0)()(2110-==+⇒+=⇒==⇒=⇒=-==∑-=Nr r x r x r n n r x r x r n n n x N k W n x k X N n nk N 其中令奇数令偶数按奇偶分成两组:将,第二步代入DFT 定义式:12,,1,0)()()()()12()2()]([)]([)(212/0212/021)12(12/012/0221-=⋅+⋅=⋅++⋅=+=∑∑∑∑-=-=+-=-=N r W Wr x Wr x Wr x Wr x r x DFT r x DFT k X kNrk N N r N r rk Nk r NN r N r rk N其中第三步求子序列的DFT蝶形图如下:CABA + BCA - BC频域抽取基2FFT 算法原理设输入序列长度为N=2M(M 为正整数),将该序列的频域输出序列X(k)按其频域顺序的奇偶分解为越来越短的子序列,称基2按频率抽取FFT 算法。
若序列长度不满足条件N=2M ,可以加零补长使其达到 N=2M 。
算法步骤:第一步分组:12,,1,0)2(12,,1,0)()()(1,,0)()(10-=+-=⇔-==∑-=Nn N n x Nn n x n x k X N k W n x k X N n nk N 后半部分:前半部分:按前后分为两部分:奇偶分组,第二步代入DFT 定义式nkNk NN N n N n kNn N Nn nk NkNn N N n nk NN n nk NW W N n x n x W N n x Wn x W N n x Wn x Wn x k X ])2()([)2()(])2()([)()(21212)2(120)2(12010++=++=++==∑∑∑∑∑-=-=+-=+-=-=第三步变量置换16,4,2,0)]2()([)(12,1,0''2112/02-=⋅++=∴-===∑-=N k W N n x n x k X N k k k Wnk N N n k N N其中:,,令蝶形运算符号:二、设计方案using System;using System.Collections.Generic; using System.Linq; using System.Text; namespace MyFFT {class Program {static void Main(string[] args) ///程序入口{const int N=128; ///定义序列最大长度,可根据需要修改Complex[] W = new Complex[N]; ///定义旋转因子Complex[] signal = new Complex[N]; ///定义序列FFT fft = new FFT(); ///定义fft 类fft.SIZE=Convert.ToInt32(Console.ReadLine());for (int i = 0; i < fft.SIZE; i++) {W[i] = new Complex(); ///初始化旋转因子signal[i] = new Complex(); ///初始化序列}fft.ShowInputMessage(signal); ///人机接口fft.initW(W); ///计算旋转因子 Console.Write("正变换FFT 请按0,逆变换IFFT 请按1:");fft.Model = Convert.ToInt32(Console.ReadLine()); if (fft.Model == 0)fft.DoFFT(W, signal);else if (fft.Model == 1)fft.DoIFFT(W,signal);Console.WriteLine("输出例如下:");fft.ShowResult(signal); ///输出变换后的序列结果Console.ReadLine();}}}namespace Fengfeng.He{///定义复数类Complex///成员:Re Imclass Complex{public double Re; ///复数实部public double Im; ///复数虚部public Complex() ///构造函数{}public Complex(double Re, double Im) ///带参的构造函数重载{this.Re = Re;this.Im = Im;}///运算符重载+号public static Complex operator +(Complex c1, Complex c2){return new Complex(c1.Re + c2.Re, c1.Im + c2.Im);}///运算符重载-号public static Complex operator -(Complex c1, Complex c2){return new Complex(c1.Re - c2.Re, c1.Im - c2.Im);}///运算符重载*号public static Complex operator *(Complex c1, Complex c2){return new Complex(c1.Re * c2.Re - c1.Im * c2.Im, c1.Re * c2.Im + c1.Im * c2.Re);}///运算符重载/号public static Complex operator /(Complex c1, Complex c2){// return new Complex(((c1.Re*c2.Re+c1.Im*c2.Im)/(c2.Re*c2.Re+c2.Im*c2.Im)),(c1. Im*c2.Re-c1.Re*c2.Im)/c2.Re*c2.Re+c2.Im*c2.Im);Complex c = new Complex();c.Re = (c1.Re * c2.Re + c1.Im * c2.Im) / (c2.Re * c2.Re + c2.Im * c2.Im);c.Im = (c1.Im * c2.Re - c1.Re * c2.Im) / (c2.Re * c2.Re + c2.Im * c2.Im);return c;}};/// <summary>/// 定义FFT类/// 成员函数:/// 1、ReverseOder()倒序变换/// 2、DoFFT()FFT变换/// 3、DoIFFT()IFFT变换/// 4、W()旋转因子计算/// </summary>class FFT{public int SIZE = 0; ///序列长度public int Model; ///变换模式private double PI = Math.Atan(1) * 4;// private double PI = 3.14159;public void ReverseOder(Complex[] x){Complex temp;int i = 0, j = 0, k = 0;double t;for (i = 0; i < SIZE; i++){k = i; j = 0;t = Math.Log(SIZE, 2);while ((t--) > 0){j = j << 1;j |= (k & 1);k = k >> 1;}if (j > i){temp = x[i];x[i] = x[j];x[j] = temp;}}}/// <summary>/// 倒序函数/// W:输入旋转因子序列数组名/// </summary>public void initW(Complex[] W){int i;#if DEBUGfor (i = 0; i < SIZE; i++){Console.WriteLine("DEBUG->W{0}+j{1}", W[i].Re, W[i].Im);}#endiffor (i = 0; i < SIZE; i++){W[i].Re = Math.Cos(2 * PI * i / SIZE); //旋转因子实部展开W[i].Im = -1 * Math.Sin(2 * PI * i / SIZE); //旋转因子虚部展开}#if DEBUGfor (i = 0; i < SIZE; i++){Console.WriteLine("DEBUG->WW{0}+j{1}",W[i].Re, W[i].Im);}#endif}public void DoFFT(Complex[] W, Complex[] x){int i = 0, j = 0, k = 0, l = 0;Complex up, down, product;ReverseOder(x); ///对输入序列进行倒序#if DEBUGfor (i = 0; i < SIZE; i++){Console.WriteLine("DEBUG->{0}+j{1}", x[i].Re, x[i].Im);}#endiffor (i = 0; i < Math.Log(SIZE, 2); i++) ///外循环,变换级数循环{l = 1 << i;for (j = 0; j < SIZE; j += 2 * l) ///中间循环,旋转因子循环{for (k = 0; k < l; k++) ///内循环,序列循环{product = x[j + k + l] * W[SIZE * k / 2 / l];up = x[j + k] + product;down = x[j + k] - product;x[j + k] = up;x[j + k + l] = down;}}}#if DEBUGfor (i = 0; i < SIZE; i++){Console.WriteLine("DEBUG->fft:{0}+j{1}", x[i].Re, x[i].Im);}#endif}public void DoIFFT(Complex[] W, Complex[] x){int i = 0, j = 0, k = 0, l = SIZE;Complex up, down;for (i = 0; i < Convert.ToInt32((Math.Log(SIZE, 2))); i++) ///外循环,级数循环{l /= 2;for (j = 0; j < SIZE; j += 2 * l) ///中间循环,旋转因子循环{for (k = 0; k < l; k++) ///内循环,序例循环{up = x[j + k] + x[j + k + l];up.Re /= 2; up.Im /= 2;down = x[j + k] - x[j + k + l];down.Re /= 2; down.Im /= 2;down = down / W[SIZE * k / 2 / l];x[j + k] = up;x[j + k + l] = down;}}}ReverseOder(x); ///倒序还原}public void ShowResult(Complex []signal){for (int i = 0; i < SIZE; i++){Console.Write("{0}", signal[i].Re);if (signal[i].Im > 0.00001) ///定义精度Console.WriteLine(" + {0}i", signal[i].Im);else if (Math.Abs(signal[i].Im) > 0.00001)Console.WriteLine(" {0}i", signal[i].Im);elseConsole.WriteLine();}}public void ShowInputMessage(Complex []signal){///人机接口,命令提示行for (int i = 0; i < SIZE; i++){三、仿真结果。
基于FPGA的FFT算法硬件实现

基于FPGA的FFT算法硬件实现引言:FFT是一种用于将时域信号转换为频域信号的算法,常用于信号处理和图像处理领域。
由于FFT的高计算复杂度,硬件实现可以提供更高的计算效率和并行处理能力。
本文将介绍基于FPGA的FFT算法硬件实现,并详细解释算法的原理和实现过程。
一、快速傅里叶变换(FFT)算法简介快速傅里叶变换(FFT)是一种将一个N点离散序列转换为频域离散序列的算法。
它的时间复杂度为O(NlogN),相比于传统的傅里叶变换算法的时间复杂度O(N^2),FFT算法具有更高的计算效率。
FFT算法的核心思想是将一个N点离散序列划分为其各个子序列,然后再分别计算各个子序列的傅里叶变换,并将结果通过一系列的蝶形运算合并得到最终的频域信号。
二、FFT算法的硬件实现原理基于FPGA的FFT算法实现可以充分发挥FPGA的并行计算能力和灵活性。
硬件实现的核心是设计一个包含多个计算单元的并行处理模块。
常见的FFT硬件实现架构包括基于蝶形运算的位递归FFT算法和基于矩阵运算的线性变换FFT算法。
1.基于蝶形运算的位递归FFT算法实现首先将输入序列分为奇数位和偶数位两个子序列,然后分别对这两个子序列进行FFT计算。
然后将得到的结果通过蝶形运算合并得到最终的频域信号。
在硬件实现中,可以设计一个包含多个蝶形运算单元的并行计算模块。
每个蝶形运算单元包括两个输入通道和两个输出通道,通过并行计算可以同时进行多个蝶形运算操作,提高计算效率。
2.基于矩阵运算的线性变换FFT算法实现线性变换FFT算法将FFT计算表示为矩阵运算的形式,可以充分利用FPGA的向量计算能力。
这种实现方法将输入序列表示为一个复数矢量,然后通过矩阵运算得到最终的频域信号。
在硬件实现中,可以设计一个包含多个矩阵运算单元的并行计算模块。
每个矩阵运算单元可以同时对多个输入进行矩阵运算,提高计算效率。
三、基于FPGA的FFT算法硬件实现步骤1.硬件资源规划:根据需要计算的样本点数N,确定所需的FPGA资源,包括DSP片上资源、BRAM资源和IO资源等。
fft算法c语言实现

fft算法c语言实现快速傅里叶变换(FFT)是一种高效的离散傅里叶变换算法,用于计算信号在频域的表示。
下面是一个简单的使用 C 语言实现的 FFT 算法示例,它可以用于对输入的时域信号进行离散傅里叶变换。
```c#include <stdio.h>#include <stdlib.h>#include <math.h>#define N 16// 复数结构体typedef struct {double real;double imag;} Complex;// 初始化复数void initComplex(Complex *c, double real, double imag) {c->real = real;c->imag = imag;}// FFT 算法void fft(Complex *c, int n) {int i, j, k;Complex w, u, v;// 层次遍历for (i = 1; i < n; i <<= 1) {// 旋转因子w.real = cos(2 * M_PI * i / n);w.imag = -sin(2 * M_PI * i / n);for (j = 0; j < n; j += i) {for (k = 0; k < i / 2; k++) {u.real = c[j + k].real;u.imag = c[j + k].imag;v.real = c[j + i / 2 + k].real;v.imag = c[j + i / 2 + k].imag;c[j + k].real = u.real + w.real * v.real - w.imag * v.imag; c[j + k].imag = u.imag + w.real * v.imag + w.imag * v.real; c[j + i / 2 + k].real = u.real - w.real * v.real + w.imag * v.imag; c[j + i / 2 + k].imag = u.imag - w.real * v.imag - w.imag * v.real; }}}}// 打印复数void printComplex(Complex c) {printf("%f + %fi\n", c.real, c.imag);}int main() {Complex c[N];// 输入的时域信号for (int i = 0; i < N; i++) {c[i].real = rand() / RAND_MAX;c[i].imag = rand() / RAND_MAX;}printf("输入的时域信号:\n");// 打印输入的时域信号for (int i = 0; i < N; i++) {printComplex(c[i]);}fft(c, N);printf("经过 FFT 变换后的频域信号:\n");// 打印经过 FFT 变换后的频域信号for (int i = 0; i < N; i++) {printComplex(c[i]);}return 0;}```上述代码是一个简单的 C 语言实现的 FFT 算法示例。
FFT算法设计与实现

FFT算法设计与实现FFT(快速傅里叶变换)是一种高效的算法,用于计算离散傅里叶变换(DFT)。
DFT是一种将时域信号转换为频域信号的方法,常用于信号处理、图像压缩、通信系统等领域。
由于DFT计算复杂度为O(n^2),在处理大规模数据时效率较低。
而FFT算法通过巧妙地利用对称性和旋转因子,将计算复杂度降低到O(nlogn),大大提高了计算效率。
FFT算法的设计思想基于分治策略。
它将DFT分解为两个较小规模的DFT的和,然后通过迭代地递归计算这两个较小规模的DFT,最终得到完整的DFT结果。
这个分解过程可以通过二叉树的方式来表示,每个节点代表一个规模较小的DFT计算。
在计算过程中,FFT算法利用了频率域的对称性质,将计算任务分为偶数项和奇数项,从而减少了重复计算。
FFT算法的实现可以通过递归和迭代两种方式。
递归实现是基于分治策略,它将DFT的计算过程逐步分解为规模较小的DFT计算,直到规模最小时可以直接计算出结果。
然后通过合并计算得到较大规模的DFT结果,最终得到完整的DFT结果。
迭代实现则是基于迭代式DFT公式,通过不断地将n点DFT计算转化为两个n/2点DFT计算的和差形式,直到规模最小再直接计算。
在实际使用中,常用的FFT算法有Cooley-Tukey算法和Winograd算法。
Cooley-Tukey算法是最常用的FFT算法,在计算过程中将DFT的长度N分解为N/2长度的连续两个子问题,通过迭代地计算这些子问题来得到结果。
Winograd算法则是一种更高效的算法,它通过减少旋转因子的计算次数和乘法运算的次数,进一步提高了计算效率。
FFT算法的实现还需要考虑数值稳定性和误差控制。
由于涉及到浮点数的计算,存在舍入误差和截断误差问题。
为了避免这些问题带来的误差累积,需要采用一些数值稳定的算法和误差控制技术,如使用双精度浮点数计算、控制截断误差和舍入误差等。
综上所述,FFT算法是一种高效的计算DFT的算法,通过分治策略和对称性的利用,将计算复杂度降低到O(nlogn)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
������������ ,其中 ������������ = ������ −������
(1)
应用 3 维线性索引映射,令
N N n1 2 n2 n3 N 2 2 (2) 2 k k1 2k2 2 k3 N n
k1 , k2 0,1, k3 0,1...( 1); 其中 n1 , n2 0,1, n3 0,1...( 1),
号流图。一个 N 16 的信号流图如下:
x(0) x(1) x(2) x(3) x(4) x(5) x(6) x(7) x(8) x(9) x(10) x(11) x(12) x(13) x(14) x(15) x(0) N/4 N/4 DFT DFT (k1=0,k2=0) (k1=0,k2=0)
( 1 )蝶形单元工作同步控制信号 t,s ( 2 )旋转因子地址信号 (3) 每级的旁路控制信号 4.复数乘法器的设计 普通复数乘需要 4 个乘法器: y= xreal + ximag ∗ ������������������������ + ������������������������������ = xreal ������������������������ − ximag ������������������������ + ������(xreal ������������������������ − ximag ������������������������) 为了节省乘法器,可以采用下面的公式并采用流水线结构,这样增加了 3 个加法器而 减少了一个乘法器。 y real = xreal + ximag ������������������������ + ximag (−������������������������ − ������������������������ ) y imag = xreal + ximag ������������������������ + xreal (������������������������ − ������������������������ ) 5.旋转因子的存储和取址设计 级 数 M FFT 点数 N 16 32 64 128 256 512 1024 2048 W 16[0…3] W 32[0…7] W 64[0…15] W 128[0…31] W 256[0…63] W 512[0…127] W 1024[0…255] W 2048[0…511] W 4[0] W 8[0…1] W 16[0…3] W 32[0…7] W 64[0…15] W 128[0…31] W 256[0…63] W 512[0…127] W 4[0] W 8[0…1] W 16[0…3] W 32[0…7] W 64[0…15] W 128[0…31] W 4[0] W 8[0…1] W 16[0…3] W 32[0…7] W 4[0] W 8[0…1] 1 1 2 3 M 4 5 M 6 7 M 8 9 M 10 11 M
BF2II
x ( n)
CLK
7 6
W 1(n)
BF2I
BF2II
W 2(n)
BF2I
BF2II
W 3(n)
BF2I
BF2II
X (k )
1 0
5
4
3
2
需要考虑的问题: 1.蝶形单元的设计
xr (n)
0 1 0 1 1 0 1 0 s
Z r (n N / 2)
xi (n)
Z i (n N / 2)
FFT 硬件算法实现
本文给出 FFT 算法的数学推导,基 22 SDF 流水线 FFT 的实现结构,以及一些需要注意 的问题。
1.数学推导
N 点 DFT 定义为:
nk X k xnWN , k 0,1...N 1 n 0 N 1
2 ������������������ ������
则( 1 4k3 )
N /4 1 1 n3 0
N N ( n1 n2 n3 )( k1 2 k2 4 k3 ) N N 2 x( 2 n1 4 n2 n3 )WN 4 n2 0 n1 0 1 N N ( n2 n3 ) k1 ( n2 n3 )(2 k2 4 k3 ) N n2 n3 )WN 4 }WN 4 4
BF 1 BF 1 N N 3N k1 ( k1 2 k2 ) k1 H (k1 , k2 , n3 ) [ x(n3 ) (1) x(n3 )] ( j ) [ x( n3 ) ( 1) x( n3 )] 2 4 4 BF 2 (7) 公式 (7)
代表了前 2 级蝶形运算,我们把乘 ( j ) 称为无关紧要的乘法,因为它不需要复数乘法器, 而只需要对输入复数实部和虚部进行交换和取反操作。经过两级蝶形运算后,才需要复数 乘法器进行与旋转因子 WN 3 对长 N
n ( k1 2 k2 )
的复数乘法操作。
4
点的 DFT 递归的应用以上过程,我们便可以得到完整的基 2 2 SDF FFT 的信
xr (n N / 2)
xi (n N / 2)
Z r ( n)
Z i ( n)
BF1结构
对于 BF1, 在前 N/2 个时钟周期,2 选 1 选择器选在位置“ 0 ”,因此蝶形运算单元是空 闲的。 输入数据直接进入 N/2 延时寄存器。 待到延时寄存器为满时, 即后 N/2 个时钟周期, 2 选 1 选择器选在位置“ 1 ”,蝶形运算单元开始对输入数据和 N/2 延时寄存器中存储的值 进行 2 点 DFT 计算,即 Z1(n)=x(n)+x(n+N/2) 0 <= n < N/2 Z1(n+N/2)=x(n)-x(n+N/2)0<=n<N/2 把蝶形运算的输出 Z1(n) 送入第 2 级蝶形运算单元,同时把 Z1(n+N/2) 送回 N/2 延时寄 存器,这是与下一组 FFT 数据的前 N/2 个数据的载入是同时的。实际上这一操作把并行的 蝶形数据又变为串行 ( 单路延时反馈转接 ,SDF) ,如果两路同时进行 , 则方法变为多路延迟转 接结构(多路延时转接 ,MDC ) .
这是第一个蝶形运算结构,记为 BF1 。
我们现在对旋转因子做进一步分解,
WN 4
(
N
n2 n3 )( k1 2 k2 4 k3 )
WNNn2 k3WN4
N
n2 ( k1 2 k2 )
WNn3 ( k1 2 k2 )WN4 n3k3
4 n3 k3 ( j ) n2 ( k1 2 k2 ) WNn3 ( k1 2 k2 )WN
N点FFT 数据
x1 (n)
x1 (n N / 2)
x2 (n)
x2 (n N / 2)
N / 2 寄存器
BF1输出
x1 (n)
Z1 (n)
x2 (n)
Z1 (n N / 2)
N / 2 寄存器
N' N / 2
Z1 (n)
Z1 (n N ' / 2)
Z1 (n N / 2)
Z 2 ( n)
Z 2 (n N ' / 2)
第N 级 第N+1级
Z1 (n)
Z 2 ( n)
BF2输出 乘旋转因子延迟
Z1 (n)
Z1 (n N / 2)
'
乘(-j)
2.移位寄存器的设计 ( 1 ) D 触发器组 ( 2 )简单双端口 RAM (需要读写控制信号,地址产生器,资源中等) ( 3 )基于 RAM 的移位寄存器(移位位数是 3 的整数倍,所以对于 N/2 点需要再加 D 触发器,资源较少) ( 4 )基于 RAM 的 FIFO (需要读写控制信号 , 本身会输出一些指示信号,可能利用起 来比较方便,但资源增多) 3.控制信号的设计
N /4 1 1
n3 0 n2 0
k1 ( {BN 2
n3 原理:X(k)= ( x(n3 )WN x(n3 n3 0 N 1 4
N 1 4
N n3 N N N n3 N N )WN 4 x(n3 )WN 4 2 ) 4 4 2
(3)
n3 0 n2 0 n1 0
j j j j
W0
W3
W6
N/4 N/4 DFT DFT (k1=1,k2=1) (k1=1,k2=1)
W9
图 N 16 的信号流图
2.基 22 SDF 流水线 FFT 实现结构
一个 256 点的 2 2 SDF FFT 的实现结构如下:
128 64 32 16 8 4 2 1
BF2I
W
0
x(8) x(4) x(12) x(2) x(10) x(6) x(14) x(1) x(9) x(5) x(13) x(3) x(11) x(7) x(15)
W2
W4
W6
W
0
N/4 N/4 DFT DFT (k1=0,k2=1) (k1=0,k2=1)
W1
W
W
2
3
N/4 N/4 DFT DFT (k1=1,k2=0) (k1=1,k2=0)
注意:这里的旋转因子还未乘以 [0 2 1 3], 即对于 2048 点 W 2048[0…511] ,真正需要的旋
mn 转因子为 ������2048 , n = 0, 1 … 511, m = 0,2,1,3。 ������ ������������ 由 ������������ = ������������������ 可知, N / 2 点 FFT 的旋转因子是由 N 点 FFT 的旋转因子抽取得到的。 mn 即 2048 点 FFT 的旋转因子 ������2048 包含了其它点数的旋转因子。通过恰当的存储设计和地址