1 设计与实现
本设计为128点FFT,采用简单实用的基2时间抽取(DIT)算法。该模块的FFT处理共需3个过程,即外部数据倒序输入过程,FFT中间运算过程(128点的FFT运算可分解成7级运算,每级64个基2蝶形运算)和运算结果正序输出过程。整个FFT模块内部结构简图如图2所示。该FFT模块主要包括蝶形运算单元、控制单元和存储单元(ROM和双口RAM)。
1.1 蝶形运算单元
基2时间抽取蝶形运算信号流图如图3所示。
其中,括号内的p和q表示数据的序号;xm(p),xm(q)是第m级蝶形运算的输入, 为相应的旋转因子,xm+1(p),xm+1(q)是该蝶形运算的输出。其算法可表示为:
由上述公式可以看出,一个基2蝶形运算要进行1次复乘、2次复加。若在一个时钟周期内完成复乘,则需要4个实数乘法器和2个实数加法器。因为一个蝶形运算需要取两个输入数据,而只存在1次复乘,所以可以用2个时钟周期来完成1次复乘,即可以对实数乘法器进行复用,从而减少乘法器的数目同时不降低处理速度。
改进后的基2蝶形运算单元充分利用了FPGA片内的寄存器,采用流水和并行的结构将复乘所需的4个实数乘法器减少到2个,其逻辑结构如图4。从中可以看出,蝶形运算单元主要由寄存器、选择器、乘法器和加法器构成。左边3个选择器用来选择做乘法的数据,右边2个选择器用来选择加法器的加减功能。
该蝶形运算单元中的复乘运算是2个8比特的复数相乘得到15比特的复数。因为输入数据和旋转因子的8比特数据实际上表征的是模值不大于“1”的复小数,所以复乘运算的输出结果用15比特表示并不会产生溢出。2个15比特的数据进行复加运算得到16比特的结果。为便于下一级运算,将复加运算输出的16比特数据截掉低8位(采用定点四舍五人的方法以减小误差)。128点FFT的7级运算中每一级的数据都相当于先左移了7位(旋转因子的模值为128),而后又截掉了低8位,所以每一级都相当于做了除2运算,故此128点FFT输出结果是理论值的(1/2)7。
1.2 控制单元
控制单元是整个FFT模块的核心。主要有以下两个功能:
1)提供各个模块的运算使能。
当检测到输入口的FFT_start信号后,立即开始接收数据,并反序存储到RAM中。在128个时钟周期之后,启动各级的蝶形运算,并同时产生RAM的读写使能信号。在第7级运算结束时,提供数据输出的标志FFT_done,并控制RAM 同步正序输出数据。
2)产生各级运算所需的地址
产生FFT输入的倒序地址和输出的正序地址(正序和倒序均用同步计数器实现,正序为当前计数器的输出,倒序为当前计数器的高位与低位的对应位全部对调后的输出);各级运算的地址(按照计数器的输出,根据各级蝶形运算的规律产生。先产生蝶形运算第一个数据的RAM地址,再产生第二个数据的RAM地址;在产生以上两个取数地址的同时,产生所对应的旋转因子的ROM取数地址)。
1.3 存储单元
该FFT模块中的存储单元(ROM和双口RAM)由Xilinx ISE 6.2i的CORE Generator工具根据FPGA的型号生成。
本FFT设计中有2个ROM分别用来存储旋转因子,并以补码的形式将它们按照*.mif格式文件输出。用工具例化ROM,将*.mif文件写入各自的ROM初始化文件中,完成对ROM的初始化。
通常的FFT设计采用的是有2块(按实、虚部分开算是4块)RAM的“乒乓”式结构,而在处理速度要求不太高的情况下,可以采用1块(按实、虚部分开算是2块)RAM来完成,进而节省RAM资源,便于以后的ASIC开发。在此FFT模块的设计中,有2个分别用来存储数据实部和虚部的双口RAM(端口a只写,端口b只读)。RAM的两端口可以在读写地址不同的情况下同时工作,即在通过端口b从RAM中读取蝶形运算数据的同时,也在通过端口a往RAM 中写入上几次蝶形运算的结果。
2 仿真与分析
采用Verilog HDL对所设计的FFT模块进行RTL描述。FFT处理点数为128,输入输出用8比特补码表示。采用MoldSim SE 5.8a对整个设计进行功能仿真,采用Synplify Pro 7.3.3进行综合;使用Xilinx的ISE 6.2i工具配置比特流下载;FPGA选用Xilinx Spartan II系列中的xc2s200pq208-5。用MoldSim进行仿真的局部时序如图5所示。
将MATLAB的计算结果与FPGA的仿真结果进行对比,如图6所示。可见两组结果能较好地吻合,从而验证了所设计的FFT模块的正确性。
整个FFT模块在Spartan II的xc2s200pq208-5上共用去逻辑单元(LUTs)393,占总资源的8%,这样就为OFDM系统其他模块的设计节省了大量资源。
128点FFT需要完成蝶形运算 (128/2)×log2128=448次,每个蝶形运算需要2个时钟周期,蝶形运算需要7个时钟周期的延时,收发外部数据需要128×2=256个时钟周期,所以整个FFT运算共需要时钟周期448×2+7+256=1159个,在处理速度上达到了预期的目标。
3 结论
本文中设计的FFT模块采用基2时间抽取算法,用verilog HDL对其进行了RTL描述,用MoldSim和Synplify工具进行了仿真和综合,并在Xilinx Spartan II FPGA中进行了验证。
此外,FFT运算结果的精度与输入数据的位数及运算过程中的位数有关。在定点计算中,存储器数据的位数越大,运算精度越高,使用的存储单元和逻辑单元也越多。在OFDM系统的实际应用中,可以根据实际情况折衷选择FFT模块的精度和资源。
本文所设计的FFT模块的输入、输出和旋转因子为8比特数据,采用了1块(按实、虚部分开算是2块)双口RAM和基2单蝶形流水运算的结构,达到了某些OFDM系统对FFT模块的精度和资源的要求,为OFDM系统的ASIC的开发提供了很好的依据。
文章评论(0条评论)
登录后参与讨论