参考: http://blog.csdn.net/yijingjijng/article/details/48137897
http://xilinx.eetop.cn/viewnews-1262
http://blog.csdn.net/u011746496/article/details/44761865
http://xilinx.eetrend.com/article/6144
http://xilinx.eetrend.com/blog/8856
该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/O
FFTip核使用基二和基四分解法计算离散傅里叶变换,对于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输入时钟,上升沿有效
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。
[plain] view
plain copy
-
`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文件内容如下:
[plain] view
plain copy
-
000000
-
000001
-
000002
-
000003
-
000004
-
000005
-
000006
-
000007
stimulus1_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