基于Verilog的FFT模块实现

Posted fpga&matlab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Verilog的FFT模块实现相关的知识,希望对你有一定的参考价值。

/* 
-- Arish Alreja: ECE 4902 Special Problems Spring 2006
-- School of Electrical & Computer Engineering
-- Georgia Institute of Technology
-- Atlanta, GA 30332
--
-- 64 point FFT Processor 
--        
-- Top level FFT module */
 
module fft (
       clk, 
       en_fft, 
       done_fft, 
       memwrite_en,
       
       mem_rd_addr0, 
       mem_rd_addr1,
       mem_rd_addr2,
       mem_rd_addr3,
       mem_rd_addr4,
       mem_rd_addr5,
       mem_rd_addr6,
       mem_rd_addr7,
       
       mem_wr_addr0, 
       mem_wr_addr1, 
       mem_wr_addr2, 
       mem_wr_addr3, 
       mem_wr_addr4, 
       mem_wr_addr5, 
       mem_wr_addr6, 
       mem_wr_addr7,
        
       rd_data0, 
       rd_data1, 
       rd_data2, 
       rd_data3, 
       rd_data4, 
       rd_data5, 
       rd_data6, 
       rd_data7, 
       
       wr_data0,
       wr_data1,
       wr_data2,
       wr_data3,
       wr_data4,
       wr_data5,
       wr_data6,
       wr_data7
       
);
    
   // Clock and initialization signal    
    input clk;
    input en_fft;
   
   // Read Address buses 
    output [02:00] mem_rd_addr0;
    output [02:00] mem_rd_addr1;
    output [02:00] mem_rd_addr2;
    output [02:00] mem_rd_addr3;
    output [02:00] mem_rd_addr4;
    output [02:00] mem_rd_addr5;
    output [02:00] mem_rd_addr6;
    output [02:00] mem_rd_addr7;

   // Write Address buses
    output [02:00] mem_wr_addr0; 
    output [02:00] mem_wr_addr1; 
    output [02:00] mem_wr_addr2; 
    output [02:00] mem_wr_addr3; 
    output [02:00] mem_wr_addr4; 
    output [02:00] mem_wr_addr5; 
    output [02:00] mem_wr_addr6; 
    output [02:00] mem_wr_addr7; 
   
   // Read Data buses
    input [31:00] rd_data0;
    input [31:00] rd_data1;
    input [31:00] rd_data2;
    input [31:00] rd_data3;
    input [31:00] rd_data4;
    input [31:00] rd_data5;
    input [31:00] rd_data6;
    input [31:00] rd_data7;

   // Write Data buses
    output [31:00] wr_data0;
    output [31:00] wr_data1;
    output [31:00] wr_data2;
    output [31:00] wr_data3;
    output [31:00] wr_data4;
    output [31:00] wr_data5;
    output [31:00] wr_data6;
    output [31:00] wr_data7;
    
   // Signal to enable Write to memory
     output memwrite_en;
    
   // Signal to indicate completion of FFT
     output done_fft;
    
   // REGISTER BANKS TO PROVIDE INPUT TO AND RECEIVE OUTPUT FROM THE BUTTERFLY PROC.
     reg [31:0] regbankone[7:0];
     reg [31:0] regbanktwo[7:0];
         
   // control signal wire coming out of the microcoded state machine  
     wire [14:0] controlsignal;
   
    // Signals to go into and come out of the butterfly processor
     reg  [31:00] bfp_in_a;
     reg  [31:00] bfp_in_b;
     wire [31:00] bfp_out_a;
     wire [31:00] bfp_out_b;
    
    // delayed output of the butterfly processor
     reg  [31:0] d_bfp_out_a;
     reg  [31:0] d_bfp_out_b;
     reg  [31:0] dd_bfp_out_a;
     reg  [31:0] dd_bfp_out_b;
    
    
    // Instantiation of the butterfly processor
    butterfly butterfly (
    .clk               (clk), 
    .reset             (en_fft),
    .read_data_a       (bfp_in_a),
    .read_data_b       (bfp_in_b), 
    .write_data_a      (bfp_out_a),
    .write_data_b      (bfp_out_b),
    .bfpcontrol        (controlsignal[4:0])
    );
    
    
    // Registers to hold the signals coming out of the control module
    // along with their delayed versions
     wire [2:0] RS1;
     wire [2:0] RS2;
     reg  [2:0] D_RS1;
     reg  [2:0] D_RS2;
     reg  [2:0] DD_RS1;
     reg  [2:0] DD_RS2;
     reg  [2:0] DDD_RS1;
     reg  [2:0] DDD_RS2;
     reg  [2:0] DDDD_RS1;
     reg  [2:0] DDDD_RS2;


     reg D_input_reg_sel;
     reg DD_input_reg_sel;
     reg DDD_input_reg_sel;
     reg DDDD_input_reg_sel;
     reg D_dest_bank_sel;
     reg DD_dest_bank_sel;
     reg DDD_dest_bank_sel;
     reg DDDD_dest_bank_sel;

     wire dest_bank_sel;
     wire readmem_en;
     wire input_reg_sel;
    
    assign memwrite_en   = controlsignal[14];
    assign readmem_en    = controlsignal[13];
    assign RS1[2:0]      = controlsignal[12:10];
    assign RS2[2:0]      = controlsignal[9:7];
    assign input_reg_sel = controlsignal[6];
    assign dest_bank_sel = controlsignal[5];
    
    
    // Instantiation of the MICROCODED STATE MACHINE control module
    control control(
    .clk               (clk),
    .en_fft            (en_fft),
    .done_fft          (done_fft),
    .controlsignal     (controlsignal)
    );
    
 // Instantiation of the Address Generation Unit
    agu agu(
    .clk               (clk),
    .en_fft            (en_fft),
    .readmem_en        (readmem_en),
    .memwrite_en       (memwrite_en),
    
    .agu_rd_addr0          (mem_rd_addr0),
    .agu_rd_addr1          (mem_rd_addr1),
    .agu_rd_addr2          (mem_rd_addr2),
    .agu_rd_addr3          (mem_rd_addr3),
    .agu_rd_addr4          (mem_rd_addr4),
    .agu_rd_addr5          (mem_rd_addr5),
    .agu_rd_addr6          (mem_rd_addr6),
    .agu_rd_addr7          (mem_rd_addr7),
    
    .agu_wr_addr0         (mem_wr_addr0),
    .agu_wr_addr1         (mem_wr_addr1),
    .agu_wr_addr2         (mem_wr_addr2),
    .agu_wr_addr3         (mem_wr_addr3),
    .agu_wr_addr4         (mem_wr_addr4),
    .agu_wr_addr5         (mem_wr_addr5),
    .agu_wr_addr6         (mem_wr_addr6),
    .agu_wr_addr7         (mem_wr_addr7)
    );
    
     
 
    // Multiplexer for selecting the butterfly input 'a' from reg bank 1
    reg [31:0]bfpr1_a;
    always @(RS1 or regbankone[0] or regbankone[1] or regbankone[2] or regbankone[3]
             or regbankone[4] or regbankone[5] or regbankone[6] or regbankone[7])
    begin
        if (RS1 == 0) begin
           bfpr1_a = regbankone[0];end
        if (RS1 == 1) begin
            bfpr1_a = regbankone[1]; end
        if (RS1 == 2) begin
           bfpr1_a= regbankone[2]; end
        if (RS1 == 3) begin
           bfpr1_a = regbankone[3]; end
        if (RS1 == 4) begin
           bfpr1_a = regbankone[4]; end   
        if (RS1 == 5) begin 
           bfpr1_a = regbankone[5]; end
        if (RS1 == 6) begin 
           bfpr1_a = regbankone[6]; end
        if (RS1 == 7) begin 
           bfpr1_a = regbankone[7]; end
    end           
       
           
    // Multiplexer for selecting the butterfly input 'b' from reg bank 1
    reg [31:0]bfpr1_b;
    always @(RS2 or regbankone[0] or regbankone[1] or regbankone[2] or regbankone[3]
             or regbankone[4] or regbankone[5] or regbankone[6] or regbankone[7])
    begin
        if (RS2 == 0) begin
           bfpr1_b = regbankone[0]; end
        if (RS2 == 1) begin
           bfpr1_b = regbankone[1]; end
        if (RS2 == 2) begin
           bfpr1_b = regbankone[2]; end
        if (RS2 == 3) begin
           bfpr1_b = regbankone[3]; end
        if (RS2 == 4) begin
           bfpr1_b = regbankone[4]; end   
        if (RS2 == 5) begin 
           bfpr1_b = regbankone[5]; end
        if (RS2 == 6) begin 
           bfpr1_b = regbankone[6]; end
        if (RS2 == 7) begin 
           bfpr1_b = regbankone[7]; end
    end 
    
       
    
    // Multiplexer for selecting the butterfly input 'a' from reg bank 2
    reg [31:0]bfpr2_a;
    always @(RS1 or regbanktwo[0] or regbanktwo[1] or regbanktwo[2] or regbanktwo[3]
             or regbanktwo[4] or regbanktwo[5] or regbanktwo[6] or regbanktwo[7])
    begin
        if (RS1 == 0) begin
           bfpr2_a = regbanktwo[0]; end
        if (RS1 == 1) begin
           bfpr2_a = regbanktwo[1]; end
        if (RS1 == 2) begin
           bfpr2_a = regbanktwo[2]; end
        if (RS1 == 3) begin
           bfpr2_a = regbanktwo[3]; end
        if (RS1 == 4) begin
           bfpr2_a = regbanktwo[4]; end   
        if (RS1 == 5) begin 
           bfpr2_a = regbanktwo[5]; end
        if (RS1 == 6) begin 
           bfpr2_a = regbanktwo[6]; end
        if (RS1 == 7) begin 
           bfpr2_a = regbanktwo[7]; end
    end       
    
    
    
     // Multiplexer for selecting the butterfly input 'b' from reg bank 2
    reg [31:0]bfpr2_b;
    always @(RS2 or regbanktwo[0] or regbanktwo[1] or regbanktwo[2] or regbanktwo[3]
             or regbanktwo[4] or regbanktwo[5] or regbanktwo[6] or regbanktwo[7])
    begin
        if (RS2 == 0) begin
           bfpr2_b = regbanktwo[0]; end
        if (RS2 == 1) begin
           bfpr2_b = regbanktwo[1]; end
        if (RS2 == 2) begin
           bfpr2_b = regbanktwo[2]; end
        if (RS2 == 3) begin
           bfpr2_b = regbanktwo[3]; end
        if (RS2 == 4) begin
           bfpr2_b = regbanktwo[4]; end   
        if (RS2 == 5) begin 
           bfpr2_b = regbanktwo[5]; end
        if (RS2 == 6) begin 
           bfpr2_b = regbanktwo[6]; end
        if (RS2 == 7) begin 
           bfpr2_b = regbanktwo[7]; end
    end    
    
    // Multiplexer to select the input a (from regbank 1 or 2)
    always @(input_reg_sel or bfpr1_a or bfpr2_a)
    begin
    bfp_in_a = (input_reg_sel == 1) ? bfpr2_a : bfpr1_a;
    end
             
     // Multiplexer to select the input b (from regbank 1 or 2)
    always @(input_reg_sel or bfpr1_b or bfpr2_b)
    begin
    bfp_in_b = (input_reg_sel == 1) ? bfpr2_b : bfpr1_b;
    end       
        
    reg dest_bank;      // signal to choose the target register bank.
    // Multiplexer to choose the Destination Register Bank for the output
    // of the Butterfly Processor
    always @(DDDD_input_reg_sel or DDDD_dest_bank_sel)
    begin
        dest_bank =(DDDD_dest_bank_sel)? ~DDDD_input_reg_sel : DDDD_input_reg_sel;
    end
    
    // Demultiplexer to choose the destination register bank for butterfly
    // outputs 'a' and 'b'.
    
    always @(readmem_en or dd_bfp_out_a or dd_bfp_out_b or dest_bank)
    begin
       if (readmem_en == 0) begin
          if (dest_bank == 0 )begin
           regbankone[DDDD_RS1] = dd_bfp_out_a;
           regbankone[DDDD_RS2] = dd_bfp_out_b; end
       
          if (dest_bank ==1) begin
           regbanktwo[DDDD_RS1] = dd_bfp_out_a;
           regbanktwo[DDDD_RS2] = dd_bfp_out_b; end
       end
   end
   
    
    // Write data buses are asynchronous
     assign wr_data0 = regbanktwo[0];
     assign wr_data1 = regbanktwo[1];
     assign wr_data2 = regbanktwo[2];
     assign wr_data3 = regbanktwo[3];
     assign wr_data4 = regbanktwo[4];
     assign wr_data5 = regbanktwo[5];
     assign wr_data6 = regbanktwo[6];
     assign wr_data7 = regbanktwo[7]; 
        
        
        
        
    // ALWAYS STATEMENT FOR DEFAULT INITIALIZATION OF DELAYED SIGNALS
    // AND TO DELAY ALL THE NECESSARY SIGNALS
    always @(posedge clk)
    begin
        if (en_fft==1)
        begin 
        // reset all the signals here
        DDDD_RS1<=0;
        DDD_RS1<=0;
        DD_RS1 <=0;
        D_RS1  <=0;
        
        DDDD_RS2<=0;
        DDD_RS2<=0;
        DD_RS2 <=0;
        D_RS2  <=0;
        
        DDDD_input_reg_sel<=0;
        DDD_input_reg_sel<=0;
        DD_input_reg_sel <=0;
        D_input_reg_sel  <=0;
        
        DDDD_dest_bank_sel<=0;
        DDD_dest_bank_sel<=0;
        DD_dest_bank_sel <=0;
        D_dest_bank_sel  <=0;
        end
        
        // DELAY ALL THE SIGNALS HERE //
        DDDD_RS1<=DDD_RS1;
        DDD_RS1<=DD_RS1;
        DD_RS1 <=D_RS1;
        D_RS1  <=RS1;
        
        DDDD_RS2<=DDD_RS2;
        DDD_RS2<=DD_RS2;
        DD_RS2 <=D_RS2;
        D_RS2  <=RS2;
   
        dd_bfp_out_a <= d_bfp_out_a;
        dd_bfp_out_b <= d_bfp_out_b;
        d_bfp_out_a <= bfp_out_a;
        d_bfp_out_b <= bfp_out_b;
        
        DDDD_input_reg_sel<= DDD_input_reg_sel;
        DDD_input_reg_sel<= DD_input_reg_sel;
        DD_input_reg_sel <= D_input_reg_sel;
        D_input_reg_sel  <= input_reg_sel;
        
        DDDD_dest_bank_sel<=DDD_dest_bank_sel;
        DDD_dest_bank_sel<=DD_dest_bank_sel;
        DD_dest_bank_sel <=D_dest_bank_sel;
        D_dest_bank_sel  <=dest_bank_sel;

     // Write read data bus onto regbank 1 when reading from memory
        if (readmem_en == 1) 
       begin
            regbankone[0] = rd_data0;
            regbankone[1] = rd_data1;
            regbankone[2] = rd_data2;
            regbankone[3] = rd_data3;
            regbankone[4] = rd_data4;
            regbankone[5] = rd_data5;
            regbankone[6] = rd_data6;
            regbankone[7] = rd_data7; 
        end
        
    end
endmodule

D158

以上是关于基于Verilog的FFT模块实现的主要内容,如果未能解决你的问题,请参考以下文章

FPGA教程案例36通信案例6——基于vivado核的FFT傅里叶变换开发以及verilog输入时序配置详解,通过matlab进行辅助验证

FPGA教程案例10基于Verilog的复数乘法器设计与实现

基于FPGA的FFT变换实现

基于FPGA的OFDM-QPSK链路verilog实现

FPGA+FFT基于FPGA的FFT频率计设计与实现

用Verilog语言实现一个简单的MII模块