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                                                                    \n";
   ///////////////////////////////////////////////////////////////////////////////////////////////
   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                                                                                                 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM