一、前言。
频域,更利于分析信号的成分,如:基波、谐波。在示波器、频谱仪中,经常用到频谱图。
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、在线傅立叶计算。