• quartus ii FFT核使用


    quartus ii FFT核使用

    导入自己程序自带的txt文件,写出控制模块

    时序图

    FFT核文件给出的时序图输入

    仿真时序图

     

    1024个采样点数,输入结束

     fft数据输出

     

     2、代码

    `timescale 1ns/1ns
    module fft_ctrl
    #(
            parameter [9:0]   fftpts_n = 10'd11,
            parameter [9:0]   real_imag_wei = 10'd16    
    )
    (
        //inputs
           clk                    ,    
           reset_n                ,
        sink_valid             ,//拉高表示通知FFT即将有N个数据输入
        sink_real            ,//输入数据的实部
        sink_imag            ,//输入数据的虚部
        inverse                ,//0 -  FFT    1 - IFFT
        fftpts_array_N        ,    //采样的点数 
       
        //output
        source_sop        ,   //输出数据起始标记
        source_eop        ,   //输出数据结束标记
        source_valid        , //置高,准备输出结果
        //从时序看应该是sink_ready和sink_valid同步的
        sink_ready        ,//FFT模块准备就绪,可以接收数据 output 
        sink_sop        ,//输入数据起始标记脉冲(维持一个时钟的高电平),与第一个数据同步
        sink_eop        ,//输入数据结束标记脉冲(维持一个时钟的高电平),与最后一个数据同步
        source_real        ,//变换后输出数据的实部
        source_imag        ,//变换后输出数据的虚部
        source_exp        , //结果数据缩放因子:这
        end_input            ,   //数据输入结束
        end_test            ,   //数据输入结束 置1
        end_output          //数据输出结束    
        
        
    
    );
        
    //******************************* input and output *********************//    
        
        //inputs
       input                    clk                    ;    
       input                    reset_n                ;
       input                   sink_valid             ;//拉高表示通知FFT即将有N个数据输入
       input     [real_imag_wei - 1:0]   sink_real                ;//输入数据的实部
       input     [real_imag_wei - 1:0]   sink_imag                ;//输入数据的虚部
       input                  inverse                ;//0 -  FFT    1 - IFFT
       input      [fftpts_n - 1:0] fftpts_array_N;    //采样的点数 
       
      //output
      output                 source_sop        ;   //输出数据起始标记
      output                 source_eop        ;   //输出数据结束标记
      output                 source_valid    ; //置高,准备输出结果
      //从时序看应该是sink_ready和sink_valid同步的
      output                 sink_ready        ;//FFT模块准备就绪,可以接收数据 output 
      output     [real_imag_wei - 1: 0] source_real    ;//变换后输出数据的实部
      output     [real_imag_wei - 1: 0] source_imag    ;//变换后输出数据的虚部
      output     [5:0]       source_exp        ; //结果数据缩放因子:这
      output                 end_input;   //数据输入结束
      output     reg         end_test;     //输入的数据结束 置1
      output                 end_output;  //数据输出结束    
      output                 sink_sop;//输入数据起始标记脉冲(维持一个时钟的高电平),与第一个数据同步
      output                 sink_eop;//输入数据结束标记脉冲(维持一个时钟的高电平),与最后一个数据同步
      
    //***************************** parameter and interface *************************// 
    
       wire                 source_ready;//表明downstream模块(理解为FFT的后续接收数据模块)可以接收数据 input
       wire [1:0]           sink_error;
       wire [1:0] source_error;
     
      localparam                        NUM_FRAMES_c = 4;        //输入数据的次数
      //parameter                        MAXVAL_c = 2**(16 -1);     
      //parameter                        OFFSET_c = 2**(16);        
      //parameter MAXVAL_EXP_c = 2**5;
      //parameter OFFSET_EXP_c = 2**6;
     
       //reg             start;
       //number of input frames
       reg  [7:0] frames_in_index;
       //number of output frames
       reg  [7:0] frames_out_index;
       // signal the end of the input data stream and output data stream.
       reg  [fftpts_n - 1:0] cnt;
      
      
       ///////////////////////////////////////////////////////////////////////////////////////////////
       // Clock Generation                                                                         
       ///////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////
       // Set FFT Direction     
       // '0' => FFT      
       // '1' => IFFT
       // assign inverse = 1'b0;
    
      //no input error
      assign sink_error = 2'b0;
           
      // for example purposes, the ready signal is always asserted.
      assign source_ready = 1'b1;
    
       ///////////////////////////////////////////////////////////////////////////////////////////////
       // All FFT MegaCore input signals are registered on the rising edge of the input clock, clk and 
       // all FFT MegaCore output signals are output on the rising edge of the input clock, clk. 
       //////////////////////////////////////////////////////////////////////////////////////////////
    
      // start valid for first cycle to indicate that the file reading should start.
      /*
            always @ (posedge clk or negedge reset_n)
            begin
                if (reset_n == 1'b0)
                    start <= 1'b1;
                else
                    begin
                        if (sink_valid == 1'b1 & sink_ready == 1'b1)
                        start <= 1'b0;
                    end
                end
       */
      //sop and eop asserted in first and last sample of data
      always @ (posedge clk or negedge reset_n)
      begin
        if (reset_n == 1'b0)
          cnt <= 'd0;
        else
          begin
            if (sink_valid == 1'b1 & sink_ready == 1'b1)
              begin
                 if (cnt == fftpts_array_N - 1)
                   cnt <= 'd0;
                 else
                   cnt <= cnt + 1'b1;
              end
          end
      end
    
      // count the input frames and increment the index
      always @(posedge clk or negedge reset_n)
        begin
           if (reset_n == 1'b0)
             frames_in_index <= 'd0;
           else
             begin
                if (sink_eop == 1'b1 & sink_valid == 1'b1 & sink_ready == 1'b1 & frames_in_index < NUM_FRAMES_c -1)
                  frames_in_index <= frames_in_index + 1'b1;
             end
        end 
    
       // count the output frames and increment the index
       always @(posedge clk or negedge reset_n)
        begin
           if (reset_n == 1'b0)
            frames_out_index <= 'd0;
           else
             begin
                if (source_eop == 1'b1 &  source_valid == 1'b1 & source_ready == 1'b1 & frames_out_index < NUM_FRAMES_c -1)
                  frames_out_index <= frames_out_index + 1'b1;
             end
        end 
    
       // signal when all of the input data has been sent to the DUT
       assign end_input = (sink_eop == 1'b1 & sink_valid == 1'b1 & sink_ready == 1'b1 & frames_in_index == NUM_FRAMES_c - 1) ? 1'b1 : 1'b0;
        
       // signal when all of the output data has be received from the DUT
       assign end_output = (source_eop == 1'b1 & source_valid == 1'b1 & source_ready == 1'b1 & frames_out_index == NUM_FRAMES_c - 1) ? 1'b1 : 1'b0;
      
    
       // generate start and end of packet signals
       assign sink_sop = (cnt == 0) ? 1'b1 : 1'b0 ;
       assign sink_eop = ( cnt == fftpts_array_N - 1 ) ? 1'b1 : 1'b0;
    
       //halt the input when done
        always @(posedge clk or negedge reset_n)
          begin
            if (reset_n == 1'b0)
              end_test <= 1'b0;
            else
              begin
                if (end_input == 1'b1)
                 end_test <= 1'b1; 
              end
          end
          
    ip_fft dut(
                          .clk                (clk),               //
                          .reset_n            (reset_n),           //
                          .inverse            (inverse),           //0 -  FFT    1 - IFFT
                          .sink_real        (sink_real),         //输入数据的实部
                          .sink_imag        (sink_imag),         //输入数据的虚部
                          .sink_sop            (sink_sop),          //输入数据起始标记脉冲(维持一个时钟的高电平),与第一个数据同步
                          .sink_eop            (sink_eop),          //输入数据结束标记脉冲(维持一个时钟的高电平),与最后一个数据同步
                          .sink_valid       (sink_valid),        //拉高表示通知FFT即将有N个数据输入
                          .sink_error       (sink_error),        //指示数据流的错误信息:00——没有错误;01——丢失SOP;10——丢失EOP;11——多余的EOP;
                          .source_error     (source_error),       //表明upstream模块或者FFT模块出了问题,错误信息提示与sink_error一样 output
                          .source_ready     (source_ready),       //表明downstream模块(理解为FFT的后续接收数据模块)可以接收数据 input
                          .sink_ready        (sink_ready),        //FFT模块准备就绪,可以接收数据 output
                          .source_real      (source_real),       //变换后输出数据的实部
                          .source_imag        (source_imag),       //变换后输出数据的虚部
                          .source_exp        (source_exp),        //结果数据缩放因子:这个指数位的意思打个比方说吧,
                          //比如它是3,就是说这时输出的虚部和实部的数值要除以2的3次方,如果是10,就要除以2的10次方,
                          //如果对结果精度要求不高的话,可以直接截去相应的长度,
                          //比如指数是3,实部输出1011_0111_0111,那么此刻实际的值应该为1_0110_1110.111;取整就是101101110
                          .source_valid        (source_valid),       //置高,准备输出结果
                          .source_sop        (source_sop),        //输出数据起始标记
                          .source_eop        (source_eop)         //输出数据结束标记
    );
    
    endmodule
    // ================================================================================
    // Legal Notice: Copyright (C) 1991-2008 Altera Corporation
    // Any megafunction design, and related net list (encrypted or decrypted),
    // support information, device programming or simulation file, and any other
    // associated documentation or information provided by Altera or a partner
    // under Altera's Megafunction Partnership Program may be used only to
    // program PLD devices (but not masked PLD devices) from Altera.  Any other
    // use of such megafunction design, net list, support information, device
    // programming or simulation file, or any other related documentation or
    // information is prohibited for any other purpose, including, but not
    // limited to modification, reverse engineering, de-compiling, or use with
    // any other silicon devices, unless such use is explicitly licensed under
    // a separate agreement with Altera or a megafunction partner.  Title to
    // the intellectual property, including patents, copyrights, trademarks,
    // trade secrets, or maskworks, embodied in any such megafunction design,
    // net list, support information, device programming or simulation file, or
    // any other related documentation or information provided by Altera or a
    // megafunction partner, remains with Altera, the megafunction partner, or
    // their respective licensors.  No other licenses, including any licenses
    // needed under any third party's intellectual property, are provided herein.
    // ================================================================================
    //
    
    `timescale 1ns / 1ps
    module ip_fft_ctrl_tb;
    
    
       //inputs
       reg clk;    
       reg reset_n;
       reg sink_valid;
       reg[16 - 1:0] sink_real;
       reg[16 - 1:0] sink_imag;
       reg  [10:0]    fftpts_array_N;
       reg                  inverse;
       wire                 sink_sop;
       wire                 sink_eop;
       wire                 sink_ready;
     
       wire                 source_sop;
       wire                 source_eop;
       wire                 source_valid;
       wire [5:0] source_exp;   
       wire [16 - 1: 0] source_real;
       wire [16 - 1: 0] source_imag;
       parameter                        NUM_FRAMES_c = 4;
       parameter                        MAXVAL_c = 2**(16 -1);
       parameter                        OFFSET_c = 2**(16);
       parameter MAXVAL_EXP_c = 2**5;
       parameter OFFSET_EXP_c = 2**6;
      
    
       // signal the end of the input data stream and output data stream.
       wire end_test;
       wire end_input;
       wire end_output;
       
       integer fft_rf, fft_if;
       integer expf;   
       integer data_rf,data_if;           
       integer data_real_in_int,data_imag_in_int;
       integer fft_real_out_int,fft_imag_out_int;
       integer exponent_out_int;
    
    initial
       begin
    
    
         data_rf = $fopen("ip_fft_real_input.txt","r");
         data_if = $fopen("ip_fft_imag_input.txt","r");
         fft_rf = $fopen("ip_fft_real_output_ver.txt");
         fft_if =$fopen("ip_fft_imag_output_ver.txt");
         expf = $fopen("ip_fft_exponent_output_ver.txt");
         #0 clk = 1'b0;
          inverse = 0;
         fftpts_array_N = 11'd1024;
         sink_valid = 0;
         inverse = 0;
         #0 reset_n = 1'b0;
         #92 reset_n = 1'b1;
        
    
         
      end
        
       ///////////////////////////////////////////////////////////////////////////////////////////////
       // Clock Generation                                                                         
       ///////////////////////////////////////////////////////////////////////////////////////////////
       always
         begin
           if (end_test == 1'b1 & end_output == 1'b1) 
             begin
               clk = 1'b0;
               $finish;
             end
           else
             begin
               #5 clk = 1'b1;
               #5 clk = 1'b0;
             end
         end
    
       ///////////////////////////////////////////////////////////////////////////////////////////////
       //采样的点数
       //assign fftpts_array_N = 11'd1024;
       
       ///////////////////////////////////////////////////////////////////////////////////////////////
       // All FFT MegaCore input signals are registered on the rising edge of the input clock, clk and 
       // all FFT MegaCore output signals are output on the rising edge of the input clock, clk. 
       //////////////////////////////////////////////////////////////////////////////////////////////
    
      // start valid for first cycle to indicate that the file reading should start.
      reg             start;
      reg             sink_valid_r;
      always @ (posedge clk)
      begin
         if (reset_n == 1'b0)
           start <= 1'b1;
         else
           begin
             if (sink_valid_r == 1'b1 & sink_ready == 1'b1)
               start <= 1'b0;
           end
       end
    
       ///////////////////////////////////////////////////////////////////////////////////////////////
       // Read input data from files. Data is generated on the negative edge of the clock, clk, in the
       // testbench and registered by the core on the positive edge of the clock                                                                    
    ";
       ///////////////////////////////////////////////////////////////////////////////////////////////
       integer rc_x;
       integer ic_x;
       always @ (posedge clk)
         begin
            if(reset_n==1'b0)
              begin
                 sink_real<=16'b0;
                 sink_imag<=16'b0;
                 sink_valid_r <= 1'b0;
              end
            else
              begin
                 // send in NUM_FRAMES_c of data or until the end of the file
                 if((end_test == 1'b1) || (end_input == 1'b1))
                   begin
                      sink_real<=16'b0;
                       sink_imag<=16'b0;
                      sink_valid_r <= 1'b0;
                   end
                 else
                   begin
                      if ((sink_valid_r == 1'b1 & sink_ready == 1'b1 ) ||
                          (start == 1'b1 & !(sink_valid_r == 1'b1 & sink_ready == 1'b0)))
                        begin
                           rc_x = $fscanf(data_rf,"%d",data_real_in_int);
                           sink_real <= data_real_in_int;
                           ic_x = $fscanf(data_if,"%d",data_imag_in_int); 
                           sink_imag <= data_imag_in_int;
                           sink_valid_r <= 1'b1;
                        end 
                      else
                        begin
                           sink_real<=sink_real;
                           sink_imag<=sink_imag;
                           sink_valid_r <= 1'b0;
                        end
                   end
              end
         end
    
       //////////////////////////////////////////////////////////////////////////////////////////////
       // Write Real and Imginary Data Components and Block Exponent to Disk                         
       //////////////////////////////////////////////////////////////////////////////////////////////
       always @ (posedge clk) 
         begin
            if((reset_n==1'b1) & (source_valid == 1'b1))
              begin
                 fft_real_out_int = source_real;
                 fft_imag_out_int = source_imag;
                 $fdisplay(fft_rf, "%d", (fft_real_out_int < MAXVAL_c) ? fft_real_out_int : fft_real_out_int - OFFSET_c);
                 $fdisplay(fft_if, "%d", (fft_imag_out_int < MAXVAL_c) ? fft_imag_out_int : fft_imag_out_int - OFFSET_c);
                 exponent_out_int = source_exp;
                $fdisplay(expf, "%d", (exponent_out_int < MAXVAL_EXP_c) ? exponent_out_int : exponent_out_int - OFFSET_EXP_c);
              end
            end
    
        ///////////////////////////////////////////////////////////////////////////////////////////////
       // FFT Module Instantiation                                                               
       /////////////////////////////////////////////////////////////////////////////////////////////
        fft_ctrl
        #(
                .fftpts_n(10'd11),
                .real_imag_wei(10'd16)    
        ) fft_ctrl
        (
            //inputs
            .clk                (clk            ),    
            .reset_n            (reset_n        ),
            .sink_valid         (sink_valid_r     ),//拉高表示通知FFT即将有N个数据输入
            .sink_real            (sink_real        ),//输入数据的实部
            .sink_imag            (sink_imag        ),//输入数据的虚部
            .inverse            (inverse        ),//0 -  FFT    1 - IFFT     0
            .fftpts_array_N        (fftpts_array_N    ),    //采样的点数  1024
        
            //output
            .source_sop            (source_sop    ),   //输出数据起始标记
            .source_eop            (source_eop    ),   //输出数据结束标记
            .source_valid        (source_valid), //置高,准备输出结果
            //从时序看应该是sink_ready和sink_valid同步的
            .sink_ready            (sink_ready    ),//FFT模块准备就绪,可以接收数据 output 
            .sink_sop           (sink_sop),//输入数据起始标记脉冲(维持一个时钟的高电平),与第一个数据同步
            .sink_eop           (sink_eop),//输入数据结束标记脉冲(维持一个时钟的高电平),与最后一个数据同步
            .source_real        (source_real),//变换后输出数据的实部
            .source_imag        (source_imag),//变换后输出数据的虚部
            .source_exp            (source_exp    ), //结果数据缩放因子:这
            .end_input            (end_input    ),   //数据输入结束
            .end_test            (end_test    ),   //数据输入结束 置1
            .end_output              (end_output    )//数据输出结束    
        );
        
        
    endmodule                                                                                                 
  • 相关阅读:
    show point on image
    vec2d
    Size类型如何调用和定义
    opencv数据类型和格式的坑
    IplImage 与mat之间的转换及释放内存
    linux平台程序高精度延时问题select-usleep等
    gettimeofday的使用
    列模式编辑文本
    【linux基础】如何开机自启动某个程序-linux工具-ubuntu
    查看camera设备-linux
  • 原文地址:https://www.cnblogs.com/wanglinwensi/p/12871229.html
Copyright © 2020-2023  润新知