基于FPGA的FFT设计

一、前言。

频域,更利于分析信号的成分,如:基波、谐波。在示波器、频谱仪中,经常用到频谱图。

DFT和FFT都是时域变换到频域的工具,DFT适用于任意点数,而FFT一般是偶数点(基2、基4、分裂基等)而且速度更快。

二、方案。

由于FFT是统一处理若干个点,也就是若干个数据,所以先把数据缓存起来,计算好再输出。

这里使用了两块RAM做输入、输出缓存器。

蝶形运算主要由复数乘法器和复数加/减法器构成,其中复数乘法器可以由3个实数乘法器实现。

旋转因子可以先扩大再存入ROM中,计算完成后,再缩小。

主控状态机,就负责协调其它模块的运作。

三、输入RAM缓存。

将输入的数据按顺序缓存到RAM中,然后倒位序取出。倒位序只需要将地址镜像一下就好了,如下图所示。

由于写入的数据是从0到31(地址和数据相同),所以取出时原本是1的数据,变为16,如下图所示。(单独写成一个文件,为了方便以后扩展为不同的接口)

四、旋转因子ROM。

旋转因子可以先用Matlab生成,保存为mif或者coe格式。代码如下:

clear;
clc;

N=16;    %点数
A=16;    %旋转因子的位宽
mif_en=1; %设为1,则输出mif文件
coe_en=1; %设为1,则输出coe文件

%输出无符号数
if(mif_en)
    fid=fopen('wn.mif','w+');
    fprintf(fid,'DEPTH = %d;\n',N);
    fprintf(fid,'WIDTH = %d;\n',2*A);   %一个地址同时存实数和虚数,高位实数,低位虚数
    fprintf(fid,'ADDRESS_RAIDX = HEX;\n');
    fprintf(fid,'DATA_RADIX = HEX;\n');
    fprintf(fid,'CONTENT\nBEGIN\n');
    for n=0:(N-1)
        W_real=round(cos((2*pi*n)/N)*(2^A/2-1))+2^A/2; %无符号数
        W_imag=round(sin((-2*pi*n)/N)*(2^A/2-1))+2^A/2; %无符号数
        W_real_hex=dec2hex(W_real);
        W_imag_hex=dec2hex(W_imag);   
        fprintf(fid,'%s : %04s%04s;\n',dec2hex(n),W_real_hex,W_imag_hex); % %04需要按照位宽设定
    end
    fprintf(fid,'END ;\n');
    fclose(fid);
end

if(coe_en)
    fid=fopen('wn.coe','w+');
    fprintf(fid,'MEMORY_INITIALIZATION_RADIX=16;\nMEMORY_INITIALIZATION_VECTOR=');
    %一个地址同时存实数和虚数,高位实数,低位虚数
    for n=0:(N-1)
        W_real=round(cos((2*pi*n)/N)*(2^A/2-1))+2^A/2;%无符号数
        W_imag=round(sin((-2*pi*n)/N)*(2^A/2-1))+2^A/2;%无符号数
        W_real_hex=dec2hex(W_real);
        W_imag_hex=dec2hex(W_imag); 
        fprintf(fid,'%04s%04s',W_real_hex,W_imag_hex); % %04需要按照位宽设定
        if(n==(N-1))
            fprintf(fid,';');
        else
            fprintf(fid,',');
        end
    end
    fclose(fid);
end

在quartus中打开mif文件,如下图所示:

然后再另存为hex格式,就可以在modelsim中仿真了。

旋转因子的仿真较为简单,直接读取ROM的内容即可(单独写成一个文件,为了方便以后扩展为cordic算法)。

五、复数乘法。

复数乘法,可以使用以下公式进行简化。

(a+b*j) * (c+d*j) = I+Q*j
I=(a-b)*d + (c-d)*a
Q=(a-b)*d + (c+d)*b

I、Q中的(a-b)*d是相同的,可以少用一个乘法器。

所以,一个复数乘法器,可由三个实数乘法器和五个实数加法器(减法也能用加法器来实现)组成。

那么实数乘法,可以使用布斯乘法器来算补码乘法(如下图所示)。

复数乘法可以与复数乘法在线计算器进行对照,如下图所示。

六、蝶形运算。

蝶形运算的计算公式如下图所示,均使用复数计算。

其中蝶形运算可以用matlab来验证计算是否正确。

clear all; clc;

xn1 = 2 + 5i;
xn2 = 4 + 8i;
wn  = 6 + 9i;

Xn1 = xn1 + xn2*wn
Xn2 = xn1 - xn2*wn

最终计算结果如下图所示。

七、输出RAM缓存。

与输入缓存类似,输出缓存不需要倒位序,所以输出的数据与输入的数据相同,如下图所示。(单独写成一个文件,为了方便以后扩展为不同的接口)

八、主控状态机。

九、FFT仿真结果。

 

十、其它问题。

1、在线傅立叶计算

 

  • 12
    点赞
  • 127
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值