zoukankan      html  css  js  c++  java
  • Xilinx FFT IP v9.0 使用

    该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核的port例如以下:

    输入输出方向在上图中已经非常明显了,以下描写叙述port作用

    Aclk输入时钟。上升沿有效

    Aclken :使用有效信号,高使能

    Aresetn:同步复位信号,低电平有效(至少保持aclk两个时钟周期)

    s_axis_config_tdata:包含配置信息,CP_LEN, FWD/INV, NFFT,SCALE_SCH.

    上面信号全部s開始的表示的是axi信号的slave端,m是master端。

    各信号作用參考《Fast Fourier Transform v9.0 LogiCORE IP Product Guide》

    以8点FFT示意,configure

    implementtation


    summary


    因为xilinx自带的testbench是VHDL的。这里给出自己写的verilog版本号的testbench。

    `timescale 1ns / 1ps
    //////////////////////////////////////////////////////////////////////////////////
    // Company: 
    // Engineer: shichaog
    // 
    // Create Date: 04/13/2016 08:35:42 PM
    // Design Name: 
    // Module Name: TB_fft256
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //////////////////////////////////////////////////////////////////////////////////
    module TB_fft256;
    	// Inputs
    	reg aclk;
    	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 [95: 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 [95 : 0] m_axis_data_tdata;
    	
    	reg[23:0] mem0_re[0:7];
    	reg[23:0] mem1_re[0:7];
        reg[23:0] mem2_re[0:7];
    	initial $readmemh("/home/gsc/FPGA_exercise/bf_verilog/stimulus0_24bit.dat",mem0_re);
    	initial $readmemh("/home/gsc/FPGA_exercise/bf_verilog/stimulus1_24bit.dat",mem1_re);
    	initial $readmemh("/home/gsc/FPGA_exercise/bf_verilog/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_256 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 = 16'b0000000000000111; // FFT desired (and not IFFT
    		
    		//s_axis_data_tlast = 1;
    		s_axis_data_tdata = 96'h000000;	
    		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 <= {{24'h000000},mem1_re[i],{24'h000000},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 = 96'h000000;	
            s_axis_data_tvalid = 0;
    		#1000 $finish;  
    		//$stop
    		
    	end
    endmodule
    stimulus0_24bit.dat文件内容例如以下:

    000000
    000001
    000002
    000003
    000004
    000005
    000006
    000007
    stimulus1_24bit.dat文件内容随便。这里是两个通道的FFT计算。

    仿真波形图例如以下:



    MATLAB计算所得的FFT结果例如以下:


    将FFT结果的放大后得到例如以下图:

    MATLAB计算的结果是28。而fpga仿真结果是00000e,-4则是fffffe。这是由于设置了scaling因子,且scaling因子是2,即28/2=14。

    关于hls的实现见:

    http://blog.csdn.net/shichaog/article/details/50811449

  • 相关阅读:
    c#中判断对象为空的几种方式(字符串等)
    log4net示例3控制台、windows事件
    c#中如何截取Windows消息来触发自定义事件
    向ArcGIS的ToolBarControl中添加任意的windows组建的方法
    log4net示例1最简单的回滚文件记录日志程序(时间)
    Qt 定时器实现循环
    把 MPP Sample 编译成动态库
    Linux Shell 常用编程语法
    VSCode 调试
    Hisi 使用GDB调试(直接调试)
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7357876.html
Copyright © 2011-2022 走看看