精华内容
下载资源
问答
  • FFT_XILINX实现

    2018-03-26 21:24:47
    使用Xilinx FPGA实现4096点的FFT变换,变换效果良好。
  • xilinx FFT

    2018-09-14 11:21:26
    基于xilinx公司提供的FFT核,编写了硬件测试代码,经测试所得结果与计算结果一致
  • xilinx FFT核手册

    2019-03-15 16:35:43
    The Xilinx® LogiCORE™ IP Fast Fourier Transform (FFT) core implements the Cooley-Tukey FFT algorithm, a computationally efficient method for calculating the Discrete Fourier Transform (DFT).
  • Xilinx FFT IP核

    2018-05-13 23:42:50
    Vivado Xilinx FFT 快速傅里叶变换IP核文档 详细介绍FFT9.0 IP核灾Vivado环境下的配置和使用 全英文 做通信实现相关的可以仔细读一读
  • Xilinx FFT IP使用介绍

    2021-04-07 14:18:50
    前言 暂不更新,仅是为日后有兴趣时提供一个学习方向。 感兴趣的可以阅读参考文献 参考文献 ...FPGADesigner《FPGA数字信号处理系列》目录与传送...Vivado Xilinx FFT IP核v9.0 使用详解(附仿真实例) ...

    前言

    暂不更新,仅是为日后有兴趣时提供一个学习方向。

    感兴趣的可以阅读参考文献

     

    参考文献

     

    FPGADesigner《FPGA数字信号处理系列》目录与传送门

    关于XILINX FPGA FFT IP核的学习笔记

    Vivado Xilinx FFT IP核v9.0 使用详解(附仿真实例)

     

     

     

     

     

    展开全文
  • FFT的分析和XILINX fft核的介绍

    千次阅读 2015-03-30 23:59:05
    fft输入输出解析。 输入:fft要求输入一个复数,但一般可以只输入实数。输出:输出一个复数,其模为信号强度。相位为波形相位。设: 采样频率FS 转换长度N 则: 分辨率为FS/N。 ‘量程’为-FS/2~FS/2 提高...


    fft输入输出解析。
    输入:fft要求输入一个复数,但一般可以只输入实数。

    输出:输出一个复数,其模为信号强度。相位为波形相位。

    设:
    采样频率FS
    转换长度N
    则:
    分辨率为FS/N。
    ‘量程’为-FS/2~FS/2
    提高采样频率则可提高量程,却会(在转换长度不变的情况下)降低分辨率。此时需要通过
    增加转换长度的方式增加分辨率,但却会增加处理时间。


    相关ip核:
    FFT V7.1:适用于Spartan3E系列,输入输出为wire或reg型。
    FFT V8.0:使用AXI_STREAM总线协议。
    FFT V9.0:使用AXI_STREAM总线协议,适用zyqn。


    fftV7.1 ip核仿真实例:
    开发环境:xilinx ISE+modelsim
    选择设备,添加ip核,编写仿真文件
    仿真文件如下
    module test;

        // Inputs
        reg clk;
        reg start;
        reg fwd_inv;
        reg fwd_inv_we;
        reg scale_sch_we;
        reg [15:0] xn_re;
        reg [15:0] xn_im;
        reg [11:0] scale_sch;
    
        // Outputs
        wire rfd,irfd;
        wire busy,ibusy;
        wire edone,iedone;
        wire done,idone;
        wire dv,idv;
        wire [9:0] xn_index;
        wire [9:0] xk_index;
        wire [9:0] ixn_index;
        wire [9:0] ixk_index;
        wire [15:0] xk_im_t;
        wire [15:0] xk_re_t;
        wire [15:0] ixk_im_t;
        wire [15:0] ixk_re_t;
        wire [32:0] out;
        wire signed [15:0] xk_re;
        wire signed [15:0] xk_im;
        wire signed [15:0] ixk_re;
        wire signed [15:0] ixk_im;
        wire [16:0] getifft;
    
        // Instantiate the Unit Under Test (UUT)
        fft 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)
        );
        complent inst1(ixk_re,ixk_re_t);
        complent inst2(ixk_im,ixk_im_t);
        assign out = ixk_re_t[14:0]*ixk_re_t[14:0]+ ixk_im_t[14:0]*ixk_im_t[14:0];
        sqrt your_instance_name (
          .x_in(out), // input [15 : 0] x_in
          .x_out(getifft), // output [8 : 0] x_out
          .clk(clk) // input clk
        );
        /*
        fft iuut (
            .clk(clk), 
            .start(dv), 
            .fwd_inv(~fwd_inv), 
            .fwd_inv_we(fwd_inv_we), 
            .scale_sch_we(0), 
            .rfd(irfd), 
            .busy(ibusy), 
            .edone(iedone), 
            .done(idone), 
            .dv(idv), 
            .xn_re(xk_re), 
            .xn_im(xk_im), 
            .scale_sch(0), 
            .xn_index(ixn_index), 
            .xk_index(ixk_index), 
            .xk_re(ixk_re), 
            .xk_im(ixk_im)
        );
        */
         ifft iuut (
            .clk(clk), 
            .start(dv), 
            .fwd_inv(~fwd_inv), 
            .fwd_inv_we(fwd_inv_we), 
            .rfd(irfd), 
            .busy(ibusy), 
            .edone(iedone), 
            .done(idone), 
            .dv(idv), 
            .xn_re(xk_re), 
            .xn_im(xk_im), 
            .xn_index(ixn_index), 
            .xk_index(ixk_index), 
            .xk_re(ixk_re), 
            .xk_im(ixk_im)
        );
    
    
        initial begin
            // Initialize Inputs
            clk = 0;
            start = 1;
            fwd_inv = 1;
            fwd_inv_we = 1;
            scale_sch_we = 1;
            xn_re = 0;
            xn_im = 0;
            scale_sch = 12'b101010101011;
    
            // Wait 100 ns for global reset to finish
            #100;
    
            // Add stimulus here
    
        end
    
        always #50
        begin
            xn_re[14]=(~xn_re[14]);
        end
        always #1
            clk=~clk; 
    endmodule
    
    
    
    module complent(
        input [15:0] complent,
        output [15:0] truecode
        );
        wire [14:0]temp1;
        wire [15:0]temp2;
        assign temp1=complent[15]==0?complent[14:0]:~(complent[14:0]);
        assign temp2={complent[15],temp1};
        assign truecode= temp2 + 1;
    
    
    endmodule
    

    使用modelsim结果如下
    输入波形
    输入波形
    fft输出波形,包括实部和虚部
    fft输出波形,包括实部和虚部
    ifft输出波形(实部和虚部),和经变换后的输出波形
    ifft输出波形(实部和虚部),和经变换后的输出波形

    展开全文
  • Xilinx FFT IP核 调试经验

    千次阅读 多人点赞 2018-11-20 10:21:23
    23333,这两天做FBMC FPGA的实现 入了XilinxFFT IP的坑,在此把遇到的痛苦经历记录下来,如有和我情况一样的拿走不谢。 话不多说,直接上经历。 1.FFT IP核无法进行8/16/32点的配置,意味着最少从64点起步。我...

    挺多人问我原工程,我就把它打包放网盘了,需要自取。
    链接:https://pan.baidu.com/s/1nDqoB2a1y-TZJhI3lfHXtQ
    提取码:tm26
    ———————————————————————以下原文————————————————————————————

    23333,这两天做FBMC FPGA的实现 入了Xilinx的FFT IP的坑,在此把遇到的痛苦经历记录下来,如有和我情况一样的拿走不谢。 话不多说,直接上经历。

    1.FFT IP核无法进行8/16/32点的配置,意味着最少从64点起步。我不知道是不是版本的问题,反正我和我同学的都是这样,脑阔疼。 我是2016.3的vivado版本。

    2.关于
    在这里插入图片描述

    切记,RESET一定要勾选,一定要,一定要!话说三遍,你不勾选自己去看后果吧,上电复位最少三个时钟切记。 关于这个XK_INDEX的话,这个会使得你在后续FFT处理中非常的方便。

    3.关于s_axis_config_tdata,这个是FFT的配置数据,形式在FFT IP Core说明书中是有的,只不过看的有点脑阔疼。告诉你个小窍门
    在这里插入图片描述
    看到了吗,在这个页面下,关于配置数据的格式是有定义的 ,你根据你的定义去进行修改即可。

    4.关于某时刻你发现输入的数据一切完好,但是输出却是XXXXXXX,mmp,很烦了。
    这是因为你FFT例化的问题,例化的时候一定要例化好,把原生的文件原生的端口一个不落的加进来

    fft fft_module (
      .aclk(aclk),                                                // input wire aclk
      .aresetn(reset),                                          // 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 [31 : 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 [31 : 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
      .m_axis_data_tuser(m_axis_data_tuser),                      // output wire [7 : 0] m_axis_data_tuser
      
       .event_fft_overflow(event_fft_overflow),                    // output wire event_fft_overflow
      .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
    );
    这样一般就ok了。
    

    5.关于AXIS协议。FFT 这么多线是不是头疼,其实如果你细心的话你会发现上面那个代码块被我分成了5部分。第一部分是时钟和复位,不再赘述,接下来是配置数据,输入端和输出端,最后是提示的一些信息。其中配置数据输入端和输出端是一样的协议。除了data外还有三根线axis_data_tvalid,axis_data_tready,axis_data_tlast。axis_data_tvalid是说向对方表示我数据准备好了,你可以进行传送了,axis_data_tready是对方向你说他数据准备好了可以传送了。通常在这两种都完成的情况下,数据就可以进行传送了,最后一根线axis_data_tlast是在最后一个数据时这个数据线拉高i,提示对方说我的数据传输完了。是这个意思。恩对。

    6.关于FFT和IFFT。不得不说FFT蛮准的,跟MATLAB基本差不多。但是IFFT就emmmmm…先看一组数据
    这个是仿真数据
    在这里插入图片描述
    这个是MATLAB做出来的结果
    在这里插入图片描述
    是不是感觉差别好大。。。 我心态都快炸了,感觉两个数据一点都不一样啊。但是你细心看,仿真得到的数据都等于MATLAB做出的数据乘以128,128是我的FFT点数,这样的话基本就ok了。原来这样子,IFFT做出来的结果统一要进行除以FFT点数的运算,才能得到和MATLAB一样的结果。

    7.关于缩放因子。是这样的,比如MATLAB求出来的这个数是56,如果你的缩放因子是6’b000011的话,那你仿真得到的结果就是56/(2^3)=7.

    行,大概就是这样子,有什么问题我再补充吧。接下来上一下测试代码和matlab生成需要变换数据文件的代码。要的,拿去。

    //测试代码
    `timescale 1ns / 1ps
    module tb();
    
    reg[15:0] memory[0:127];//申请128个16位的存储单元
    reg[11:0] n;
    initial
    	begin
    		$readmemb("F:/mem.txt",memory); //读取file1.txt中的数字到memory
    	    for(n=0;n<128;n=n+1)   //把八个存储单元的数字都读取出来,若存的数不到八个单元输出x态,程序结果中会看到
    		  $display("%b",memory[n]);
    	end
    
    reg aclk;
    reg reset;
    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 [63: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_fft_overflow;
    wire event_data_in_channel_halt;
    wire event_data_out_channel_halt;
    wire [63: 0] m_axis_data_tdata;
    wire [7:0]  m_axis_data_tuser;
    
    //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
    fft fft_module (
      .aclk(aclk),                                                // input wire aclk
      .aresetn(reset),                                          // 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 [31 : 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 [31 : 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
      .m_axis_data_tuser(m_axis_data_tuser),                      // output wire [7 : 0] m_axis_data_tuser
      
       .event_fft_overflow(event_fft_overflow),                    // output wire event_fft_overflow
      .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
    );
    
    // generate clk
    always #5 aclk =! aclk;
    
    initial
    begin
    		// Initialize Inputs
    		aclk = 0;
    		reset = 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;
    	      
    	    #200;
    	    reset = 1;
            // Wait 100 ns for global reset to finish
            #100;
            m_axis_data_tready = 1;
            s_axis_config_tvalid = 1;
            s_axis_config_tdata = 15'b0000000000000000; // FFT 
            s_axis_data_tdata = 64'b0;	
            s_axis_data_tvalid = 0;
            
         
           #1000;    
              for(n=0;n<128;n=n+1)
                  begin
                    #10
                    s_axis_data_tvalid <= 1;
                    s_axis_data_tdata <= {{48'b0},memory[n]};
                    $display("mem_a[%d] = %h", n, memory[n]);
                    if(n== 127)
                        s_axis_data_tlast <= 1;
                    else
                        s_axis_data_tlast <= 0;
                   end
          
            
            #10;
            s_axis_data_tlast <= 0;
            s_axis_data_tdata = 64'h0000;    
            s_axis_data_tvalid = 0;
      
     end
     
    wire [31:0] m_data_im;
    wire [31:0] m_data_re; 
     assign m_data_im = m_axis_data_tdata[63:32];
     assign m_data_re = m_axis_data_tdata[31:0];
    
    endmodule
    
    
    %MATLAB生成数据
    table = 0:127;
    trans_table = str2num(dec2bin(table));
    
    add = fopen('F:\mem.txt','w+');
    
    fprintf(add,'%016d \n',trans_table);
    
    fclose(add);
    

    接着,是在FPGA上实现的代码,我前边有一个FIR,从RAM里读数据给FFT然后再做运算,可以参考。

    `timescale 1ns / 1ps
    module FFT(
        //-------------------------输入-------------------------------------------------------------
        input               CLK_100M,
        input               reset,
        
        input    [31:0]     FFT_Data,
        input               FFT_im_re,          //前两个数是虚实还是实数虚数
        input    [11:0]     FIR_add,
        output              FFT_input_start,
        
        output reg  [11:0]     FFT_Data_address,  //需要第几个地址
        output      [15:0]     FFT_ans_add,  //输出地址
        output      [31:0]     FFT_ans_Data_re, //输出实部
        output      [31:0]     FFT_ans_Data_im, //输出虚部
        output                  FFT_ans_valid     //FFT输出有效
    );
    //----------------------------------------------------------------------------------------------------
    //                  IFFT例化
    wire                            s_axis_config_tready;
    
    reg         [63:0]              s_axis_data_tdata;
    reg                             s_axis_data_tvalid;
    wire                            s_axis_data_tready;
    reg                             s_axis_data_tlast;
    
    wire         [63:0]              m_axis_data_tdata;
    wire         [15: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;
    
    IFFT IFFT_Module (
      .aclk(CLK_100M),                                                // input wire aclk
      .aresetn(reset),                                               // input wire aresetn
      
      .s_axis_config_tdata(16'd0),                                // input wire [15 : 0] s_axis_config_tdata
      .s_axis_config_tvalid(1'b1),                                // 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 [63 : 0] m_axis_data_tdata
      .m_axis_data_tuser(m_axis_data_tuser),                      // output wire [15 : 0] m_axis_data_tuser
      .m_axis_data_tvalid(m_axis_data_tvalid),                    // output wire m_axis_data_tvalid
      .m_axis_data_tready(1'b1),                                  // 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
    );
    //---------------------------------------------------------------------------------------------------------------
    //                      开始进行IFFT   
    reg                 one_end_flag;
    always @ (posedge CLK_100M)
    begin
        if(FFT_Data_address == 12'd4095)
            s_axis_data_tvalid <= 1'b0;
        else if((FIR_add==12'd4095)&one_end_flag)
            s_axis_data_tvalid <= 1'b1;
    end
    //---------------------------------------------------------------------------------------------------------------
    //                      只进行一帧
    
    always @ (*)
    begin
        if(FFT_Data_address == 12'd4095)
            one_end_flag = 1'b0;
        else if(FIR_add==12'd4094)
            one_end_flag = 1'b1;
    end
    //---------------------------------------------------------------------------------------------------------------
    //                      生成取数地址
    reg [11:0]  FFT_Data_address_n;
    always @ (*)
    begin
        if(FFT_Data_address == 12'd4095)
            FFT_Data_address_n = 12'd0;
        else if(s_axis_data_tvalid&one_end_flag)
            FFT_Data_address_n = FFT_Data_address +1'b1;
        else
            FFT_Data_address_n = 12'd0;
    end
    
    always @ (posedge CLK_100M or negedge reset)
    begin
        if(!reset)
            FFT_Data_address = 12'd0;
        else
            FFT_Data_address <= FFT_Data_address_n ;
    end
    //---------------------------------------------------------------------------------------------------------------
    //                      虚实选择
    always @ (posedge CLK_100M)
    begin
        if(FFT_im_re)
            begin
                if(FFT_Data_address[0])
                    s_axis_data_tdata <= {FFT_Data,32'b0};
                else
                    s_axis_data_tdata <= {32'b0,FFT_Data};
            end
         else
             begin
                 if(FFT_Data_address[0])
                     s_axis_data_tdata <= {32'b0,FFT_Data};
                 else
                     s_axis_data_tdata <= {FFT_Data,32'b0};
             end
    end
    
    //---------------------------------------------------------------------------------------------------------------
    //                      最后一帧拉高
    always @ (posedge CLK_100M or negedge reset)
    begin
        if(!reset)
             s_axis_data_tlast <= 1'b0;
        else
            begin
                if(FFT_Data_address==12'd4094)
                    s_axis_data_tlast <= 1'b1;
                else
                    s_axis_data_tlast <= 1'b0;
            end
    end
    
    //---------------------------------------------------------------------------------------------------------------
    //                      输出端口赋值
    assign FFT_ans_add = m_axis_data_tuser;
    assign FFT_ans_Data_re = m_axis_data_tdata[31:0];
    assign FFT_ans_Data_im = m_axis_data_tdata[31:0];
    assign FFT_ans_valid = m_axis_data_tvalid;
    assign FFT_input_start = s_axis_data_tvalid;
    
    initial
    begin
        s_axis_data_tlast = 1'b0;
        s_axis_data_tdata = 64'd0;
        s_axis_data_tvalid = 1'b0;
        m_axis_data_tready = 1'b0;
        FFT_Data_address_n = 12'd0;
        one_end_flag = 1'b0;
    end
    
    endmodule
    
    

    最后,吐槽下CSDN难用的编辑器,让我编辑这篇文章编辑了两遍,谢谢你。

    展开全文
  • 1 xilinx FFT IP介绍Xilinx快速傅立叶变换(FFT IP)内核实现了Cooley-Tukey FFT算法,这是一种计算有效的方法,用于计算离散傅立叶变换(DFT)。1)...

    1 xilinx FFT IP介绍

    Xilinx快速傅立叶变换(FFT IP)内核实现了Cooley-Tukey FFT算法,这是一种计算有效的方法,用于计算离散傅立叶变换(DFT)。

    1)正向和反向复数FFT,运行时间可配置。

    2)变换大小N = 2m,m = 3 – 16

    3)数据采样精度bx = 8 – 34

    4)相位系数精度bw = 8 – 34

    5)算术类型:

    °无标度(全精度)定点

    °定标定点

    °浮点数

    6)定点或浮点接口

    7)蝴蝶后舍入或截断

    8)Block RAM或分布式RAM,用于数据和相位因子存储

    9)可选的运行时可配置转换点大小

    10)可扩展的定点核心的运行时可配置扩展时间表

    11)位/数字反转或自然输出顺序

    12)用于数字通信系统的可选循环前缀插入

    13)四种架构在内核大小和转换时间之间进行权衡

    14)位精确的C模型和用于系统建模的MEX功能可供下载

    15)有四种运算架构可供选择

    .Pipelined Streaming I/O

    .Radix-4 Burst I/O

    .Radix-2 Burst I/O

    .Radix-2 Lite Burst I/O

    2 FFT IP接口介绍

     

    图1 xilinx FFT IP

    1)AXI4-Stream 介绍

    AXI4-Stream接口带来了标准化,并增强了Xilinx IP LogiCORE解决方案的互操作性。除了诸如aclk,acclken和aresetn之类的常规控制信号以及事件信号之外,到内核的所有输入和输出都通过AXI4-Stream通道进行传输。通道始终由TVALID和TDATA以及必填字段和可选字段(如TREADY,TUSER和TLAST)组成。TVALID和TREADY一起执行握手以传输消息,其中有效负载为TDATA,TUSER和TLAST。内核对包含在TDATA字段中的操作数进行运算,并将结果输出到输出通道的TDATA字段中。

     

    图2 AXI4-Stream时序图

    图2显示了在AXI4-Stream通道中的数据传输。TVALID由通道的源(主)端驱动,而TREADY由接收器(从属)驱动。TVALID指示有效负载字段(TDATA,TUSER和TLAST)中的值有效。TREADY表示从机已准备好接收数据。当一个周期中的TVALID和TREADY均为TRUE时,将发生传输。主机和从机分别为下一次传输分别设置TVALID和TREADY。

    2)s_axis_config_tdata接口介绍

    s_axis_config_tdata接口携带配置信息CP_LEN,FWD / INV,NFFT和SCALE_SCH。

    NFFT(变换的点大小):NFFT可以是最大变换的大小或任何较小的点大小。例如,1024点FFT可以计算点大小1024、512、256等。NFFT的值为log2(点大小)。该字段仅在运行时可配置的转换点大小时出现。

    CP_LEN(循环前缀长度):从转换结束起,在输出整个转换之前,最初作为循环前缀输出的样本数。CP_LEN可以是小于点大小的从零到一的任何数字。该字段仅在循环前缀插入时出现。

    FWD_INV:指示是执行前向FFT变换还是逆向FFT变换(IFFT)。当FWD_INV = 1时,将计算前向变换。如果FWD_INV = 0,则计算逆变换。

    SCALE_SCH伸缩时间表:对于突发I / O架构,伸缩时间表由每个阶段的两位指定,第一阶段的伸缩由两个LSB给出。缩放比例可以指定为3、2、1或0,代表要移位的位数。N = 1024,Radix-4 Burst I / O的示例缩放计划是[1 0 2 3 2](从最后阶段到第一阶段排序)。对于N = 128,Radix-2 Burst I / O或Radix-2 Lite Burst I / O,一个可能的扩展时间表是[1 1 1 1 0 1 2](从最后阶段到第一阶段排序)。对于流水线I / O架构,从两个LSB开始,每两对Radix-2级用两位指定扩展时间表。例如,N = 256的缩放时间表可以是[2 2 2 3]。当N不是4的幂时,最后一级的最大位增长为一位。例如,对于N = 512,[0 2 2 2 2]或[1 2 2 2 2]是有效的缩放时间表,但是[2 2 2 2 2]无效。对于此变换长度,SCALE_SCH的两个MSB只能为00或01。此字段仅可用于缩放算法(非缩放,块浮点或单精度浮点)。

    s_axis_config_tdata接口格式:

    1.(可选)NFFT加填充

    2.(可选)CP_LEN加填充

    3.前转/后转

    4.(可选)SCALE_SCH

     

    举例:

    内核具有可配置的转换大小,最大大小为128点,具有循环前缀插入和3个FFT通道。内核需要配置为执行8点变换,并在通道0和1上执行逆变换,并在通道2上执行前向变换。需要4点循环前缀。这些字段采用表中的值。

     

    这给出了19位的向量长度。由于所有AXI通道必须与字节边界对齐,因此需要5个填充位,从而s_axis_config_tdata的长度为24位。

     

    3)相关标志信号

     

    3 xilinx FFT IP的仿真测试

     FFT的长度选择8点,x输入序列为x=[1,2,3,4,5,6,7,8];

    Matlab验证:

    clear all
    close all
    clc
     
    x = [1,2,3,4,5,6,7,8];
    y =fft(x,8);
    realy=real(y);
    imagy=imag(y);
    

     

    Y的实部输出为realy=[36,-4,-4,-4,-4,-4,-4,-4];

    Y的虚部输出为imagy=[0,9.6569,4,1.6569,0,-1.6569,-4,-9.6569];

    FPGA仿真验证:

    1)IP的设置

     

     

    2)仿真顶层

    `timescale 1ns / 1ps
    
    
     
    module tb_fft_top(
     
        );
        reg aclk;                        
        reg [7 : 0] s_axis_config_tdata;
        reg         s_axis_config_tvalid;        
        wire        s_axis_config_tready;       
        wire [31 : 0] s_axis_data_tdata;  
        reg         s_axis_data_tvalid;          
        wire        s_axis_data_tready;         
        reg         s_axis_data_tlast;           
        wire [31 : 0] m_axis_data_tdata;
        wire        m_axis_data_tvalid;         
        reg         m_axis_data_tready;  
        wire        m_axis_data_tlast;
        reg [15:0] real_data;
        reg [15:0] imag_data;
        wire [15:0] real_dataout;
        wire [15:0] imag_dataout;
        reg [9:0]  cnt;
        assign s_axis_data_tdata={real_data,imag_data};
        assign real_dataout = m_axis_data_tdata[31:16];
        assign imag_dataout = m_axis_data_tdata[15:0];
        initial begin
          aclk = 0;
          s_axis_config_tdata=8'b0;
          s_axis_config_tvalid=1'b0;
          s_axis_data_tvalid=1'b0;
          s_axis_data_tlast=1'b0;
          real_data=16'd0;
          imag_data=16'd0;
          cnt = 0;
          m_axis_data_tready=1'b1;
          #1000;
          s_axis_config_tdata=8'b0000_0001;
          s_axis_config_tvalid=1'b1;
          #10;
          s_axis_config_tdata=8'b0000_0000;
          s_axis_config_tvalid=1'b0;
          #1000;
          repeat(8)begin
            s_axis_data_tvalid=1'b1;
            real_data=real_data+16'd1;
            cnt=cnt+1;
            if(cnt==8) s_axis_data_tlast=1'b1;
            #10;
          end
          s_axis_data_tvalid=1'b0;
          s_axis_data_tlast=1'b0;
          real_data=16'd0;
          #1000;
          $stop;
        end
        always #(5) aclk= ~aclk;
    fft_top Ufft_top(
          .aclk(aclk),                                                // input wire aclk
          .s_axis_config_tdata(s_axis_config_tdata),                  // input wire [7 : 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 [31 : 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 [31 : 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       
              );
    endmodule
    

    3)仿真结果

     

    Vivado最终的仿真结果为

     Real=[36,-4,-4,-4,-4,-4,-4,-4];

     Imag=[0,-10,-4,-2,0,1,4,9];

    与matlab的计算结果相比实部一样,除虚部因为数据位的取舍问题以外,正数和负数部分顺序相反。

    展开全文
  • Xilinx FFT ip核使用例程

    千次阅读 热门讨论 2020-04-06 17:12:21
    近来开展FFT相关的研究,尝试了一下XilinxFFT IP核,再此分享一下; 源码不上传了(关键代码文中已有),有需要的请在评论区留下邮箱。 本例子的框架为: FFT IP核设置--> MATLAB生成模拟的正弦波并保存在...
  • xilinx fft ip核源代码及测试代码
  • IP核手册,需要的自行下载吧。这个手册详细解释了FFT的使用方法,非常详细。
  • Xilinx vivado FFT IP v9.0 详解

    万次阅读 多人点赞 2018-08-16 15:36:29
    Xilinx FFT IP v9.0 在线设置变换长度详解 IP介绍 FFT IP核支持三种数据类型: 1. 定点全精度 1. 定点缩减位宽 1. 块浮点 有四种可选择的FFT运算方式: 1. PipelinedStreaming I/O 1. Radix-4Burst I/O 1...
  • Xilinx FFT IP v9.0 使用

    万次阅读 热门讨论 2016-04-19 14:18:12
    该ip用于实现点FFT的变换, 实现的数学类型包括: A) 定点全精度 B) 定点缩减位宽 C) 块浮点 每一级蝶型运算后舍入或者取整。对于N点运算,FFT还是逆FFT,scaling策略以及循环前缀的长度是运行时可配置的,可随...
  • 自己阅读XILINX FFT IP核整理的中文文档 快速傅里叶变换v9.0 IP核指南 ——Vivado设计套件 介绍:Xilinx FFT IP核是一种计算DFT的有效方式。 特点:•前向变换(FFT)和反向变换(IFFT)在复数空间,并且可以在...
  • Xilinx vivado FFT IP核v9.0官方手册 pg109
  • XILINX FFT IP核的基本使用

    千次阅读 2019-08-10 13:18:32
    vivado中FFT IP核的基本使用 最近用vivado仿真时需要用到FFT IPCore,调通程序的过程中也遇到一些麻烦,在此将一些问题进行总结,希望可以帮到有需要的人。 - 配置阶段 在IP Catalog中搜索FFT,然后双击即可进入配置...
  • Xilinx FPGA FFT 应用笔记

    千次阅读 2018-08-08 15:19:35
    1024Hz的采样率采样1024点,刚好是1秒,也就是说,采样1秒时间的信号并做FFT,则结果可以分析到1Hz,如果采样2秒时间的信号并做FFT,则结果可以分析到0.5Hz。如果要提高频率分辨力,则必须增加采样点数,也即采样...
  • 本文及后续几篇文章,我们针对XilinxFFT IP核v9.0提供详细介绍。本文作为开篇,介绍以下内容: Xilinx FFT IP核的特性 Xilinx FFT IP核输入输出接口介绍 1.Xilinx FFT IP核特性 图1、Xilinx FFT IP核 Xilinx...
  • Xilinx FFT ip核的使用

    2020-07-14 19:29:33
    配置通道 Field Name Width Padded Description NFFT 5 Yes 传输点的长度,就是FFT变换的实际长度,其值:N= 2n2n2n2n2n 2^n2n2n2n(2NFFT​) No 简单点说,就是设置缩放倍数,比如 SCALE_SCH = [01 10 00 11 10]就...
  • 本文介绍了一种基于Xilinx IP核的FFT算法的设计与实现方法。在分析FFT算法模块图的基础上,以Xilinx Spartan-3A DSP系列FPGA为平台,通过调用FFT IP核,验证FFT算法在中低端FPGA中的可行性和可靠性。
  • xilinx FFT IP 9.0的使用

    千次阅读 2018-12-11 16:46:24
    对于N点运算,FFT还是逆FFT,scaling策略以及循环前缀的长度是运行时可配置的,可随帧改变,改变变换点数会复位FFT ip核。 有四种可选择的FFT的实现 架构 : 1) PipelinedStreaming I/O 2) Radix-4...
  • 这是vivado里面付费LTE-FFT IP核的技术文档,在xilinx官网上只能下载到此IP核的简略文档,此版本是详细文档,望有购买需求或者使用需求的开发人员能看到文档之后进一步对此IP核有多了解。
  • Xilinx_FFT_核的应用

    2013-04-25 17:01:19
    FFT的IP核使用介绍,如不会使用可以详细参考,里面内容很详细。
  • 笔者在校的科研任务,需要用FPGA搭建OFDM通信系统,而OFDM的核心即是IFFT和FFT运算,因此本文通过Xilinx FFT IP核的使用总结给大家开个头,详细内容可查看官方文档PG109。关于OFDM理论背景,可参考如下博文:给"小白...
  • Xilinx_LTE_FFT_V2.0

    2018-12-07 20:01:14
    根据官网申请的lte_fft V2.0的IP,管网就给了简单介绍,本数据手册给予了全面的介绍
  • Xilinx公司在Vivado开发工具中提供了FFT/IFFT的 IP核,供开发人员很方便的调用和使用,因此,本文主要对Vivado中的Xilinx FFT/IFFT IP核使用流程展开详细介绍。 1、FFT/IFFT IP核的创建 在使用FFT/IFFT IP核之前...
  • 采用c语言编写的二维傅里叶变换,对想要采用硬件Fpga实现的同学有一定的参考价值,目前在xilinx开发板上实现sdk处理fft2,效果还不错
  • 关于XILINXfft ip core的使用

    千次阅读 2019-04-12 17:48:29
    总结一下最近设计fft的经验和心得。 一开始知道需要用到fft,上知网下了一大堆文献,什么fft的设计类的,读了半天,需要每个模块单独写,当时只是一个菜鸟,啥都不懂。使劲看,先看算法吧,结果,看半天晕晕乎乎...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 176
精华内容 70
关键字:

fftxilinx