xilinx FFT IP 9.0的使用

本文详细介绍了64点FFT IP核的功能、架构及配置方法。涵盖IP核的信号线分类、AXI4-Stream总线工作原理、状态线功能解析及在线修改变换点数的步骤。附带Verilog实现代码与MATLAB验证程序,展示数据的良好一致性。
摘要由CSDN通过智能技术生成

参考博客:       https://blog.csdn.net/shichaog/article/details/51189711

                         https://blog.csdn.net/qq_36375505/article/details/81742680

                         https://blog.csdn.net/yanshanyan/article/details/82386575

1、IP基础知识:

该ip用于实现N=2**m(m=3~16)点FFT的变换,

实现的数学类型包括:

A)      定点全精度

B)      定点缩减位宽

C)      块浮点

每一级蝶型运算后舍入或者取整。对于N点运算,FFT还是逆FFT,scaling策略以及循环前缀的长度是运行时可配置的,可随帧改变,改变变换点数会复位FFT ip核。

有四种可选择的FFT的实现架构

1)  PipelinedStreaming I/O

2)  Radix-4Burst I/O

3)  Radix-2Burst I/O

4) Radix-2 Lite Burst I/O

FFTip核使用基二和基四分解法计算离散傅里叶变换,对于Burst I/O architectures采用时域抽取法实现,对于Pipelined Streaming I/Oarchitecture.使用频域抽取法。当使用基四计算时,其蝶型算法的级数是log 4 (N),每一级包括N/4的基四蝶型运算。对于点数不是4的指数情况,则需要一个额外的基二来组合数据。类似的基二实现法需要log 2 (N)级蝶型运算。对于scaling方法,其每一级的scaling因子由s_axis_config_tdata来配置。Ip核的端口如下:

2、各端口介绍

整个IP的信号线可以分为三个部分:

  • 三个AXI4-Stream的总线分别完成数据的输入输出和命令的输入。
  • 时钟线和复位线是IP核的基本信号。
  • 之后是一大堆的状态线,以event开头,标志了IP核的不同状态和遇到的各种问题。

下面简单说明一下AXI4-Stream:

  • 总的来说AXI4-Stream总线分为主(一般开头带个m)从(一般开头带个s)两部分组成。一个主连接一个从,形成了一个严密的握手结构。在整个通信过程中,tdata是数据的通路,tready、tvalid两个信号分别由一个主一个从控制,主(或从)准备好接受(或发送)数据时,会拉高自己控制的信号线,如果两边都准备好了(即两个线都拉高了)开始传数据。tlast信号的作用是:当前的数据是一组数据的最后一个时tlast信号会拉高,用于数据对齐,同时还有一定的数据判错作用。还有一个tuser信号,会表明当前周期传递的信号是第几个数据。

各个状态线及其作用:

  • event_frame_started:每一新的次fft开始时上跳一次。 

  • event_tlast_unexpected:当s_axis_data_tlast上跳,但IP核认为这并不是最后一个数据时上跳一次。 

  • event_tlast_missing:当IP核认为这是最后一个数据,但s_axis_data_tlast还是低的时候,该信号上跳。 

  • event_fft_overflow:在从数据输出通道输出的数据样本中发现溢出时上跳。只有当overflow选项被选择有效时才出现。 

  • event_data_in_channel_halt:当IP核需要新的输入数据但输入口并没有提供足够的数据时拉高。 

  • event_data_out_channel_halt:当 IP核尝试输出数据但无法输出时(可能时输出对象没有给IP核输出接收使能信号)拉高。只在Non-Realtime 模式下有效。 

  • event_status_channel_halt:当 IP核尝试输出数据到状态通道但无法输出时拉高。只在Non-Realtime 模式下有效。

在线修改变换点数。

  • 在设置正确之后,修改变换点数非常简单,只要拉低复位线3个时钟周期以上,之后送入配置命令即可。

其他信号

  • Aclk输入时钟,上升沿有效
  • Aclken :使用有效信号,高使能
  • Aresetn:同步复位信号,低电平有效(至少保持aclk两个时钟周期)
  • s_axis_config_tdata:包括配置信息,CP_LEN, FWD/INV, NFFT,SCALE_SCH. 

3、IP 的datasheet

4、配置IP 

1)

2) 

3) 

5、程序: 

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/10 17:16:18
// Design Name: 
// Module Name: xfft_64text
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


//module xfft_64text(aclk,aresetn,s_axis_config_tdata,s_axis_data_tlast,s_axis_data_tready,s_axis_config_tvalid,s_axis_config_tready,s_axis_data_tvalid,s_axis_data_tdata,m_axis_status_tready,m_axis_data_tdata,
//m_axis_data_tuser,m_axis_data_tvalid,m_axis_data_tready,m_axis_data_tlast,m_axis_status_tdata,m_axis_status_tvalid,event_frame_started,event_tlast_unexpected,event_tlast_missing,event_fft_overflow,
//event_status_channel_halt,event_data_in_channel_halt,event_data_out_channel_halt);
  
//    input aclk;
//    input aresetn;
//    input [7:0] s_axis_config_tdata;
//    input s_axis_data_tlast;
//    output s_axis_data_tready;
//    output s_axis_config_tready;
//    input s_axis_config_tvalid;
//    input s_axis_data_tvalid;
//    input [31:0] s_axis_data_tdata;
//    input m_axis_status_tready;
//    output [31:0] m_axis_data_tdata;
//    output [15:0] m_axis_data_tuser;
//    output m_axis_data_tvalid;
//    input  m_axis_data_tready;
//    output m_axis_data_tlast;
//    output [7:0] m_axis_status_tdata;
//    output m_axis_status_tvalid;
//    output event_frame_started;
//    output event_tlast_unexpected;
//    output event_tlast_missing;
//    output event_fft_overflow;
//    output event_status_channel_halt;
//    output event_data_in_channel_halt;
//    output event_data_out_channel_halt;

//    xfft_64 xfft_64(
    
//        .aclk(aclk),
//        .aresetn(aresetn),
//        .s_axis_config_tdata(s_axis_config_tdata),
//        .s_axis_data_tlast(s_axis_data_tlast),
//        .s_axis_data_tready(s_axis_data_tready),
//        .s_axis_config_tready(s_axis_config_tready),
//        .s_axis_config_tvalid(s_axis_config_tvalid),
//        .s_axis_data_tvalid(s_axis_data_tvalid),
//        .s_axis_data_tdata(s_axis_data_tdata),
//        .m_axis_status_tready(m_axis_status_tready),
//        .m_axis_data_tdata(m_axis_data_tdata),
//        .m_axis_data_tuser(m_axis_data_tuser),
//        .m_axis_data_tvalid(m_axis_data_tvalid),
//        .m_axis_data_tready(m_axis_data_tready),
//        .m_axis_data_tlast(m_axis_data_tlast),
//        .m_axis_status_tdata(m_axis_status_tdata),
//        .m_axis_status_tvalid(m_axis_status_tvalid),
//        .event_frame_started(event_frame_started),
//        .event_tlast_unexpected(event_tlast_unexpected),
//        .event_tlast_missing(event_tlast_missing),
//        .event_fft_overflow(event_fft_overflow),
//        .event_status_channel_halt(event_status_channel_halt),
//        .event_data_in_channel_halt(event_data_in_channel_halt),
//        .event_data_out_channel_halt(event_data_out_channel_halt)
//    );
//endmodule
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/10 17:07:53
// Design Name: 
// Module Name: xfft_64_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module xfft_64text( 
        input  aclk,
        input  aresetn,
        input [15:0] xn_im,
        input [15:0] xn_re,
        input s_axis_data_tvalid,
        input s_axis_data_tlast,
        input s_axis_config_tvalid,
        
        
        output s_axis_data_tready,
        output  [15:0]   xk_im,
        output  [15:0]   xk_re,
        output m_axis_data_tvalid
        
    );
          
       
        
        wire [7 : 0] s_axis_config_tdata = 8'b0000001;
        wire [31:0] m_axis_data_tdata;
      
      
        
        wire [15:0] m_axis_data_tuser;
        wire    m_axis_data_tlast;     
        wire    s_axis_config_tready;
        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;
        
        wire [31:0] s_axis_data_tdata = {xn_im,xn_re};       
        assign  {xk_im,xk_re} = m_axis_data_tdata;
        
        xfft_64 usr_FFT(
    
                .aclk(aclk),
                .aresetn(aresetn),
    
                .s_axis_config_tdata(s_axis_config_tdata),
                .s_axis_config_tvalid(s_axis_config_tvalid),
                .s_axis_config_tready(s_axis_config_tready),
    
                .s_axis_data_tdata(s_axis_data_tdata),
                .s_axis_data_tvalid(s_axis_data_tvalid),
                .s_axis_data_tready(s_axis_data_tready),
                .s_axis_data_tlast(s_axis_data_tlast),
    
                .m_axis_data_tdata(m_axis_data_tdata),
                .m_axis_data_tuser(m_axis_data_tuser),
                .m_axis_data_tvalid(m_axis_data_tvalid),
                .m_axis_data_tready(1'b1),
                .m_axis_data_tlast(m_axis_data_tlast),
    
                .event_frame_started(event_frame_started),
                .event_tlast_unexpected(event_tlast_unexpected),
                .event_tlast_missing(event_tlast_missing),
                .event_status_channel_halt(event_status_channel_halt),
                .event_data_in_channel_halt(event_data_in_channel_halt),
                .event_data_out_channel_halt(event_data_out_channel_halt)
        );   

    
 

endmodule

测试程序:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/10 17:07:53
// Design Name: 
// Module Name: xfft_64_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module xfft_64_tb();
       reg  aclk;
       reg  aresetn;
       wire [15:0] xn_im;
       wire [15:0] xn_re;
       reg s_axis_data_tvalid;
       reg s_axis_data_tlast;
       reg s_axis_config_tvalid;
       reg [7:0] dat_c;   
       wire s_axis_data_tready;
       wire  [15:0]   xk_im;
       wire  [15:0]   xk_re;
       wire  m_axis_data_tvalid;
   
     
       
    integer handle1;
    initial
        begin//sequence block 
          
          handle1 =$fopen("C:/Users/lyw/Desktop/fsave.txt");       
          #200000  $fclose(handle1);
          $stop;
        end 
    

    initial  begin
        aclk = 0;
        s_axis_data_tvalid = 0;
        s_axis_data_tlast = 0;
        s_axis_config_tvalid = 0;
        dat_c = 8'b0;
        aresetn=0;
        #200 aresetn = 1;

        forever #10 aclk = ~aclk;        
    end

    reg [15:0]  cnt=0;
    reg [15:0] index = 0;
    always @(posedge aclk)
    begin
        if(aresetn)
            begin
                cnt <= cnt + 1'b1;
                if(cnt == 0)     
                    begin     
                        s_axis_config_tvalid  <=1;    
                    end
                else if(cnt == 3)
                    s_axis_config_tvalid  <= 0;
                else if(cnt == 6)
                    begin    
                        s_axis_data_tvalid <= 1;
                        dat_c <= 0;
                        index = 0;
                    end        
                else if(cnt == 16'd69)
                    begin        
                        s_axis_data_tlast <= 1'b1;                
                        dat_c <= (dat_c + 4'b1000);                
                    end
                else if(cnt == 16'd70)
                    begin
                        s_axis_data_tvalid <= 1'b0;
                        s_axis_data_tlast <= 1'b0;
                    end
               
                else
                    begin            
                        
                        dat_c <=(dat_c + 4'b1000);                
                    end
                
                if(s_axis_data_tvalid)
                    index <= index +1;
            end
    end 
 
    always @(posedge aclk)
    begin
        if(s_axis_data_tvalid)        
            $fwrite(handle1,"%d %d \n",xn_re,xn_im);  
        else if(m_axis_data_tvalid)        
            $fwrite(handle1,"%d %d \n",xk_re,xk_im);        
    end
    
    
     assign xn_re ={13'b0,{dat_c[7]? ~dat_c[7:4] : dat_c[7:4]}};
     assign xn_im =0;
     
    xfft_64text xfft_64_inst(
           .aclk(aclk),
           .aresetn(aresetn),
           .xn_im(xn_im),
           .xn_re(xn_re),
           .s_axis_data_tvalid(s_axis_data_tvalid),
           .s_axis_data_tlast(s_axis_data_tlast),
           .s_axis_config_tvalid(s_axis_config_tvalid),
           .s_axis_data_tready(s_axis_data_tready),
           .xk_im(xk_im),
           .xk_re(xk_re),
           .m_axis_data_tvalid(m_axis_data_tvalid)
           );
endmodule

matlab:验证程序

clear;
 
file_name='C:/Users/lyw/Desktop/fsave.txt';
fid = fopen(file_name,'r');
c = fscanf(fid,'%d');
fclose(fid);
%有符号数
 for i=1: length(c)
    if(c(i)>32767)
        b(i) =  c(i)-65536;
    else b(i) =  c(i);
    end
end
d1=b(1:2:end);
d2=b(2:2:end);
comp1=d1(1:64) + j*d2(1:64);
comp2=d1(65:128) + j*d2(65:128);
 
c1avr=sum(comp1)/length(comp1);
c1=comp1-c1avr;
%  c1=comp1;
 
c1fft=abs(fft(c1,64));
c2fft=abs(comp2);
plot(c1);
figure
subplot(2,1,1);
plot(c1fft);
subplot(2,1,2);
plot(c2fft);
figure
subplot(2,1,1);
plot(c1fft(1:20));
subplot(2,1,2);
plot(c2fft(1:20));

 结果:

数据表现了良好的一致性;

注:其实数据不是很完美,

输出的第一个数据是224,要是0则数据很一致,原因正在寻找中。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值