8点按时间抽取的基2 FFT的Verilog实现

懵懂的女人 提交于 2019-11-30 19:59:00

这是第一次用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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!