关于调用IP核实现FFT
时间:10-02
整理:3721RD
点击:
通过例化调用Xilinx IP核来实现一个512点、数据位宽和相位因子位宽都为10 bit的FFT算法模块,时钟频率为 50MHz,采用流水线,Streaming I/O和定点压缩结构。为了方便验证FFT IP核功能的正确性:以零开始计数,在每个时钟上升沿到来时,进行加1得到的数据,分别作为其输入信号的实部和输入信号的虚部,下面是我写的仿真程序,想请大神帮忙看看有没有什么问题,还有就是得到的结果怎样验证它的正确性
`timescale 1ps / 1ps
module fft_test1_t;
// Inputs
reg clk;
reg RSTn;
reg start;
reg fwd_inv;
reg fwd_inv_we;
reg scale_sch_we;
reg [9:0] xn_re;
reg [9:0] xn_im;
reg [9:0] scale_sch;
// Outputs
wire rfd;
wire busy;
wire edone;
wire done;
wire dv;
wire [8:0] xn_index;
wire [8:0] xk_index;
wire [9:0] xk_re;
wire [9:0] xk_im;
// Instantiate the Unit Under Test (UUT)
fft_ip uut (
.clk(clk),
.start(start),
.fwd_inv(fwd_inv),
.fwd_inv_we(fwd_inv_we),
.scale_sch_we(scale_sch_we),
.rfd(rfd),
.busy(busy),
.edone(edone),
.done(done),
.dv(dv),
.xn_re(xn_re),
.xn_im(xn_im),
.scale_sch(scale_sch),
.xn_index(xn_index),
.xk_index(xk_index),
.xk_re(xk_re),
.xk_im(xk_im)
);
initial begin
// Initialize Inputs
RSTn=0;
#4 RSTn=1;
clk = 0; forever #2 clk=~clk;
#300 $stop;
end
//always #2 clk=~clk;
reg[10:0] i;
always @(posedge clk or negedge RSTn)
begin
if(!RSTn)
begin
start <= 1'b0;
fwd_inv <= 1'b0;
fwd_inv_we <= 1'b0;
scale_sch_we <= 1'b0;
xn_re <= 10'b0;
xn_im <= 10'b0;
scale_sch <= 1'b0;
i<=11'b0;
end
else
begin
//if(!start)
//begin
start <= 1'b1;
fwd_inv <= 1'b1;
fwd_inv_we <= 1'b1;
scale_sch_we <= 1'b1;
scale_sch <=10'b01_10_10_10_11;
if(i<11'd511)
begin
i<=i+1'b1;
xn_re <=xn_re+1'b1;
xn_im <=xn_im +1'b1;
end
else
i<=i;
end
end
endmodule
下面是对应的时序图
`timescale 1ps / 1ps
module fft_test1_t;
// Inputs
reg clk;
reg RSTn;
reg start;
reg fwd_inv;
reg fwd_inv_we;
reg scale_sch_we;
reg [9:0] xn_re;
reg [9:0] xn_im;
reg [9:0] scale_sch;
// Outputs
wire rfd;
wire busy;
wire edone;
wire done;
wire dv;
wire [8:0] xn_index;
wire [8:0] xk_index;
wire [9:0] xk_re;
wire [9:0] xk_im;
// Instantiate the Unit Under Test (UUT)
fft_ip uut (
.clk(clk),
.start(start),
.fwd_inv(fwd_inv),
.fwd_inv_we(fwd_inv_we),
.scale_sch_we(scale_sch_we),
.rfd(rfd),
.busy(busy),
.edone(edone),
.done(done),
.dv(dv),
.xn_re(xn_re),
.xn_im(xn_im),
.scale_sch(scale_sch),
.xn_index(xn_index),
.xk_index(xk_index),
.xk_re(xk_re),
.xk_im(xk_im)
);
initial begin
// Initialize Inputs
RSTn=0;
#4 RSTn=1;
clk = 0; forever #2 clk=~clk;
#300 $stop;
end
//always #2 clk=~clk;
reg[10:0] i;
always @(posedge clk or negedge RSTn)
begin
if(!RSTn)
begin
start <= 1'b0;
fwd_inv <= 1'b0;
fwd_inv_we <= 1'b0;
scale_sch_we <= 1'b0;
xn_re <= 10'b0;
xn_im <= 10'b0;
scale_sch <= 1'b0;
i<=11'b0;
end
else
begin
//if(!start)
//begin
start <= 1'b1;
fwd_inv <= 1'b1;
fwd_inv_we <= 1'b1;
scale_sch_we <= 1'b1;
scale_sch <=10'b01_10_10_10_11;
if(i<11'd511)
begin
i<=i+1'b1;
xn_re <=xn_re+1'b1;
xn_im <=xn_im +1'b1;
end
else
i<=i;
end
end
endmodule
下面是对应的时序图
按着时序给数
验证结果的话,要么通过modelsim仿真,要么通过硬仿
测试数据以FFT点数为周期输入到IP核中,结果会以周期性出现。应该是
FFT是实现时域向频域转化,为什么不输入一个固定频率的连续波,然后看FFT的结果显示的频率是不是你设定的频点呢?输入计数器,做完FFT结果没有意义,不方便验证。
我自己用Verilog代码写的,中间有两个尖峰不知道是怎么回事
fft
sin
看看,占个位置
学习
看看