Vivado FFT9.0仿真验证

      在网上看了很多的介绍,基本都是一样的,但是根据这些博客,自己验证了下发现结果和matlab中不一样。

1.配置IP核

      用vivado17.2 IP版本为9.0,配置首先配置最大长度为64,时钟为100MHz,将长度可以改变选中,如下图所示:

进一步的配置,设置数据为整型,未缩放,输入16bit,输出自然顺序(不然虚部不方便验证)。

第三页默认

2.tb编写

module AA_tb;

 reg aclk;
 reg aresetn;
 reg [15 : 0] s_axis_config_tdata;
 reg s_axis_config_tvalid;
 wire s_axis_config_tready;
 reg [31 : 0] s_axis_data_tdata;
 reg s_axis_data_tvalid;
 wire s_axis_data_tready;
 reg s_axis_data_tlast;
 wire [47 : 0] m_axis_data_tdata;
 wire [7 : 0] m_axis_data_tuser;
 wire m_axis_data_tvalid;
 reg m_axis_data_tready;
 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;

 reg    [11:0] mem0_re[256:0]; 
 reg    [7:0] op_sample= 0;
 reg op_sample_first = 1;
 reg    [7:0] ip_frame=0;
 reg    [7:0] op_frame=0;

// initial $readmemh("C:/Users/74339/Desktop/vivado_code/fft_test/signal.txt",mem0_re);
 integer i;
 reg s_data;



 always #5 aclk = !aclk;

 initial begin
  // Initialize Inputs
  aclk = 0;
  aresetn = 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;
  s_data = 0;
  i = 0;
  // Wait 100 ns for global reset to finish
  #150;
  aresetn = 1;
  m_axis_data_tready = 1;
  s_axis_config_tvalid = 1;
  s_axis_config_tdata = 16'b0101100101000100; // FFT desired (and not IFFT
  //s_axis_config_tdata = 24'b100100000000000100; // FFT desired (and not IFFT

  s_axis_data_tlast = 1;
  s_axis_data_tdata = 48'h000000;  
  s_axis_data_tvalid = 0;

  #3000;
  aresetn = 0;
  #300;
  aresetn = 1;  
  m_axis_data_tready = 1;
  s_axis_config_tvalid = 1;
  s_axis_config_tdata = 16'b0101100101000110; // FFT desired (and not IFFT
  //s_axis_config_tdata = 24'b100100000000000111; // FFT desired (and not IFFT

  s_axis_data_tlast = 1;
  s_axis_data_tdata = 48'h000000;  
  s_axis_data_tvalid = 0;


 s_axis_data_tvalid = 0;
 end

 reg ff;
 
  always @(posedge aclk)
 begin
	if(s_axis_data_tready == 1)
		ff <= 1'b1;
	else
		ff <= ff;
 
 end
 
 reg [9:0] cntttt=0;
 
 
   always @(posedge aclk)
 begin
	if(ff == 0)
		cntttt <= 10'b0;
	else if(cntttt==1023)
		cntttt <= cntttt;
	else
		cntttt <= cntttt+1;
 
 end
 
 
 always @(posedge aclk)
 begin
	if((cntttt >= 800)&&(cntttt <= 814))
	begin
		s_axis_data_tvalid <= 1;
		s_axis_data_tdata <=s_axis_data_tdata+1;
		s_axis_data_tlast <= 0;
	end
	else if(cntttt == 815)
	begin
		s_axis_data_tvalid <= 1;
		s_axis_data_tdata <=s_axis_data_tdata+1;
		s_axis_data_tlast <= 1;
	end		

   else
	begin
		s_axis_data_tvalid <= 0;
		s_axis_data_tdata <=0;
		s_axis_data_tlast <= 0;
	end
 end
 
  xfft_1024 uut (                                           
   .aclk(aclk), // input wire aclk
  // .aresetn(aresetn), // input wire aresetn
   .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 [63 : 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 [79 : 0] m_axis_data_tdata
 //  .m_axis_data_tuser(m_axis_data_tuser), // output wire [7 : 0] m_axis_data_tuser
   .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
 ); 
 wire [15:0] m_real,m_image; 


assign m_real = m_axis_data_tdata[15:0];
assign m_image  = m_axis_data_tdata[39:24];

 
 
endmodule

3.16点FFT

需要注意的是输出为48位,[15:0] 为实部,[39:24]为虚部,查看结果如下所示:

Matlab中的代码如下所示:

N=16;
X=zeros(N,1);
for i=1:N
    X(i)=i;
end
FFTX=fft(X,N);
x_real=round(real(FFTX));
x_imag=round(imag(FFTX));

实部为:

虚部:

IP的仿真结果和matlab结果基本一致。

4、64点FFT

同样的代码只需要将IP的配置值修改就行

module AA_tb;

 reg aclk;
 reg aresetn;
 reg [15 : 0] s_axis_config_tdata;
 reg s_axis_config_tvalid;
 wire s_axis_config_tready;
 reg [31 : 0] s_axis_data_tdata;
 reg s_axis_data_tvalid;
 wire s_axis_data_tready;
 reg s_axis_data_tlast;
 wire [47 : 0] m_axis_data_tdata;
 wire [7 : 0] m_axis_data_tuser;
 wire m_axis_data_tvalid;
 reg m_axis_data_tready;
 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;

 reg    [11:0] mem0_re[256:0]; 
 reg    [7:0] op_sample= 0;
 reg op_sample_first = 1;
 reg    [7:0] ip_frame=0;
 reg    [7:0] op_frame=0;

// initial $readmemh("C:/Users/74339/Desktop/vivado_code/fft_test/signal.txt",mem0_re);
 integer i;
 reg s_data;



 always #5 aclk = !aclk;

 initial begin
  // Initialize Inputs
  aclk = 0;
  aresetn = 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;
  s_data = 0;
  i = 0;
  // Wait 100 ns for global reset to finish
  #150;
  aresetn = 1;
  m_axis_data_tready = 1;
  s_axis_config_tvalid = 1;
  //s_axis_config_tdata = 16'b0101100101000100; // FFT desired (and not IFFT
  s_axis_config_tdata = 16'b0101100101000110; 
  s_axis_data_tlast = 1;
  s_axis_data_tdata = 48'h000000;  
  s_axis_data_tvalid = 0;
/*
  #3000;
  aresetn = 0;
  #300;
  aresetn = 1;  
  m_axis_data_tready = 1;
  s_axis_config_tvalid = 1;
  s_axis_config_tdata = 16'b0101100101000110; // FFT desired (and not IFFT
  //s_axis_config_tdata = 24'b100100000000000111; // FFT desired (and not IFFT
*/
  s_axis_data_tlast = 1;
  s_axis_data_tdata = 48'h000000;  
  s_axis_data_tvalid = 0;


 s_axis_data_tvalid = 0;
 end

 reg ff;
 
  always @(posedge aclk)
 begin
	if(s_axis_data_tready == 1)
		ff <= 1'b1;
	else
		ff <= ff;
 
 end
 
 reg [9:0] cntttt=0;
 
 
   always @(posedge aclk)
 begin
	if(ff == 0)
		cntttt <= 10'b0;
	else if(cntttt==1023)
		cntttt <= cntttt;
	else
		cntttt <= cntttt+1;
 
 end
 
 
 always @(posedge aclk)
 begin
	//if((cntttt >= 800)&&(cntttt <= 814))
	if((cntttt >= 800)&&(cntttt <= 862))
	begin
		s_axis_data_tvalid <= 1;
		s_axis_data_tdata <=s_axis_data_tdata+1;
		s_axis_data_tlast <= 0;
	end
	//else if(cntttt == 815)
	else if(cntttt == 863)
	begin
		s_axis_data_tvalid <= 1;
		s_axis_data_tdata <=s_axis_data_tdata+1;
		s_axis_data_tlast <= 1;
	end		

   else
	begin
		s_axis_data_tvalid <= 0;
		s_axis_data_tdata <=0;
		s_axis_data_tlast <= 0;
	end
 end
 
  xfft_1024 uut (                                           
   .aclk(aclk), // input wire aclk
  // .aresetn(aresetn), // input wire aresetn
   .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 [63 : 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 [79 : 0] m_axis_data_tdata
 //  .m_axis_data_tuser(m_axis_data_tuser), // output wire [7 : 0] m_axis_data_tuser
   .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
 ); 
 wire [15:0] m_real,m_image; 

assign m_real = m_axis_data_tdata[15:0];
assign m_image  = m_axis_data_tdata[39:24];
 
endmodule

matlab:

N=64;
X=zeros(N,1);
for i=1:N
    X(i)=i;
end
FFTX=fft(X,N);
x_real=round(real(FFTX));
x_imag=round(imag(FFTX));

猜你喜欢

转载自blog.csdn.net/weixin_39813867/article/details/83861005
今日推荐