reference:https://blog.csdn.net/shichaog/article/details/51189711
https://blog.csdn.net/qq_36375505/article/details/81742680 (推薦)
https://blog.csdn.net/lovewdmcwieg/article/details/79235229
https://blog.csdn.net/FPGADesigner/article/details/80694673
該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/OFFT ip核使用基二和基四分解法計算離散傅里葉變換 ; 對於Burst I/O architectures采用時域抽取法實現,對於Pipelined Streaming I/Oarchitecture.使用頻域抽取法。當使用基四計算時,其蝶型算法的級數是log 4 (N),每一級包括N/4的基四蝶型運算。對於點數不是4的指數情況,則需要一個額外的基二來組合數據。類似的基二實現法需要log 2 (N)級蝶型運算。對於scaling方法,其每一級的scaling因子由s_axis_config_tdata來配置。Ip核的端口如下:
輸入輸出方向在上圖中已經很明顯了,下面描述端口作用
名稱 | 方向 | 可選擇性 | 描述 |
aclk |
I | NO | 上升時鍾沿采樣 |
aclken |
I | yes | 高有效,時鍾使能 |
aresetn |
I | yes | 同步低有效復位,至少需要保持兩個低有效周期; |
s_axis_config_tvalid |
I | NO | 參數配置通道,config數據有效標志 |
s_axis_config_tready |
O | NO | 參數配置通道,高狀態下,config才可以再次配置 |
s_axis_config_tdata |
I | NO | 參數配置通道,包括了配置信息:CP_LEN,FWD/INV,NFFT 和SCALE_SCH |
s_axis_data_tvalid |
I | NO | 數據輸入通道,數據有效標志 |
s_axis_data_tready |
O | NO | 數據輸入通道,狀態准備標志 |
s_axis_data_tdata |
I | NO | 數據輸入通道,數據輸入;包括未處理數據:XN_RE/XN_IM |
s_axis_data_tlast |
I | NO | 數據輸入通道,外部主設備在幀的最后一個樣本上斷言。 除了生成事件event_tlast_unexpected和event_tlast_missing事件之外,核心不使用它 |
m_axis_data_tvalid |
O | NO | 數據輸出通道,標志輸出數據的有效性 |
m_axis_data_tready |
I | NO | 數據輸出通道,接受外部從設備斷言,表示已准備好接受數據。 僅存在於非實時模式中。 |
m_axis_data_tdata |
O | NO | 數據輸出通道,包含處理后的數據:XK_RE/XK_IM |
m_axis_data_tuser |
O | NO | 數據輸出通道,攜帶額外的每個采樣信息,例如XK_INDEX,OVFLO和BLK_EXP |
m_axis_data_tlast |
O | NO | 數據輸出通道,內核在幀的最后一個采樣上斷言。 |
m_axis_status_tvalid |
O | NO | 狀態輸出通道,提供狀態有效的斷言 |
m_axis_status_tready |
I | NO | 狀態輸出通道,外部slave斷言是否准備好接收狀態數據。僅存在與非實時模式中。 |
m_axis_status_tdata |
O | NO | 狀態輸出通道,包含了狀態數據BLK_EXP/OVFLO |
event_frame_started |
O | NO | 事件狀態通道,當內核開始處理一個新幀時,內核產生斷言 |
event_tlast_unexpected |
O | NO | 事件狀態通道,當內核發現在非幀的最后一個采樣時,出現了s_axis_data_tlast拉高,內核將產生斷言 |
event_tlast_missing |
O | NO | 事件狀態通道,當在幀最后一個采樣時,s_axis_data_tlast沒有被拉高,內核將產生斷言 |
event_fft_overflow |
O | NO | 事件狀態通道,在數據輸出通道卸載的數據樣本中看到溢出時置位。 僅在溢出是有效選項時出現。 |
event_data_in_channel_halt |
O | NO | 事件狀態通道,在內核需要數據時,數據輸入數據無效,內核產生斷言 |
event_data_out_channel_halt |
O | NO | 事件狀態通道,在內核向外寫數據時,出現不能寫出時,內核出現斷言。僅出現在非實時模式下。 |
event_status_channel_halt |
O | NO | 事件狀態通道,在內核向外寫狀態時,出現不能寫出時,內核出現斷言。僅出現在非實時模式下。 |
上面信號所有s開始的表示的是axi信號的slave端,m是master端。各信號更詳細作用參考: pg109 -Fast Fourier Transform v9.0 LogiCORE IP Product Guide.pdf
以8點FFT示意,configure
implementtation
summary
由於xilinx自帶的testbench是VHDL的,這里給出自己寫的verilog版本的testbench。
`timescale 1ns / 1ps 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
000007
stimulus1_24bit.dat文件內容隨便,這里是兩個通道的FFT計算。仿真波形圖如下:
MATLAB計算所得的FFT結果如下:
將FFT結果的放大后得到如下圖:
MATLAB計算的結果是28,而fpga仿真結果是0x00000e為14,0xfffffe為-2;這是因為設置了scaling因子,且scaling因子是2,即28/2=14。
關於hls的實現見:
http://blog.csdn.net/shichaog/article/details/50811449