8點按時間抽取的基2 FFT的Verilog實現


這是第一次用Verilog寫FFT,代碼寫得很爛,但是基本功能還是能實現的。希望走過路過的大佬能夠多多指出不足,提出改進方向,也歡迎同學們向我提出所有讓自己感到困惑的內容,大家一起進步。話不多說,祭出代碼。整個工程已上傳至我的網盤,大家如果需要可以私聊我,開源精神,一切共享。

首先是FFT源碼

//******************************************************
//Data:  2019-9-10
//Name:  Li Fuong
//Theme: 8_FFT_2
//******************************************************

module FFT_8(
    clk,
    rst_n,
    
    x_r_0,    //輸入實部
    x_r_1,
    x_r_2,
    x_r_3,
    x_r_4,
    x_r_5,
    x_r_6,
    x_r_7,
    
    x_i_0,    //輸入虛部
    x_i_1,
    x_i_2,
    x_i_3,
    x_i_4,
    x_i_5,
    x_i_6,
    x_i_7,
    
    y_r_0,    //輸出實部
    y_r_1,
    y_r_2,
    y_r_3,
    y_r_4,
    y_r_5,
    y_r_6,
    y_r_7,
    
    y_i_0,    //輸出虛部
    y_i_1,
    y_i_2,
    y_i_3,
    y_i_4,
    y_i_5,
    y_i_6,
    y_i_7
);

    input clk;
    input rst_n;
    
    //輸入占5位,在保持最高位為0的條件下可輸入0~15的采樣值
    input signed [4:0] x_r_0;
    input signed [4:0] x_r_1;
    input signed [4:0] x_r_2;
    input signed [4:0] x_r_3;
    input signed [4:0] x_r_4;
    input signed [4:0] x_r_5;
    input signed [4:0] x_r_6;
    input signed [4:0] x_r_7;

    input signed [4:0] x_i_0;
    input signed [4:0] x_i_1;
    input signed [4:0] x_i_2;
    input signed [4:0] x_i_3;
    input signed [4:0] x_i_4;
    input signed [4:0] x_i_5;
    input signed [4:0] x_i_6;
    input signed [4:0] x_i_7;
    
    //輸出占7位
    output reg signed [6:0] y_r_0;
    output reg signed [6:0] y_r_1;
    output reg signed [6:0] y_r_2;
    output reg signed [6:0] y_r_3;
    output reg signed [6:0] y_r_4;
    output reg signed [6:0] y_r_5;
    output reg signed [6:0] y_r_6;
    output reg signed [6:0] y_r_7;

   output reg signed [6:0] y_i_0;
    output reg signed [6:0] y_i_1;
    output reg signed [6:0] y_i_2;
    output reg signed [6:0] y_i_3;
    output reg signed [6:0] y_i_4;
    output reg signed [6:0] y_i_5;
    output reg signed [6:0] y_i_6;
    output reg signed [6:0] y_i_7;
    
    //參數存儲寄存器,存放旋轉系數
    //w_r_*表示旋轉系數實部(cos值)
    reg [3:0] w_r_0;
    reg [3:0] w_r_1;
    reg [3:0] w_r_2;
    reg [3:0] w_r_3;
    
    //w_i_*表示旋轉系數虛部(sin值)
    reg [3:0] w_i_0;
    reg [3:0] w_i_1;
    reg [3:0] w_i_2;
    reg [3:0] w_i_3;
    
   //中間寄存器
    reg signed [11:0] x_r_tmp_0;
    reg signed [11:0] x_r_tmp_1;
    reg signed [11:0] x_r_tmp_2;
    reg signed [11:0] x_r_tmp_3;
    reg signed [11:0] x_r_tmp_4;
    reg signed [11:0] x_r_tmp_5;
    reg signed [11:0] x_r_tmp_6;
    reg signed [11:0] x_r_tmp_7;
    
    reg signed [11:0] x_i_tmp_0;
    reg signed [11:0] x_i_tmp_1;
    reg signed [11:0] x_i_tmp_2;
    reg signed [11:0] x_i_tmp_3;
    reg signed [11:0] x_i_tmp_4;
    reg signed [11:0] x_i_tmp_5;
    reg signed [11:0] x_i_tmp_6;
    reg signed [11:0] x_i_tmp_7;
    
    //中間保持寄存器,用來暫存中間寄存器的值,防止發生沖突
    reg signed [11:0] x_r_tmp_last_0;
    reg signed [11:0] x_r_tmp_last_1;
    reg signed [11:0] x_r_tmp_last_2;
    reg signed [11:0] x_r_tmp_last_3;
    reg signed [11:0] x_r_tmp_last_4;
    reg signed [11:0] x_r_tmp_last_5;
    reg signed [11:0] x_r_tmp_last_6;
    reg signed [11:0] x_r_tmp_last_7;
    
    reg signed [11:0] x_i_tmp_last_0;
    reg signed [11:0] x_i_tmp_last_1;
    reg signed [11:0] x_i_tmp_last_2;
    reg signed [11:0] x_i_tmp_last_3;
    reg signed [11:0] x_i_tmp_last_4;
    reg signed [11:0] x_i_tmp_last_5;
    reg signed [11:0] x_i_tmp_last_6;
    reg signed [11:0] x_i_tmp_last_7;
    
    //狀態機
    reg [3:0] state_machine;
    localparam state_start = 4'd0;        //所有寄存器初始化
    localparam state_input = 4'd1;        //中間寄存器獲取輸入采樣值
    localparam state_s1    = 4'd2;        //中間保持寄存器暫存數據過程
    localparam state_s2    = 4'd3;        //第一次蝶形乘法
    localparam state_s3    = 4'd4;        //中間保持寄存器暫存數據過程
    localparam state_s4    = 4'd5;        //第一次蝶形加法
    localparam state_s5    = 4'd6;        //中間保持寄存器暫存數據過程
    localparam state_s6    = 4'd7;        //第二次蝶形乘法
    localparam state_s7    = 4'd9;        //中間保持寄存器暫存數據過程
    localparam state_s8    = 4'd10;        //第二次蝶形加法
    localparam state_s9    = 4'd11;        //中間保持寄存器暫存數據過程
    localparam state_s10   = 4'd12;        //第三次蝶形乘法
    localparam state_s11   = 4'd13;        //中間保持寄存器暫存數據過程
    localparam state_s12   = 4'd14;        //第三次蝶形加法
    localparam state_end   = 4'd15;        //輸出計算結果
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            w_r_0 = 4'd0;
            w_r_1 = 4'd0;
            w_r_2 = 4'd0;
            w_r_3 = 4'd0;
            
            w_i_0 = 4'd0;
            w_i_1 = 4'd0;
            w_i_2 = 4'd0;
            w_i_3 = 4'd0;
            
            x_r_tmp_0 <= 12'd0;
            x_r_tmp_1 <= 12'd0;
            x_r_tmp_2 <= 12'd0;
            x_r_tmp_3 <= 12'd0;
            x_r_tmp_4 <= 12'd0;
            x_r_tmp_5 <= 12'd0;
            x_r_tmp_6 <= 12'd0;
            x_r_tmp_7 <= 12'd0;
            
            x_i_tmp_0 <= 12'd0;
            x_i_tmp_1 <= 12'd0;
            x_i_tmp_2 <= 12'd0;
            x_i_tmp_3 <= 12'd0;
            x_i_tmp_4 <= 12'd0;
            x_i_tmp_5 <= 12'd0;
            x_i_tmp_6 <= 12'd0;
            x_i_tmp_7 <= 12'd0;
            
            x_r_tmp_last_0 <= 12'd0;
            x_r_tmp_last_1 <= 12'd0;
            x_r_tmp_last_2 <= 12'd0;
            x_r_tmp_last_3 <= 12'd0;
            x_r_tmp_last_4 <= 12'd0;
            x_r_tmp_last_5 <= 12'd0;
            x_r_tmp_last_6 <= 12'd0;
            x_r_tmp_last_7 <= 12'd0;
                           
            x_i_tmp_last_0 <= 12'd0;
            x_i_tmp_last_1 <= 12'd0;
            x_i_tmp_last_2 <= 12'd0;
            x_i_tmp_last_3 <= 12'd0;
            x_i_tmp_last_4 <= 12'd0;
            x_i_tmp_last_5 <= 12'd0;
            x_i_tmp_last_6 <= 12'd0;
            x_i_tmp_last_7 <= 12'd0;
            
            y_r_0 <= 7'd0;
            y_r_1 <= 7'd0;
            y_r_2 <= 7'd0;
            y_r_3 <= 7'd0;
            y_r_4 <= 7'd0;
            y_r_5 <= 7'd0;
            y_r_6 <= 7'd0;
            y_r_7 <= 7'd0;
            
            y_i_0 <= 7'd0;
            y_i_1 <= 7'd0;
            y_i_2 <= 7'd0;
            y_i_3 <= 7'd0;
            y_i_4 <= 7'd0;
            y_i_5 <= 7'd0;
            y_i_6 <= 7'd0;
            y_i_7 <= 7'd0;
            
            state_machine <= state_start;
        end
        else case(state_machine)
            
            state_start: begin
                //輸入旋轉因子,其中cos值分別為10、7、0、-7
                //因此,在遇到與w_r_3相乘時,需要加上負號
                w_r_0 <= 4'd10;
                w_r_1 <= 4'd7;
                w_r_2 <= 4'sd0;
                w_r_3 <= 4'd7;
                //sin值分別為0、-7、-10、-7
                //因此,在與w_i_1、w_i_2和w_i_3相乘時,需要加上負號
                w_i_0 <= 4'd0;
                w_i_1 <= 4'd7;
                w_i_2 <= 4'd10;
                w_i_3 <= 4'd7;
                
                state_machine <= state_input;
            end
            
            state_input: begin
                x_r_tmp_0 <= x_r_0;
                x_r_tmp_1 <= x_r_4;
                x_r_tmp_2 <= x_r_2;
                x_r_tmp_3 <= x_r_6;
                x_r_tmp_4 <= x_r_1;
                x_r_tmp_5 <= x_r_5;
                x_r_tmp_6 <= x_r_3;
                x_r_tmp_7 <= x_r_7;
                
                x_i_tmp_0 <= x_i_0;
                x_i_tmp_1 <= x_i_4;
                x_i_tmp_2 <= x_i_2;
                x_i_tmp_3 <= x_i_6;
                x_i_tmp_4 <= x_i_1;
                x_i_tmp_5 <= x_i_5;
                x_i_tmp_6 <= x_i_3;
                x_i_tmp_7 <= x_i_7;
                
                state_machine <= state_s1;
            end
            
            state_s1: begin
                x_r_tmp_last_0 <= x_r_tmp_0;
                x_r_tmp_last_1 <= x_r_tmp_1;
                x_r_tmp_last_2 <= x_r_tmp_2;
                x_r_tmp_last_3 <= x_r_tmp_3;
                x_r_tmp_last_4 <= x_r_tmp_4;
                x_r_tmp_last_5 <= x_r_tmp_5;
                x_r_tmp_last_6 <= x_r_tmp_6;
                x_r_tmp_last_7 <= x_r_tmp_7;
                
                x_i_tmp_last_0 <= x_i_tmp_0;
                x_i_tmp_last_1 <= x_i_tmp_1;
                x_i_tmp_last_2 <= x_i_tmp_2;
                x_i_tmp_last_3 <= x_i_tmp_3;
                x_i_tmp_last_4 <= x_i_tmp_4;
                x_i_tmp_last_5 <= x_i_tmp_5;
                x_i_tmp_last_6 <= x_i_tmp_6;
                x_i_tmp_last_7 <= x_i_tmp_7;
                
                state_machine <= state_s2;
            end
            
            state_s2: begin
                x_r_tmp_1 <= (x_r_tmp_last_1 * w_r_0 / 10) - (x_i_tmp_last_1 * w_i_0 / 10);
                x_r_tmp_3 <= (x_r_tmp_last_3 * w_r_0 / 10) - (x_i_tmp_last_3 * w_i_0 / 10);
                x_r_tmp_5 <= (x_r_tmp_last_5 * w_r_0 / 10) - (x_i_tmp_last_5 * w_i_0 / 10);
                x_r_tmp_7 <= (x_r_tmp_last_7 * w_r_0 / 10) - (x_i_tmp_last_7 * w_i_0 / 10);
                
                x_i_tmp_1 <= (x_r_tmp_last_1 * w_i_0 / 10) + (x_i_tmp_last_1 * w_r_0 / 10);
                x_i_tmp_3 <= (x_r_tmp_last_3 * w_i_0 / 10) + (x_i_tmp_last_3 * w_r_0 / 10);
                x_i_tmp_5 <= (x_r_tmp_last_5 * w_i_0 / 10) + (x_i_tmp_last_5 * w_r_0 / 10);
                x_i_tmp_7 <= (x_r_tmp_last_7 * w_i_0 / 10) + (x_i_tmp_last_7 * w_r_0 / 10);
                
                state_machine <= state_s3;
            end
            
            state_s3: begin
                x_r_tmp_last_0 <= x_r_tmp_0;
                x_r_tmp_last_1 <= x_r_tmp_1;
                x_r_tmp_last_2 <= x_r_tmp_2;
                x_r_tmp_last_3 <= x_r_tmp_3;
                x_r_tmp_last_4 <= x_r_tmp_4;
                x_r_tmp_last_5 <= x_r_tmp_5;
                x_r_tmp_last_6 <= x_r_tmp_6;
                x_r_tmp_last_7 <= x_r_tmp_7;
                
                x_i_tmp_last_0 <= x_i_tmp_0;
                x_i_tmp_last_1 <= x_i_tmp_1;
                x_i_tmp_last_2 <= x_i_tmp_2;
                x_i_tmp_last_3 <= x_i_tmp_3;
                x_i_tmp_last_4 <= x_i_tmp_4;
                x_i_tmp_last_5 <= x_i_tmp_5;
                x_i_tmp_last_6 <= x_i_tmp_6;
                x_i_tmp_last_7 <= x_i_tmp_7;
                
                state_machine <= state_s4;
            end
            
            state_s4: begin
                x_r_tmp_0 <= x_r_tmp_last_0 + x_r_tmp_last_1;
                x_r_tmp_2 <= x_r_tmp_last_2 + x_r_tmp_last_3;
                x_r_tmp_4 <= x_r_tmp_last_4 + x_r_tmp_last_5;
                x_r_tmp_6 <= x_r_tmp_last_6 + x_r_tmp_last_7;
                
                x_r_tmp_1 <= x_r_tmp_last_0 - x_r_tmp_last_1;
                x_r_tmp_3 <= x_r_tmp_last_2 - x_r_tmp_last_3;
                x_r_tmp_5 <= x_r_tmp_last_4 - x_r_tmp_last_5;
                x_r_tmp_7 <= x_r_tmp_last_6 - x_r_tmp_last_7;
                
                x_i_tmp_0 <= x_i_tmp_last_0 + x_i_tmp_last_1;
                x_i_tmp_2 <= x_i_tmp_last_2 + x_i_tmp_last_3;
                x_i_tmp_4 <= x_i_tmp_last_4 + x_i_tmp_last_5;
                x_i_tmp_6 <= x_i_tmp_last_6 + x_i_tmp_last_7;
                
                x_i_tmp_1 <= x_i_tmp_last_0 - x_i_tmp_last_1;
                x_i_tmp_3 <= x_i_tmp_last_2 - x_i_tmp_last_3;
                x_i_tmp_5 <= x_i_tmp_last_4 - x_i_tmp_last_5;
                x_i_tmp_7 <= x_i_tmp_last_6 - x_i_tmp_last_7;
                
                state_machine <= state_s5;
            end
            
            state_s5: begin
                x_r_tmp_last_0 <= x_r_tmp_0;
                x_r_tmp_last_1 <= x_r_tmp_1;
                x_r_tmp_last_2 <= x_r_tmp_2;
                x_r_tmp_last_3 <= x_r_tmp_3;
                x_r_tmp_last_4 <= x_r_tmp_4;
                x_r_tmp_last_5 <= x_r_tmp_5;
                x_r_tmp_last_6 <= x_r_tmp_6;
                x_r_tmp_last_7 <= x_r_tmp_7;
                
                x_i_tmp_last_0 <= x_i_tmp_0;
                x_i_tmp_last_1 <= x_i_tmp_1;
                x_i_tmp_last_2 <= x_i_tmp_2;
                x_i_tmp_last_3 <= x_i_tmp_3;
                x_i_tmp_last_4 <= x_i_tmp_4;
                x_i_tmp_last_5 <= x_i_tmp_5;
                x_i_tmp_last_6 <= x_i_tmp_6;
                x_i_tmp_last_7 <= x_i_tmp_7;
                
                state_machine <= state_s6;
            end
            
            state_s6: begin
                x_r_tmp_2 <= (x_r_tmp_last_2 * w_r_0 / 10) - (x_i_tmp_last_2 * w_i_0 / 10);
                x_r_tmp_6 <= (x_r_tmp_last_6 * w_r_0 / 10) - (x_i_tmp_last_6 * w_i_0 / 10);
                
                x_r_tmp_3 <= (x_r_tmp_last_3 * w_r_2 / 10) + (x_i_tmp_last_3 * w_i_2 / 10);
                x_r_tmp_7 <= (x_r_tmp_last_7 * w_r_2 / 10) + (x_i_tmp_last_7 * w_i_2 / 10);
                
                x_i_tmp_2 <= (x_i_tmp_last_2 * w_r_0 / 10) + (x_r_tmp_last_2 * w_i_0 / 10);
                x_i_tmp_6 <= (x_i_tmp_last_6 * w_r_0 / 10) + (x_r_tmp_last_6 * w_i_0 / 10);
                
                x_i_tmp_3 <= (x_i_tmp_last_3 * w_r_2 / 10) - (x_r_tmp_last_3 * w_i_2 / 10);
                x_i_tmp_7 <= (x_i_tmp_last_7 * w_r_2 / 10) - (x_r_tmp_last_7 * w_i_2 / 10);
                
                state_machine <= state_s7;
            end
            
            state_s7: begin
                x_r_tmp_last_0 <= x_r_tmp_0;
                x_r_tmp_last_1 <= x_r_tmp_1;
                x_r_tmp_last_2 <= x_r_tmp_2;
                x_r_tmp_last_3 <= x_r_tmp_3;
                x_r_tmp_last_4 <= x_r_tmp_4;
                x_r_tmp_last_5 <= x_r_tmp_5;
                x_r_tmp_last_6 <= x_r_tmp_6;
                x_r_tmp_last_7 <= x_r_tmp_7;
            
                x_i_tmp_last_0 <= x_i_tmp_0;
                x_i_tmp_last_1 <= x_i_tmp_1;
                x_i_tmp_last_2 <= x_i_tmp_2;
                x_i_tmp_last_3 <= x_i_tmp_3;
                x_i_tmp_last_4 <= x_i_tmp_4;
                x_i_tmp_last_5 <= x_i_tmp_5;
                x_i_tmp_last_6 <= x_i_tmp_6;
                x_i_tmp_last_7 <= x_i_tmp_7;
                
                state_machine <= state_s8;
            end
            
            state_s8: begin
                x_r_tmp_0 <= x_r_tmp_last_0 + x_r_tmp_last_2;
                x_r_tmp_1 <= x_r_tmp_last_1 + x_r_tmp_last_3;
                x_r_tmp_4 <= x_r_tmp_last_4 + x_r_tmp_last_6;
                x_r_tmp_5 <= x_r_tmp_last_5 + x_r_tmp_last_7;
                
                x_r_tmp_2 <= x_r_tmp_last_0 - x_r_tmp_last_2;
                x_r_tmp_3 <= x_r_tmp_last_1 - x_r_tmp_last_3;
                x_r_tmp_6 <= x_r_tmp_last_4 - x_r_tmp_last_6;
                x_r_tmp_7 <= x_r_tmp_last_5 - x_r_tmp_last_7;
                
                x_i_tmp_0 <= x_i_tmp_last_0 + x_i_tmp_last_2;
                x_i_tmp_1 <= x_i_tmp_last_1 + x_i_tmp_last_3;
                x_i_tmp_4 <= x_i_tmp_last_4 + x_i_tmp_last_6;
                x_i_tmp_5 <= x_i_tmp_last_5 + x_i_tmp_last_7;
                
                x_i_tmp_2 <= x_i_tmp_last_0 - x_i_tmp_last_2;
                x_i_tmp_3 <= x_i_tmp_last_1 - x_i_tmp_last_3;
                x_i_tmp_6 <= x_i_tmp_last_4 - x_i_tmp_last_6;
                x_i_tmp_7 <= x_i_tmp_last_5 - x_i_tmp_last_7;
                
                state_machine <= state_s9;
            end
            
            state_s9: begin
                x_r_tmp_last_0 <= x_r_tmp_0;
                x_r_tmp_last_1 <= x_r_tmp_1;
                x_r_tmp_last_2 <= x_r_tmp_2;
                x_r_tmp_last_3 <= x_r_tmp_3;
                x_r_tmp_last_4 <= x_r_tmp_4;
                x_r_tmp_last_5 <= x_r_tmp_5;
                x_r_tmp_last_6 <= x_r_tmp_6;
                x_r_tmp_last_7 <= x_r_tmp_7;
            
                x_i_tmp_last_0 <= x_i_tmp_0;
                x_i_tmp_last_1 <= x_i_tmp_1;
                x_i_tmp_last_2 <= x_i_tmp_2;
                x_i_tmp_last_3 <= x_i_tmp_3;
                x_i_tmp_last_4 <= x_i_tmp_4;
                x_i_tmp_last_5 <= x_i_tmp_5;
                x_i_tmp_last_6 <= x_i_tmp_6;
                x_i_tmp_last_7 <= x_i_tmp_7;
                
                state_machine <= state_s10;
            end
            
            state_s10: begin
                x_r_tmp_4 <= (x_r_tmp_last_4 * w_r_0 / 10) - (x_i_tmp_last_4 * w_i_0 / 10);
                x_r_tmp_5 <= (x_r_tmp_last_5 * w_r_1 / 10) + (x_i_tmp_last_5 * w_i_1 / 10);
                x_r_tmp_6 <= (x_r_tmp_last_6 * w_r_2 / 10) + (x_i_tmp_last_6 * w_i_2 / 10);
                x_r_tmp_7 <= -(x_r_tmp_last_7 * w_r_3 / 10) + (x_i_tmp_last_7 * w_i_3 / 10);
                    
                x_i_tmp_4 <= (x_i_tmp_last_4 * w_r_0 / 10) + (x_r_tmp_last_4 * w_i_0 / 10);
                x_i_tmp_5 <= (x_i_tmp_last_5 * w_r_1 / 10) - (x_r_tmp_last_5 * w_i_1 / 10);
                x_i_tmp_6 <= (x_i_tmp_last_6 * w_r_2 / 10) - (x_r_tmp_last_6 * w_i_2 / 10);
                x_i_tmp_7 <= -(x_i_tmp_last_7 * w_r_3 / 10) - (x_r_tmp_last_7 * w_i_3 / 10);
                
                state_machine <= state_s11;
            end
            
            state_s11: begin
                x_r_tmp_last_0 <= x_r_tmp_0;
                x_r_tmp_last_1 <= x_r_tmp_1;
                x_r_tmp_last_2 <= x_r_tmp_2;
                x_r_tmp_last_3 <= x_r_tmp_3;
                x_r_tmp_last_4 <= x_r_tmp_4;
                x_r_tmp_last_5 <= x_r_tmp_5;
                x_r_tmp_last_6 <= x_r_tmp_6;
                x_r_tmp_last_7 <= x_r_tmp_7;
            
                x_i_tmp_last_0 <= x_i_tmp_0;
                x_i_tmp_last_1 <= x_i_tmp_1;
                x_i_tmp_last_2 <= x_i_tmp_2;
                x_i_tmp_last_3 <= x_i_tmp_3;
                x_i_tmp_last_4 <= x_i_tmp_4;
                x_i_tmp_last_5 <= x_i_tmp_5;
                x_i_tmp_last_6 <= x_i_tmp_6;
                x_i_tmp_last_7 <= x_i_tmp_7;
                
                state_machine <= state_s12;
            end
            
            state_s12: begin
                x_r_tmp_0 <= x_r_tmp_last_0 + x_r_tmp_last_4;
                x_r_tmp_1 <= x_r_tmp_last_1 + x_r_tmp_last_5;
                x_r_tmp_2 <= x_r_tmp_last_2 + x_r_tmp_last_6;
                x_r_tmp_3 <= x_r_tmp_last_3 + x_r_tmp_last_7;
                
                x_r_tmp_4 <= x_r_tmp_last_0 - x_r_tmp_last_4;
                x_r_tmp_5 <= x_r_tmp_last_1 - x_r_tmp_last_5;
                x_r_tmp_6 <= x_r_tmp_last_2 - x_r_tmp_last_6;
                x_r_tmp_7 <= x_r_tmp_last_3 - x_r_tmp_last_7;
                
                x_i_tmp_0 <= x_i_tmp_last_0 + x_i_tmp_last_4;
                x_i_tmp_1 <= x_i_tmp_last_1 + x_i_tmp_last_5;
                x_i_tmp_2 <= x_i_tmp_last_2 + x_i_tmp_last_6;
                x_i_tmp_3 <= x_i_tmp_last_3 + x_i_tmp_last_7;
                
                x_i_tmp_4 <= x_i_tmp_last_0 - x_i_tmp_last_4;
                x_i_tmp_5 <= x_i_tmp_last_1 - x_i_tmp_last_5;
                x_i_tmp_6 <= x_i_tmp_last_2 - x_i_tmp_last_6;
                x_i_tmp_7 <= x_i_tmp_last_3 - x_i_tmp_last_7;
                
                state_machine <= state_end;
            end
            
            state_end: begin
                y_i_0 <= (x_i_tmp_0);
                y_i_1 <= (x_i_tmp_1);
                y_i_2 <= (x_i_tmp_2);
                y_i_3 <= (x_i_tmp_3);
                y_i_4 <= (x_i_tmp_4);
                y_i_5 <= (x_i_tmp_5);
                y_i_6 <= (x_i_tmp_6);
                y_i_7 <= (x_i_tmp_7);
            
                y_r_0 <= (x_r_tmp_0);
                y_r_1 <= (x_r_tmp_1);
                y_r_2 <= (x_r_tmp_2);
                y_r_3 <= (x_r_tmp_3);
                y_r_4 <= (x_r_tmp_4);
                y_r_5 <= (x_r_tmp_5);
                y_r_6 <= (x_r_tmp_6);
                y_r_7 <= (x_r_tmp_7);
                
                state_machine <= state_start;
            end             
            
            default: begin
                state_machine <= state_start;
            end
            
        endcase
    end
    
endmodule

接下來是testbench文件

`timescale 1ns / 1ns

`define clock_period 200

module FFT_8_tb;

    reg                    clk;
    reg                    rst_n;
    
    reg signed [4:0] x_r_0;
    reg signed [4:0] x_r_1;
    reg signed [4:0] x_r_2;
    reg signed [4:0] x_r_3;
    reg signed [4:0] x_r_4;
    reg signed [4:0] x_r_5;
    reg signed [4:0] x_r_6;
    reg signed [4:0] x_r_7;

    reg signed [4:0] x_i_0;
    reg signed [4:0] x_i_1;
    reg signed [4:0] x_i_2;
    reg signed [4:0] x_i_3;
    reg signed [4:0] x_i_4;
    reg signed [4:0] x_i_5;
    reg signed [4:0] x_i_6;
    reg signed [4:0] x_i_7;


    wire signed [6:0] y_r_0;
    wire signed [6:0] y_r_1;
    wire signed [6:0] y_r_2;
    wire signed [6:0] y_r_3;
    wire signed [6:0] y_r_4;
    wire signed [6:0] y_r_5;
    wire signed [6:0] y_r_6;
    wire signed [6:0] y_r_7;

    wire signed [6:0] y_i_0;
    wire signed [6:0] y_i_1;
    wire signed [6:0] y_i_2;
    wire signed [6:0] y_i_3;
    wire signed [6:0] y_i_4;
    wire signed [6:0] y_i_5;
    wire signed [6:0] y_i_6;
    wire signed [6:0] y_i_7;
    
    FFT_8 FFT_8_Inst(
        .clk(clk),
        .rst_n(rst_n),
        
        .x_r_0(x_r_0),    //輸入實部
        .x_r_1(x_r_1),
        .x_r_2(x_r_2),
        .x_r_3(x_r_3),
        .x_r_4(x_r_4),
        .x_r_5(x_r_5),
        .x_r_6(x_r_6),
        .x_r_7(x_r_7),
        
        .x_i_0(x_i_0),    //輸入虛部
        .x_i_1(x_i_1),
        .x_i_2(x_i_2),
        .x_i_3(x_i_3),
        .x_i_4(x_i_4),
        .x_i_5(x_i_5),
        .x_i_6(x_i_6),
        .x_i_7(x_i_7),
        
        .y_r_0(y_r_0),    //輸出實部
        .y_r_1(y_r_1),
        .y_r_2(y_r_2),
        .y_r_3(y_r_3),
        .y_r_4(y_r_4),
        .y_r_5(y_r_5),
        .y_r_6(y_r_6),
        .y_r_7(y_r_7),
        
        .y_i_0(y_i_0),    //輸出虛部
        .y_i_1(y_i_1),
        .y_i_2(y_i_2),
        .y_i_3(y_i_3),
        .y_i_4(y_i_4),
        .y_i_5(y_i_5),
        .y_i_6(y_i_6),
        .y_i_7(y_i_7)
    );
    
    initial clk = 1;
    always #(`clock_period/2) clk = ~clk;
    
    initial begin
    
        rst_n = 1'b0;
        
        x_r_0 = 5'd0;
        x_r_1 = 5'd0;
        x_r_2 = 5'd0;
        x_r_3 = 5'd0;
        x_r_4 = 5'd0;
        x_r_5 = 5'd0;
        x_r_6 = 5'd0;
        x_r_7 = 5'd0;
        
        x_i_0 = 5'd0;    
        x_i_1 = 5'd0;
        x_i_2 = 5'd0;
        x_i_3 = 5'd0;
        x_i_4 = 5'd0;
        x_i_5 = 5'd0;
        x_i_6 = 5'd0;
        x_i_7 = 5'd0;
        
        #(`clock_period*10 + 1);
        
        rst_n = 1'b1;
        
        x_r_0 = 5'b0_1110;
        x_r_1 = 5'b0;
        x_r_2 = 5'b0_0110;
        x_r_3 = 5'b0;
        x_r_4 = 5'b0_0101;
        x_r_5 = 5'b0;
        x_r_6 = 5'b0_1111;
        x_r_7 = 5'b0;
        
        x_i_0 = 5'd0;
        x_i_1 = 5'd0;
        x_i_2 = 5'd0;
        x_i_3 = 5'd0;
        x_i_4 = 5'd0;
        x_i_5 = 5'd0;
        x_i_6 = 5'd0;
        x_i_7 = 5'd0;
        
        #(`clock_period*50);
        
        x_r_0 = 5'b0_0101;
        x_r_1 = 5'b0_0101;
        x_r_2 = 5'b0_0101;
        x_r_3 = 5'b0_0101;
        x_r_4 = 5'b0_0101;
        x_r_5 = 5'b0_0101;
        x_r_6 = 5'b0_0101;
        x_r_7 = 5'b0_0101;
        
        x_i_0 = 5'd0;
        x_i_1 = 5'd0;
        x_i_2 = 5'd0;
        x_i_3 = 5'd0;
        x_i_4 = 5'd0;
        x_i_5 = 5'd0;
        x_i_6 = 5'd0;
        x_i_7 = 5'd0;
        
        #(`clock_period*50);
        
        $stop;
    end
    
endmodule

 


免責聲明!

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



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