ZYNQ7020 FPGA FFT_IP核

FFT_IP核原理框图

ZYNQ7020 FPGA FFT_IP核_第1张图片

引脚定义:
aclk: 上升沿有效
aclken: 高电平时钟使能(可选)
aresetn: Active-Low同步清除(可选,始终优先于aclken)。需要两个周期的最小有效脉冲。
s_axis_config_tvalid:配置频道的TVALID。 由外部主设备发出信号,表明它能够提供数据。
s_axis_config_tready: TREADY作为配置通道。 核心声明表示已准备好接受数据。
s_axis_config_tdata: TDATA用于配置通道。携带配置信息:CP_LEN,FWD / INV,NFFT和SCALE_SCH。 请参阅运行时间转换配置。
s_axis_data_tvalid: 数据输入通道的TVALID。 由外部主设备用来表示它能够提供数据。
s_axis_data_tready: 数据输入通道的TREADY。核心用它来表示已经准备好接受数据。
s_axis_data_tdata: TDATA为数据输入通道。 载入未处理的采样数据:XN_RE和XN_IM。 请参阅数据输入通道。
s_axis_data_tlast: 数据输入通道的TLAST。 在框架的最后一个样本上由外部主设备声明。 除了生成事件event_tlast_unexpected和event_tlast_missing事件之外,核心不使用这个事件。
m_axis_data_tvalid: 数据输出通道的TVALID。 核心声明表示能够提供样本数据。
m_axis_data_tready: 数据输出通道的TREADY。由外部从设备断言,表示已准备好接受数据。 仅以非实时模式呈现。
m_axis_data_tdata: TDATA为数据输出通道。载入处理后的样本数据XK_RE和XK_IM。
m_axis_data_tuser: 用于数据输出通道的TUSER。携带附加的每个样本信息,例如XK_INDEX,OVFLO和BLK_EXP。
m_axis_data_tlast: 数据输出通道的TLAST。在框架的最后一个样本上由核心声明。
m_axis_status_tvalid: 状态通道的TVALID。核心声明表示它能够提供状态数据。
m_axis_status_tready: TREADY用于状态通道。由外部从设备断言,表示已准备好接受数据。 仅以非实时模式呈现。
m_axis_status_tdata: TDATA的状态通道。携带状态数据:BLK_EXP或OVFLO.See状态通道。
event_frame_started: 当核开始处理一个新的帧时声明。请参阅event_frame_started。
event_tlast_unexpected: 当内核在不是帧中最后一个数据采样的s_axis_data_tlast为高电平时触发。请参阅event_tlast_unexpected。
event_tlast_missing: 在帧的最后一个数据样本上s_axis_data_tlast为低时断言。 请参阅event_tlast_missing。
event_fft_overflow: 在从数据输出通道卸载的数据样本中发现溢出时断言。 只有当溢出是一个有效的选项时才出现。 请参阅event_fft_overflow。
event_data_in_channel_halt: 内核从数据输入通道请求数据并且没有可用时声明。 请参阅event_data_in_channel_halt。
event_data_out_channel_halt: 当内核尝试将数据写入数据输出通道并且无法执行时声明。 仅以非实时模式呈现。 请参阅event_data_out_channel_halt。
event_status_channel_halt: 当内核尝试将数据写入状态通道并且无法执行时断言。 仅以非实时模式呈现。 请参阅event_status_channel_halt。

IP核测试调用过程:
第一步:添加IP核(通过在project manager中的IP Catalog中添加IP核)

ZYNQ7020 FPGA FFT_IP核_第2张图片

第二步:在Hierarchy->simulation source目录下添加测试代码

ZYNQ7020 FPGA FFT_IP核_第3张图片

运行仿真即可

ZYNQ7020 FPGA FFT_IP核_第4张图片

需注意:
configuration:选择通道时可选择1个通道、传输长度为数据长度。

ZYNQ7020 FPGA FFT_IP核_第5张图片

implementation:可选择数据类型和unscaled选项。

ZYNQ7020 FPGA FFT_IP核_第6张图片

Detailed Implementation:可不用配置。

ZYNQ7020 FPGA FFT_IP核_第7张图片

切记:
对IP核进行配置时,不可将IP核在初始化后直接将数据类型配置为浮数,需从定点->浮数按部就班配置,否则直接将IP核第一次配置为浮数型会失败,无法生成框架代码。。

配置示例1:(定数)

number of channel :1
Transform length : 8
data Format : fixed point
scaling options : unsclaed
rounding modes : truncation
input data width : 16
phase factor width : 16

**代码配置:(测试代码中)
只做重要部分解释:**


module fft_test_bench( );
        reg aclk;  
        reg s_axis_config_tvalid;  
        reg s_axis_data_tvalid;  
        reg s_axis_data_tlast;  
        reg m_axis_data_tready;  
        reg [7:0] s_axis_config_tdata;  
        reg [31: 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_data_in_channel_halt;  
        wire event_data_out_channel_halt;  
        wire [47 : 0] m_axis_data_tdata;  

       reg[15:0] mem0_re[0:7];  
       reg[15:0] mem1_re[0:7];  
       reg[15:0] mem2_re[0:7];  
        initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus0_24bit.dat",mem0_re);  
        initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus1_24bit.dat",mem1_re);  
        initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus2_24bit.dat",mem2_re);  

//        reg[7:0]   op_sample= 0;  
//        reg        op_sample_first = 1;  
//        reg[7:0]   ip_frame=0;  
//        reg[7:0]   op_frame=0;  

        integer i;  

        // generate clk  
        always #5 aclk =! aclk;  

        // Instantiate the Unit Under Test (UUT)  
    xfft_1 uut (  
          .aclk(aclk),                                                // input wire aclk  
          .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 [95 : 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 [95 : 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  
          .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  
        );  

        initial begin  
            // Initialize Inputs  
            aclk = 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;  

            // Wait 100 ns for global reset to finish  
            #150;  
            m_axis_data_tready = 1;  
            s_axis_config_tvalid = 1;  
            //s_axis_config_tdata = 16'b0101100101011011; // FFT desired (and not IFFT  
            s_axis_config_tdata = 8'b00000011; // FFT desired (and not IFFT  

            //s_axis_data_tlast = 1;  
            s_axis_data_tdata = 32'h0000;   
            s_axis_data_tvalid = 0;  


            begin  
              for(i=0;i<8;i=i+1)  
                  begin  
                    #10  
                    s_axis_data_tvalid <= 1;  
                    s_axis_data_tdata <= {{16'h00},mem0_re[i]};  
                    $display("mem_a[%d] = %h", i, mem0_re[i]);  
    //              if(i== 256)  
    //                  s_axis_data_tlast <= 1;  
    //              else  
    //                  s_axis_data_tlast <= 0;  
                    end  

            end  
            #10;  
            s_axis_data_tdata = 32'h0000;   
            s_axis_data_tvalid = 0;  
            #1000 $finish;    
            //$stop  

        end  
endmodule

配置示例2:(浮数)
注意:
该浮数遵循IEEE 754 32位单精度规则!!!!
配置过程:
将其Implementstion选项中data format类型选择为floating point类型,其他可不做变更。
ZYNQ7020 FPGA FFT_IP核_第8张图片
ZYNQ7020 FPGA FFT_IP核_第9张图片
ZYNQ7020 FPGA FFT_IP核_第10张图片
由于输入的数据长度为64为,需修改其测试代码为:

module fft_test_bench(

    );
    reg aclk;  
            reg s_axis_config_tvalid;  
            reg s_axis_data_tvalid;  
            reg s_axis_data_tlast;  
            reg m_axis_data_tready;  
            reg [7: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_data_in_channel_halt;  
            wire event_data_out_channel_halt;  
            wire [63 : 0] m_axis_data_tdata;  

           reg[31:0] mem0_re[0:7];  
//           reg[32:0] mem1_re[0:7];  
//           reg[32:0] mem2_re[0:7];  
            initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus0_32bit.dat",mem0_re);  
//            initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus1_32bit.dat",mem1_re);  
//            initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus2_32bit.dat",mem2_re);  

    //        reg[7:0]   op_sample= 0;  
    //        reg        op_sample_first = 1;  
    //        reg[7:0]   ip_frame=0;  
    //        reg[7:0]   op_frame=0;  

            integer i;  

            // generate clk  
            always #5 aclk =! aclk;  

            // Instantiate the Unit Under Test (UUT)  
        xfft_0 uut (  
              .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 [15 : 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
         .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
            );  

            initial begin  
                // Initialize Inputs  
                aclk = 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;  

                // Wait 100 ns for global reset to finish  
                #150;  
                m_axis_data_tready = 1;  
                s_axis_config_tvalid = 1;  
                //s_axis_config_tdata = 16'b0101100101011011; // FFT desired (and not IFFT  
                s_axis_config_tdata = 8'b00000011; // FFT desired (and not IFFT  

                //s_axis_data_tlast = 1;  
                s_axis_data_tdata = 64'h0000;   
                s_axis_data_tvalid = 0;  


                begin  
                  for(i=0;i<8;i=i+1)  
                      begin  
                        #10  
                        s_axis_data_tvalid <= 1;  
                        s_axis_data_tdata <= {{32'h00},mem0_re[i]};  
                        $display("mem_a[%d] = %h", i, mem0_re[i]);  
        //              if(i== 256)  
        //                  s_axis_data_tlast <= 1;  
        //              else  
        //                  s_axis_data_tlast <= 0;  
                        end  

                end  
                #10;  
                s_axis_data_tdata = 64'h0000;   
                s_axis_data_tvalid = 0;  
                #1000 $finish;    
                //$stop  

            end  
endmodule

运行仿真后就可完成测试。测试结果为:
ZYNQ7020 FPGA FFT_IP核_第11张图片
将得到的数据结果进行转换后与matlab计算出的结果进行对比 ,精度极高!!!!

————————————————————————–
延时对比:
一、读取数据
——定点:——

ZYNQ7020 FPGA FFT_IP核_第12张图片

——浮数——

ZYNQ7020 FPGA FFT_IP核_第13张图片

时间均在170ns读取数据!

二、输出数据
——定点——

ZYNQ7020 FPGA FFT_IP核_第14张图片

——浮数——

ZYNQ7020 FPGA FFT_IP核_第15张图片

从图中可以观看到定点处理在705ns时开始输出数据,浮数处理在1005ns时开始输出数据,存在300ns的延时,可能随着具体ZYNQ的频率延时发生改变!!!

你可能感兴趣的:(FPGA数字信号,fft,fpga)