基于vivado 2015.4 的FFT IP核仿真

小弟最近毕业论文在做OFDM方面的研究,用到了vivado中的FFT IP核,发现网上现有的也只是介绍了一些接口,而且大部分给的代码跑不出来,所以对自己使用该IP核做一些总结,并附上代码和matlab的仿真结果,欢迎大家批评指正一起学习进步。

关于OFDM这篇文章很详细可以看看
给"小白"图示讲解OFDM的原理

首先打开vivado找到FFT IP点击打开
在这里插入图片描述
之后弹出对话框,需要配置的参数有三个标签页,需要一一配置

关于一些端口的说明:

s_axis_config_tdata:控制输入模式,进行fft/ifft以及衰减因子的设置,第0位为1fft,为0做ifft,高位用于scale因子的设置。

s_axis_config_tvalid:拉高若干个时钟周期后归零,之后将s_axis_data_tvalid拉高

s_axis_config_tready:s_axis_config_tvalid拉高两个时钟周期后,该口给1输出;

s_axis_data_tready:s_axis_config_tvalid拉高两个时钟周期后,该口给1输出,ip核初始化完成,可进行数据输入必须进行赋值;

s_axis_data_tvalid:拉高64个周期,输入64个数据进行fft;

s_axis_data_tdata:输入32位数据

s_axis_data_tlast:输入64个数据后拉高,停止数据输入;

第一个标签页里主要配置通道数,点数,时钟,吞吐量,结构,以及是否可以运行时配置,需要注意的是结构的配置会影响调整因子。
在这里插入图片描述
有四种可选择的FFT运算方式:

  1. PipelinedStreaming I/O

  2. Radix-4Burst I/O

  3. Radix-2Burst I/O

  4. Radix-2 Lite Burst I/O

在这里我选择的是Radix-4Burst I/O(基4—突发式),64点,100Mhz

第二页下可设置FFT的数据格式为定点Fixed Point或浮点Float Point;输出截位方式选择:不截位(Unscaled),截位(Scaled),块浮点(Block Floating Point);设置输入数据的位宽和相位因子位宽。还有一些可选的附加信号,如时钟使能(ACLKEN),复位信号(ARESETn,低有效)等。“Output Ordering”用以选择FFT计算结果以自然顺序(Nature Order)或位倒序(Bit/Digit Reversed Order)输出。在这里插入图片描述
在这里我选择的是不截位,自然顺序

第三配置页主要配置内部数据块的使用和优化的方式。

所有这些配置完成后,可以左侧一列中察看配置的结果,IP Symbol中主要察看各种接口,Implementation Detals 中有较多的信息,比如结构,长度,数据宽度等,需要注的是CONFIG TDATA这一项,与配置接口的参数有关,在使用中需要正确配置。在当前的配置, FWD_INV使用1bit,为1时,做FFT;为0时做IFFT;由于选取的是不截位所以也不需要设置缩放因子,如果选取截位则不同的结构调整因子不同,详细的可以参看FFT的核文献。
在这里插入图片描述
在左侧有Latency这一栏,切忌如果你有多组64个数据,每一组的输入间隔务必大于这个数据处理时间(2.450us),否则仿真会出错。

最后附上代码(完全可以运行):仿真采用1~64循环输入间隔要大于数据处理时间

FFT代码:

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2020/08/04 14:33:42

// Design Name:

// Module Name: FFT1

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

module FFT1(

input aclk,

input aresetn,

input en,

output [15:0]Out_Re,

output [15:0]Out_Im,

output out_En

);

reg [7:0] s_axis_config_tdata=8'b00000001;

reg s_axis_config_tvalid;

wire s_axis_config_tready;

reg [31 : 0] s_axis_data_tdata=0;

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;

always @(posedge aclk)

begin

if(en)

begin

s_axis_config_tvalid = 0;

s_axis_data_tlast = 0;

  m_axis_data_tready = 0;

end

else

begin



m_axis_data_tready = 1;

    s_axis_config_tvalid = 1;

        s_axis_data_tlast = 1;

end

end



reg [9:0] cntttt=0;

always @(posedge aclk)

begin

if((cntttt >= 200)&&(cntttt <= 262))

begin

s_axis_data_tvalid <= 1;

s_axis_data_tdata <=s_axis_data_tdata+1;

s_axis_data_tlast <= 0;

cntttt<= cntttt+1;

end

else if( (cntttt>=0)&&(cntttt<=199))

begin

s_axis_data_tvalid <= 0;

            s_axis_data_tdata <=0;

            s_axis_data_tlast <= 0;

            cntttt<= cntttt+1;

      end     

else if(cntttt == 263)

begin

s_axis_data_tvalid <= 1;

s_axis_data_tdata <=s_axis_data_tdata+1;

s_axis_data_tlast <= 1;

cntttt<= cntttt+1;

end

  else if((cntttt>=264)&&(cntttt<=480))//为了比数据处理时间高

  begin

        s_axis_data_tvalid <= 0;

          s_axis_data_tdata <=0;

          s_axis_data_tlast <= 0;

          cntttt<= cntttt+1;

  end

  else

begin

    cntttt<=200;

s_axis_data_tvalid <= 0;

s_axis_data_tdata <=0;

s_axis_data_tlast <= 0;

end

end

  xfft_0 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(out_En), // 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

);

assign  Out_Re = m_axis_data_tdata[15:0];

assign  Out_Im  = m_axis_data_tdata[39:24];

endmodule

测试代码

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2020/08/04 14:14:07

// Design Name:

// Module Name: tset

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

module tset;

reg clk1=1;

reg aresetn;

reg en;

wire [15:0] Out_Re;

wire [15:0] Out_Im;

wire out_En;

initial begin

aresetn=0;

en=1;

#150

aresetn=1;

en=0;

end

always#5 clk1=!clk1;

FFT1 FFT(clk1,aresetn,en,Out_Re,Out_Im,out_En);

endmodule

仿真结果:

在这里插入图片描述

Matlab仿真程序:

N=64;

X=zeros(1,N);

for i=1:N;

    X(i)=i;

end

Y=fft(X)

X_real=real(Y)

X_imag=imag(Y)

Matlab仿真结果:

在这里插入图片描述
在这里插入图片描述
可以看出仿真结果几乎一致

最后本文只介绍了FFT的结果,自己在做IFFT时结果和matlab结果差距很大也不知道问题在哪,欢迎各位大佬讨论补充。

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值