該ip用於實現N=2**m(m=3~16)點FFT的變換,
實現的數學類型包含:
A) 定點全精度
B) 定點縮減位寬
C) 塊浮點
每一級蝶型運算后舍入或者取整。對於N點運算。FFT還是逆FFT,scaling策略以及循環前綴的長度是執行時可配置的,可隨幀改變,改變變換點數會復位FFT ip核。
有四種可選擇的FFT的實現架構:
1) PipelinedStreaming I/O
2) Radix-4Burst I/O
3) Radix-2Burst I/O
4) Radix-2 Lite Burst I/OFFTip核使用基二和基四分解法計算離散傅里葉變換,對於Burst I/O architectures採用時域抽取法實現,對於Pipelined Streaming I/Oarchitecture.使用頻域抽取法。當使用基四計算時。其蝶型算法的級數是log 4 (N)。每一級包含N/4的基四蝶型運算。對於點數不是4的指數情況,則須要一個額外的基二來組合數據。
類似的基二實現法須要log 2 (N)級蝶型運算。對於scaling方法。其每一級的scaling因子由s_axis_config_tdata來配置。
Ip核的port例如以下:

輸入輸出方向在上圖中已經非常明顯了,以下描寫敘述port作用
Aclk輸入時鍾。上升沿有效
Aclken :使用有效信號,高使能
Aresetn:同步復位信號,低電平有效(至少保持aclk兩個時鍾周期)
s_axis_config_tdata:包含配置信息,CP_LEN, FWD/INV, NFFT,SCALE_SCH.
上面信號全部s開始的表示的是axi信號的slave端,m是master端。
各信號作用參考《Fast Fourier Transform v9.0 LogiCORE IP Product Guide》
以8點FFT示意,configure
implementtation

summary

因為xilinx自帶的testbench是VHDL的。這里給出自己寫的verilog版本號的testbench。
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: shichaog
//
// Create Date: 04/13/2016 08:35:42 PM
// Design Name:
// Module Name: TB_fft256
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module TB_fft256;
// Inputs
reg aclk;
reg s_axis_config_tvalid;
reg s_axis_data_tvalid;
reg s_axis_data_tlast;
reg m_axis_data_tready;
reg [15:0] s_axis_config_tdata;
reg [95: 0] s_axis_data_tdata;
// Outputs
wire s_axis_config_tready;
wire s_axis_data_tready;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;
wire event_frame_started;
wire event_tlast_unexpected;
wire event_tlast_missing;
wire event_status_channel_halt;
wire event_data_in_channel_halt;
wire event_data_out_channel_halt;
wire [95 : 0] m_axis_data_tdata;
reg[23:0] mem0_re[0:7];
reg[23:0] mem1_re[0:7];
reg[23:0] mem2_re[0:7];
initial $readmemh("/home/gsc/FPGA_exercise/bf_verilog/stimulus0_24bit.dat",mem0_re);
initial $readmemh("/home/gsc/FPGA_exercise/bf_verilog/stimulus1_24bit.dat",mem1_re);
initial $readmemh("/home/gsc/FPGA_exercise/bf_verilog/stimulus2_24bit.dat",mem2_re);
reg[7:0] op_sample= 0;
reg op_sample_first = 1;
reg[7:0] ip_frame=0;
reg[7:0] op_frame=0;
integer i;
// generate clk
always #5 aclk =! aclk;
// Instantiate the Unit Under Test (UUT)
xfft_256 uut (
.aclk(aclk), // input wire aclk
.s_axis_config_tdata(s_axis_config_tdata), // input wire [15 : 0] s_axis_config_tdata
.s_axis_config_tvalid(s_axis_config_tvalid), // 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 [95 : 0] s_axis_data_tdata
.s_axis_data_tvalid(s_axis_data_tvalid), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tlast(s_axis_data_tlast), // input wire s_axis_data_tlast
.m_axis_data_tdata(m_axis_data_tdata), // output wire [95 : 0] m_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tready(m_axis_data_tready), // input wire m_axis_data_tready
.m_axis_data_tlast(m_axis_data_tlast), // output wire m_axis_data_tlast
.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_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
);
initial begin
// Initialize Inputs
aclk = 0;
s_axis_config_tvalid = 0;
s_axis_config_tdata = 0;
s_axis_data_tvalid = 0;
s_axis_data_tdata = 0;
s_axis_data_tlast = 0;
m_axis_data_tready = 0;
// Wait 100 ns for global reset to finish
#150;
m_axis_data_tready = 1;
s_axis_config_tvalid = 1;
//s_axis_config_tdata = 16'b0101100101011011; // FFT desired (and not IFFT
s_axis_config_tdata = 16'b0000000000000111; // FFT desired (and not IFFT
//s_axis_data_tlast = 1;
s_axis_data_tdata = 96'h000000;
s_axis_data_tvalid = 0;
begin
for(i=0;i<8;i=i+1)
begin
#10
s_axis_data_tvalid <= 1;
s_axis_data_tdata <= {{24'h000000},mem1_re[i],{24'h000000},mem0_re[i]};
$display("mem_a[%d] = %h", i, mem0_re[i]);
// if(i== 256)
// s_axis_data_tlast <= 1;
// else
// s_axis_data_tlast <= 0;
end
end
#10;
s_axis_data_tdata = 96'h000000;
s_axis_data_tvalid = 0;
#1000 $finish;
//$stop
end
endmodule
stimulus0_24bit.dat文件內容例如以下:
000000 000001 000002 000003 000004 000005 000006 000007stimulus1_24bit.dat文件內容隨便。這里是兩個通道的FFT計算。
仿真波形圖例如以下:

MATLAB計算所得的FFT結果例如以下:

將FFT結果的放大后得到例如以下圖:

MATLAB計算的結果是28。而fpga仿真結果是00000e,-4則是fffffe。這是由於設置了scaling因子,且scaling因子是2,即28/2=14。
關於hls的實現見:
http://blog.csdn.net/shichaog/article/details/50811449
