xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习

1、FFT的IP核的信号分析
xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第1张图片clk:时钟信号,上升沿有效
start:FFT的启动信号,高电平有效。当此信号变高时,开始输入数据,随后直接进行FFT转换操作和数据输出。一个STATRT脉冲,允许对一帧进行FFT转换。如果每N个时钟有一个START脉冲或者START始终为高,则都可以连续进行FFT。如果在最初的START前还没有fwd_inv_we、scale_sch_we信号,则START变高以后就使用这些信号的默认值。由于此IP核支持非连续的数据流,因此在任何时间输入的START,即可开始数据的加载。当加载N个数据结束后,就开始FFT转换运算。在使用过程中最重要的就是注意start,信号要早于输入信号的4个周期,但实际应用中并不需要4个周期就已经开始加载数据了,可以这样说:start一直开,认为第一次加载数据时初始化,即从第二次开始正式工作,从而简化设计。
xn_re、xn_im:输入操作数,分别为实部和虚部,以2的补码输入,在使用时应该确定位宽。输入数据的虚部,在FFT运算时为0,当为IFFT运算时为输入数据的虚部。
fwd_inv:用以指示IP核为FFT还是IFFT,值取1时IP核进行FFT运算,否则进行IFFT(快速傅里叶逆变换)运算。采用哪种运算方式时可以逐帧变化的。
fwd_inv_we:fwd_inv端口的使能信号
scale_sch:在IP核设计时,如果选择在计算过程中进行中间数据的缩减,那么此信号才可以起作用。
scale_sch_we:作为scale_sch的使能信号,高电平有效。
输出信号:
rfd: 数据有效信号,高有效,在加载数据时为高电平。
busy: IP核工作状态的指示信号,在计算FFT转换时为高电平。
done: 高有效,在FFT完成后变高,只存在一个时钟。在done变高后IP核开始输出计算结果。
edone: 高有效,在done信号变高的前一个时钟变为高电平。
dv: 数据有效的指示信号,当输出端口存在有效数据时变高。
xn_index : 位宽等于log2(point size),输入数据的下标。
xk_index: 位宽等于log2(point size),输出数据的下标。
xk_re,xk_im: 输出数据的总线,以2的补码输出。如果选择scaled结构,则输出的数据位宽=输入的数据位宽。;如果选择unscaled结构输出位宽=输入位宽+log2(转换点数)+1

2、FFT的IP核设置
xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第2张图片
Channels 下拉列表用于选择FFT的通路数,范围为1~12,这里选择为1。
Transform Length 下拉列表中用于设置FFT的点数,取值范围为2的幂次方数值,这里选择16。
Implementation Options区域设置实现参数:
Target Clock Frequence 行输入工作频率,时钟频率越高可以获得更高的复用倍数,从而节省更多的资源面积,这里选择的工作始终为125MHZ。

Automatically Select选项,只需要输入数据的吞吐量,ISE就会自动的帮助用户选择实现结构。
Pipelined,Streaming I/O 项对应着流水线的连续I/O模式
Transform Length Options 区域的选项,是指在运行过程中可以根据实际情况调整变换的点数,在本项目中点数数固定的,所以不做设置。
NEXT,进行到下一页:
xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第3张图片Fixed Point 为数据的定点格式。
Precision Options区域用于选择配置输入数据的位宽和相位因子的位宽,这里选择的是16。
Scaling Options区域用于设置缩放因子,对于定点算法,相乘之后需要缩放,否则经过多级乘法器后,数据位宽会加倍递增,占用大量的硬件资源。Unscaled和Scaledd分别对应着不选择和选择缩放功能。如果选择Scaledd项,会增加缩放输入参数SCALE_SCH。
Rounding Modes 区域用于设置截位处理,Truncation项向下取,Convergent Rounding项向上取,本项目中选择向下取。
Optional Pins 区域用于选择握手信号,如CE/SCALR、OVFLO,本项目中不添加握手信号。
Optional Ordering 区域用于设置输出顺序,这里有两个选项,前者为反序输出,后者为正序输出。若选择顺序输出,还可以使能Cyclic Prefix Insertion项插入循环前缀。本项目选择顺序输出,不加前缀使能。
Input data Timing 为输入数据的定时,这里选择3clock cycle offect
点击NEXT:
xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第4张图片Memory Options区域用于设置存储空间的实现方式,DATA和Phase为灰色默认,不做设置。
Number Of Stages Using Block Ram 用于设置块RAM的使用级数,这里设置为0。
Recoder Buffer 选项区域分别用于选择相位因子和记录缓存的存储器类型,有块Ram和分布式的Ram两种,这里选择块Ram。
Optimize Options 区域为优化选项 这里选择3倍乘法器和可配置逻辑快(CLB)逻辑。

3、IP核的测试
Xilinx ISE中调用FFT IP Core的源程序
module fft(
input wire clk, //125M
input wire [15:0] xn_re, //输入实部
input wir [15:0] xn_im,//输入虚部
input wire start, //启动信号
input wire fwd_inv,//FFT
input wire fwd_inv_we,//使能
input wire [3:0] scale_sch,//缩放因子
input wire scale_sch_we,//使能
output wire [15:0] xk_im, //输出虚部
output wire [3:0] xn_index,//输入的下标
output wire [3:0] xk_index,//输出的下标
output wire rfd,//数据高有效
output wire busy,//工作信号
output wire [15:0] xk_re,//输出实部
output wire dv, //输出数据标志
output wire edone,//完成标志
output wire done//完成标志
);
fft_ip fft_ip_inst(
.clk (clk),
.start (start),
.fwd_inv (fwd_inv),
.fwd_inv_we (fwd_inv_we),
.scale_sch_we (scale_sch_we),
.scale_sch (scale_sch),
.rfd (rfd),
.busy (busy),
.edone (edone),
.done (done),
.dv (dv),
.xn_re (xn_re), //输入的数据实部
.xn_im (xn_im),
.xn_index (xn_index),
.xk_index (xk_index),
.xk_re (xk_re),
.xk_im (xk_im)
);

endmodule

在工程中添加HDL测试文件并命名,进行功能测试
module tb_myfft;
// Inputs
reg fwd_inv_we;
reg start;
reg fwd_inv;
reg clk;
reg [15:0] xn_re;
reg [15:0] xn_im;

    // Outputs
    wire rfd;
    wire dv;
    wire done;
    wire busy;
    wire edone;
    wire [15:0] xk_im;
    wire [3:0] xn_index;
    wire [15:0] xk_re;
    wire [3:0] xk_index;

   // Instantiate the Unit Under Test (UUT)
   myfft uut (
   .fwd_inv_we(fwd_inv_we), 
   .rfd(rfd), 
   .start(start), 
   .fwd_inv(fwd_inv), 
   .dv(dv), 
   .done(done), 
   .clk(clk), 
   .busy(busy), 
   .edone(edone), 
   .xn_re(xn_re), 
   .xk_im(xk_im), 
   .xn_index(xn_index), 
   .xk_re(xk_re), 
   .xn_im(xn_im), 
   .xk_index(xk_index));

initial begin
// Initialize Inputs
fwd_inv_we = 0;
start = 0;
fwd_inv = 0;
clk = 0;
xn_re = 0;
xn_im = 0;
scale_sch = 0;
scale_sch_we = 0;

// Wait 100 ns for global reset to finish;
#100;
// Add stimulus here
fwd_inv_we = 1; //设置为FFT变换
fwd_inv = 1; //使能信号
start = 1; //启动信号
end

always #10 clk=~clk;
always@(posedge clk) begin
xn_re = xn_re+1 ;
xn_im = xn_im+1 ;
end
endmodule

根据间隔每一帧数据需要三帧才能输出计算结果,可以推出850ns时刻的输出,对应着[14:29]+[14:29]*j的输出结果。在matlab中输入以下命令:
x= [14:29]+[14:29]*j;
y=round(fft(x));
计算结果如下图所示,可以看出计算结果和仿真结果是一致的
仿真结果如图1、图2、图3所示
xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第5张图片xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第6张图片xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第7张图片
5、设计方法(这里是将AD采集后的信号放到FIFO中)
xilinx 的FFT IP核的使用手册及仿真结果,matlab仿真结果对比,适合初学者学习_第8张图片
其中data_rx1[13:0]和data_rx2[13:0]是由AD采集后直接输入赋值的,前者为I路数据,作为fft ip core 的实部数据输入,后者为 Q路输入,作为作为fft ip core 的虚部数据输入,但是在这里fwd_inv为1设置的为FFT变换,所以虚部数据没有用到。

欢迎老铁批评指正。因为代码比较简单,非常适合初学者,如果你觉得文档写的还行的话请给个赞或者给个留言鼓励一下,大家一起学习共同进步,谢谢。

你可能感兴趣的:(verilog,fpga,FIFO,IP,FFT)