该ip可以实现N= 2 m 2^m 2m点的DFT或者IDFT,(m=3~16).
输入数据精度 bx= 8 – 34相位因子精度 bw= 8 – 34输入的数据类型: 未缩放(全精度)的定点数缩放的定点数块浮点数 可以在运行时配置变换点数有四种运算架构可供选择 Pipelined Streaming I/ORadix-4 Burst I/ORadix-2 Burst I/ORadix-2 Lite Burst I/O详细信息请查看官方数据手册。
那么在使用时,位宽的多少,是否填充,填充多少,这些都需要我们自己去计算吗?当然不用,Vivado IDE可以自动计算。就以NFFT为例,当我们勾选run time configurable时,我们可以看到s_axis_config_tdata 的位宽发生了变化,而且,具体的某一位代表什么也可以从中看出。
Channels:选择一个通道 Transform Length:选择1024,注意这个是最大长度,只果勾选了run time configurable,配置长度才可变。 Implementation Options:运算的架构,其资源与数据吞吐量如下图所示
Data Format:选择Fixed Point,选择其它选项会发现资源使用暴增。
Scaling Options :缩放选项,选择Scaled,同样有其它选项,但是资源使用量会暴增
因此,要合理权衡资源、运算速度、精度,选择合适的选项,如果资源太多用不完,当我没说。 Precision Options: 输入数据位宽和相位因子位宽。相位因子具体干什么用,我也不太清楚,看了下手册,好像和噪声有关,这里保持默认16bit即可,至于输入位宽,这里是指实部和虚部的位宽,实际上输入应是32bit。可以看到,高16位是虚部,低16位是实部。输出数据同理。 Control Signals: 选择复位信号,至少保持两个周期。 Output Ordering:输出时自然序列还是倒序。 其它保持默认选项,都不勾选,如果有需要使用的,可以查阅官方手册。因为这些配置已经可以进行正常的运算了。
这里主要选择资源的使用类型,比如是否使用BRAN,是否使用乘法器,用多少什么的,同样,权衡资源与速度,保持默认即可。 最后看一下Latency,这个与你计算的点数,实际时钟屏率,选择资源类型有关,所以这个Latency仅供参考。
在生成IP核以后,将其导出,然后进行仿真验证,在这里我选用ModelSim,个人建议不要选择Vivado自带的仿真,个人感觉有卡又慢又难用。然后还需要Matlab生成波形和验证结果。什么?没有Matlab,那你搞什么FFT,赶快去装一个。有了Matlab,我们可以更方便的进行仿真。
初始化部分代码 首先,需要初始化CONFIG_tdata,其一共有16个bit(为什么是16bit,去IP核配置界面自己看)这里,我们选用正变换,所以最低一个bit为1,然后10个bit是缩放因子,2个一组,选择缩放32倍,剩下的用0填充。所以结果因该是这样:
assign S_AXIS_CONFIG_tdata = 16'b0000_0_01_01_01_01_01_1;M_AXIS_DATA_tready这个一直拉高即可,详情请看AXI协议。
assign M_AXIS_DATA_tready = 1'b1;定义变换的最大点数:
parameter MAX_SIZE=16'd1024 - 1;然后我们需要1024个数据,这1024个数据采用Matlab生成,然后ModelSim读取。
reg[15:0] memory[MAX_SIZE:0];//测试波形数据存储空间 initial $readmemh("./sin_bit.txt",memory);//读取原始波形数据读到memory中我们还需要将FFT的输出数据导出,然后由Matlab分析查看结果。
integer handle1; initial begin//sequence block handle1 = $fopen("fsave.txt"); #5000; @(negedge M_AXIS_DATA_tvalid);//等待数据输出完毕 #5000; $fclose(handle1); $stop; end always @(posedge aclk) begin if(M_AXIS_DATA_tvalid) $fwrite(handle1,"%d %d \n",M_AXIS_DATA_tdata[31:16],M_AXIS_DATA_tdata[15:0]); end剩下的就是控制传输数据。
always @(posedge aclk) begin if(all_en) begin cnt <= cnt + 1'b1; if(cnt == 0) begin S_AXIS_CONFIG_tvalid <=1; end else if(cnt == 3) S_AXIS_CONFIG_tvalid <= 0; else if(cnt == 5) begin S_AXIS_DATA_tvalid <= 1; index = 0; end else if(cnt == MAX_SIZE + 5) begin S_AXIS_DATA_tlast <= 1'b1; end else if(cnt == MAX_SIZE + 6) begin S_AXIS_DATA_tvalid <= 1'b0; S_AXIS_DATA_tlast <= 1'b0; end if(S_AXIS_DATA_tlast) index <= 'd0; else if(S_AXIS_DATA_tvalid) index <= index +1; end end确认代码无误后,开始仿真,仿真主要看一下有没有错误发生,如果有,检查一下错误的原因,没有错误接下来就用Matlab处理数据。 先用Matlab生成测试的波形:
F1=1000000; F2=500000; F3=1500000; %信号的频率 Fs= F1*4;%采样频率 A1=135; A2=296; A3=502; %振幅 P1=50; P2=-60; P3=110; %信号初始相位 ADC = 400; %直流分量 N=1024;%采样点数为N WIDTH = 12;%信号位宽 t=0:1/Fs:(N-1)/Fs;%采样时刻 s= ADC+A1*cos(2*pi*F1*t+pi*P1/180)+A2*cos(2*pi*F2*t+pi*P2/180)+A3*cos(2*pi*F3*t+pi*P3/180);%生成信号 plot(s);%绘制图形 title('原始波形'); figure由于采样点数过高,这个图估计连它亲娘都不认识,所以还是看函数吧。 我们将生成的波形文件放到ModelSim中仿真,完成后,再将生成的波形文件和Matlab的FFT结果对比,这里需要注意的是,我们在IP核中,设置了放缩,所以在Matlab中需要将IP核的结果乘以32. 然后以下是Matlab和IP核的结果对比,将计算得到的数据分别转成了幅度-频率图和相位-频率图。可以发现,两者之间误差很小。
官方手册 Xilinx FFT IP v9.0 使用 VIVADO FFT核的实现 基于MATLAB的FFT分析 matlab关于fft的应用(一) [数字信号处理]Matlab做fft时点数N怎么选取