Xilinx FFT IP使用总结
Xilinx FFT IP使用總結(jié)
- 一、概述
- 二、FFT IP 配置過程
- 1、步驟一:配置FFT 點數(shù)及工作模式
- 2、步驟二:配置數(shù)據(jù)格式、輸出數(shù)據(jù)順序、循環(huán)前綴等信息
- 3、步驟三:配置內(nèi)部資源優(yōu)化選項
- 4、步驟四:查看生成了FFT信息,重點注意生成參數(shù)的格式
- 三、FFT IP的test bench
- 四、FFT結(jié)果及時序分析
- 1、整體時序波形
- 2、FFT輸入數(shù)據(jù)時序波形
- 3、FFT輸出結(jié)果時序波形
- 4、FFT輸出結(jié)果分析
- 1)FPGA計算結(jié)果
- 2)matlab計算結(jié)果
- 3)結(jié)果比對
- 五、基2突發(fā)、基4突發(fā)、pipeline三種模式資源占用及性能分析
- 六、注意事項
一、概述
FFT快速傅里葉變換是我們在數(shù)字信號處理中經(jīng)常會用到的DSP算法,本文將Xilinx FFT IP核的使用方法及注意事項總結(jié)如下 ,主要是產(chǎn)生一個周期256點的正弦信號,然后通過FFT的IP核做256點的FFT處理,最后通過仿真分析對比查看FFT輸出結(jié)果與matlab結(jié)果差異。
二、FFT IP 配置過程
下面將通過vivado配置FFT IP核的過程說明如下。
1、步驟一:配置FFT 點數(shù)及工作模式
2、步驟二:配置數(shù)據(jù)格式、輸出數(shù)據(jù)順序、循環(huán)前綴等信息
3、步驟三:配置內(nèi)部資源優(yōu)化選項
4、步驟四:查看生成了FFT信息,重點注意生成參數(shù)的格式
三、FFT IP的test bench
下面是FFT IP的測試代碼,具體見代碼注釋。
`timescale 1ns / 1nsmodule tb_fft;//基2的參數(shù)配置 //parameter FWD=1'b1;//選擇是FFT還是IFFT //parameter SCALE=16'b01_01_01_01_01_00_01_10; //parameter PAD=7'b000_0000;//基4的參數(shù)配置 parameter FWD=1'b1;//選擇是FFT還是IFFT parameter SCALE=8'b01_10_11_10;//每級右移位數(shù) parameter PAD=7'b000_0000;//基4+CP的參數(shù)配置 //parameter FWD=1'b1;//選擇是FFT還是IFFT //parameter SCALE=8'b01_10_11_10; //parameter PAD=7'b000_0000; //parameter CP_LEN=8'b0000_1000;reg sclk; reg rst_n;reg [7:0] addra; reg [8:0] addra_cnt; wire [7:0] sin_out; wire [15:0] fft_in;//基2的寄存器長度 //wire [23:0] s_axis_config_tdata; //基4的寄存器長度 wire [15:0] s_axis_config_tdata; //基4+CP的寄存器長度 //wire [23:0] s_axis_config_tdata; //wire s_axis_config_tready;wire s_axis_data_tready; reg[15:0] s_axis_data_tdata; reg s_axis_data_tvalid; wire[15:0] m_axis_data_tdata; wire[15:0] m_axis_data_tuser; wire m_axis_data_tvalid; wire m_axis_data_tlast;wire[7:0] out_re; wire[7:0] out_im;wire m_axis_status_tdata; wire m_axis_status_tvalid; wire event_frame_started; wire event_tlast_unexpected; wire event_tlast_missing; wire event_fft_overflow; wire event_status_channel_halt; wire event_data_in_channel_halt; wire event_data_out_channel_halt;initial begin #0 sclk=0;rst_n=0; #90 rst_n=1; end always #10 sclk=~sclk;//產(chǎn)生從RAM中讀取256點正弦信號地址 always@(posedge sclk or negedge rst_n) beginif(rst_n==1'b0)addra<=8'd0;else if(addra==8'd255)//只產(chǎn)生256個數(shù)據(jù)地址,然后一直保持addra<=addra;elseaddra<=addra+1'b1; end //單口RAM的IP核 blk_mem_gen_0 blk_mem_gen_0_inst (.clka(sclk), // input wire clka.ena(1'b1), // input wire ena.wea(1'b0), // input wire [0 : 0] wea.addra(addra), // input wire [7 : 0] addra.dina('d0), // input wire [7 : 0] dina.douta(sin_out) // output wire [7 : 0] douta ); //輸入的正弦信號為實信號放在實部,虛部全部補零 assign fft_in={8'd0,sin_out};//用于產(chǎn)生256個數(shù)據(jù)的s_axis_data_tvalid信號 always@(posedge sclk or negedge rst_n) beginif(rst_n==1'b0)addra_cnt<=9'd0;else if(addra_cnt==9'd256)addra_cnt<=addra_cnt;elseaddra_cnt<=addra_cnt+1'b1; end//輸入FFT數(shù)據(jù)與valid信號同步 always@(posedge sclk or negedge rst_n) beginif(rst_n==1'b0)begins_axis_data_tvalid<=1'b0;s_axis_data_tdata<=16'd0;endelse if(addra_cnt==9'd256)begins_axis_data_tvalid<=1'b0;s_axis_data_tdata<=16'd0;endelsebegins_axis_data_tvalid<=1'b1;s_axis_data_tdata<=fft_in;end end//將FFT輸入數(shù)據(jù)的valid信號進行延時 reg [9:0] delay; always@(posedge sclk or negedge rst_n) beginif(rst_n==1'b0)delay<=10'd0;elsedelay[9:0]<={delay[8:0],s_axis_data_tvalid}; end//配置FFT參數(shù) //基4的參數(shù)配置 assign s_axis_config_tdata={PAD,SCALE,FWD}; //基4+CP的寄存器長度 //assign s_axis_config_tdata={PAD,SCALE,FWD,CP_LEN}; xfft_0 xfft_0_inst (.aclk(sclk), // input wire aclk.aclken(1'b1), // input wire aclken.aresetn(rst_n), // input wire aresetn.s_axis_config_tdata(s_axis_config_tdata), // input wire [23 : 0] s_axis_config_tdata.s_axis_config_tvalid(1'b1), // input wire s_axis_config_tvalid.s_axis_config_tready(s_axis_config_tready), // output wire s_axis_config_tready.s_axis_data_tdata(s_axis_data_tdata), // input wire [15 : 0] s_axis_data_tdata.s_axis_data_tvalid(delay[0]), // input wire s_axis_data_tvalid.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready.s_axis_data_tlast(1'b0), // input wire s_axis_data_tlast.m_axis_data_tdata(m_axis_data_tdata), // output wire [15 : 0] m_axis_data_tdata.m_axis_data_tuser(m_axis_data_tuser), // output wire [15 : 0] m_axis_data_tuser.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid.m_axis_data_tready(1'b1), // input wire m_axis_data_tready.m_axis_data_tlast(m_axis_data_tlast), // output wire m_axis_data_tlast.m_axis_status_tdata(m_axis_status_tdata), // output wire [7 : 0] m_axis_status_tdata.m_axis_status_tvalid(m_axis_status_tvalid), // output wire m_axis_status_tvalid.m_axis_status_tready(1'b1), // input wire m_axis_status_tready.event_frame_started(event_frame_started), // output wire event_frame_started.event_tlast_unexpected(event_tlast_unexpected), // output wire event_tlast_unexpected.event_tlast_missing(event_tlast_missing), // output wire event_tlast_missing.event_fft_overflow(event_fft_overflow), // output wire event_fft_overflow.event_status_channel_halt(event_status_channel_halt), // output wire event_status_channel_halt.event_data_in_channel_halt(event_data_in_channel_halt), // output wire event_data_in_channel_halt.event_data_out_channel_halt(event_data_out_channel_halt) // output wire event_data_out_channel_halt ); //查看FFT輸出結(jié)果的實虛部 assign out_re=m_axis_data_tdata[7:0]; assign out_im=m_axis_data_tdata[15:8];endmodule四、FFT結(jié)果及時序分析
1、整體時序波形
2、FFT輸入數(shù)據(jù)時序波形
FFT輸入數(shù)據(jù)起始時序波形如下,將輸入數(shù)據(jù)同步信號s_axis_data_tvalid延遲了1拍,是因為輸入FFT參數(shù)配置信號s_axis_config_tready還沒有拉高,即FFT參數(shù)還沒有配置后,FFT輸入數(shù)據(jù)已經(jīng)進來,會導致輸入數(shù)據(jù)點數(shù)少于FFT點數(shù),出現(xiàn)event_data_in_channel_halt拉高報錯。
3、FFT輸出結(jié)果時序波形
從時序圖中看出,FFT的輸出數(shù)據(jù)與輸出數(shù)據(jù)同步信號m_axis_data_tvalid和最后數(shù)據(jù)指示信號m_axis_data_tlast是完全同步的。
4、FFT輸出結(jié)果分析
1)FPGA計算結(jié)果
便于比對FPGA與matalb結(jié)果,將輸出結(jié)果配置為小數(shù), 如下圖。
第256個點FFT輸出結(jié)果虛部為0.5
2)matlab計算結(jié)果
matlab代碼如下:
clc; close all; clear all; n=[0:255]; N=256; sig=round(sin(2*pi*n/N)*127); %sig=round(sin(2*pi*n/N)*32767); sig_freq_re=real(fft(sin(2*pi*n/N),256)); sig_freq_im=imag(fft(sin(2*pi*n/N),256)); %figure(1),plot(abs(sig_freq));for i=1:256if(sig(i)<0)sig(i)=256+sig(i);%對于負數(shù)要轉(zhuǎn)換為補碼形式%sig(i)=65536+sig(i);%對于負數(shù)要轉(zhuǎn)換為補碼形式elsesig(i)=sig(i);end end fid=fopen('ram_init_data.coe','w+') fprintf(fid,'memory_initialization_radix = 10; \n') fprintf(fid,'memory_initialization_vector = \n') for i=1:255fprintf(fid,'%d,',sig(i)); end fprintf(fid,'%d;',sig(256)); fclose(fid);matlab輸出結(jié)果如下:
3)結(jié)果比對
為防止在計算FFT過程中出現(xiàn)溢出,我們在配置FFT的SCALE參數(shù)時,進行了右移處理,一共右移了8位后為0.5,正好與maltab結(jié)果是完全對應(yīng)的,因此可以得出FFT IP核輸出結(jié)果正確。
五、基2突發(fā)、基4突發(fā)、pipeline三種模式資源占用及性能分析
1、基2突發(fā)模式占用資源及時延
2、基4突發(fā)模式占用資源及時延
3、pipeline模式占用資源及時序
六、注意事項
1、為防止計算FFT過程中出現(xiàn)溢出,計算256點FFT時,在基4突發(fā)和pipeline這兩種模式下,SCALE推薦采用[01_10_11_10],在基2突發(fā)模式下,推薦采用[01_01_01_01_01_00_01_10]。
2、在基2突發(fā)和基4突發(fā)模式,未采用流水下結(jié)果,只有FFT計算并輸出完成后,采用允許繼續(xù)輸入;而pipeline模式可以連續(xù)輸入數(shù)據(jù)進行FFT計算。
3、該FFT IP支持插入CP循環(huán)前綴,非常方便,但是要考慮輸入數(shù)據(jù)的連續(xù)性。
4、基2突發(fā)模式占用資源最少但是處理時延大,基4突發(fā)模式正好相反,需要根據(jù)系統(tǒng)資源情況及時延要求綜合考慮。
5、采用四舍五入方式比截斷方式準確度更好。
關(guān)于xilinx FFT IP的具體使用,可以參見官方《Fast Fourier Transform v9.1 LogiCORE IP Product Guide》手冊。
總結(jié)
以上是生活随笔為你收集整理的Xilinx FFT IP使用总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cf:B. Patchouli‘s Ma
- 下一篇: ZOJ3380_Patchouli's