参照《自己动手做CPU》自己动手做CPU

前几天参照《自己动手做CPU》一书利用vivado自己做了CPU,当然我只是个学生的水平,这里仅仅作为记录,希望可以给大家一定意义的参考。

文件关系

SampleCPU文件夹里

其中lib文件夹中

mul文件夹中

 代码

这次的大作业不是我一个人完成的,也要感谢舍友的大力相助,还有些内容不是我完成的,所以就不公开啦,我只公开我们自己写的部分。

流程图

IF模块

`include "lib/defines.vh"
module IF(
    input wire clk,  //传入时钟周期
    input wire rst,  //复位信号,负责初始化各项数据
    input wire [`StallBus-1:0] stall, //停止信号,负责暂停流水线
    input wire [`BR_WD-1:0] br_bus,   //从ID段传入,存放指令跳转的相关信息
    output wire [`IF_TO_ID_WD-1:0] if_to_id_bus,  //IF段到ID段的总线,将IF段的数据进行打包
    output wire inst_sram_en, //能不能从内存读取指令的使能
    output wire [3:0] inst_sram_wen,//能不能向内存中写入数据的使能
    output wire [31:0] inst_sram_addr,//写入内存时的写入地址
    output wire [31:0] inst_sram_wdata//写入内存的数据
    // input wire flush,
    // input wire [31:0] new_pc,
);
    reg [31:0] pc_reg;
    reg ce_reg;
    wire [31:0] next_pc;
    wire br_e;
    wire [31:0] br_addr;

    assign {
        br_e,
        br_addr
    } = br_bus;


    always @ (posedge clk) begin
        if (rst) begin
            pc_reg <= 32'hbfbf_fffc;
        end
        else if (stall[0]==`NoStop) begin
            pc_reg <= next_pc;
        end
    end

    always @ (posedge clk) begin
        if (rst) begin
            ce_reg <= 1'b0;
        end
        else if (stall[0]==`NoStop) begin
            ce_reg <= 1'b1;
        end
    end


    assign next_pc = br_e ? br_addr 
                   : pc_reg + 32'h4;
    //判断是否需要跳转,若跳转使用传进来的跳转地址,否则选择pc+4

    
    assign inst_sram_en = ce_reg;
    assign inst_sram_wen = 4'b0;
    assign inst_sram_addr = pc_reg;
    assign inst_sram_wdata = 32'b0;
    assign if_to_id_bus = {
        ce_reg,
        pc_reg
    };

endmodule

ID模块

`include "lib/defines.vh"
module ID(
    //这个覆盖了书中ID段和ID/EX段

    input wire clk,
    input wire rst,
    // input wire flush,
    input wire [`StallBus-1:0] stall,
    
    output wire stallreq,

    input wire [`IF_TO_ID_WD-1:0] if_to_id_bus,

    input wire [31:0] inst_sram_rdata,

    input wire [`WB_TO_RF_WD-1:0] wb_to_rf_bus,

    input wire [`EX_TO_RF_BUS-1:0] ex_to_rf_bus,//Siri

    input wire [`WB_TO_RF_WD-1:0] mem_to_rf_bus,//Siri


    output wire [`ID_TO_EX_WD-1:0] id_to_ex_bus,

    output wire [`BR_WD-1:0] br_bus

    //Siri


);
    
    //Siri
    //读入mem的返回值
    wire mem_to_rf_we;
    wire [4:0] mem_to_rf_waddr;
    wire [31:0] mem_to_rf_wdata;
    assign {
        mem_to_rf_we,
        mem_to_rf_waddr,
        mem_to_rf_wdata
    }=mem_to_rf_bus;
    //Siri

    //Siri
    //读入ex的返回值
    wire ex_to_rf_we;
    wire [4:0] ex_to_rf_waddr;
    wire [31:0] ex_to_rf_wdata;
    wire [5:0] ex_op;

    assign{
        ex_op,
        ex_to_rf_we,
        ex_to_rf_waddr,
        ex_to_rf_wdata
    }=ex_to_rf_bus;
    //Siri





    reg [`IF_TO_ID_WD-1:0] if_to_id_bus_r;
    wire [31:0] inst;
    wire [31:0] id_pc;
    wire ce;

    wire wb_rf_we;
    wire [4:0] wb_rf_waddr;
    wire [31:0] wb_rf_wdata;

    reg id_stop;

    always @ (posedge clk) begin
        if (rst) begin
            if_to_id_bus_r <= `IF_TO_ID_WD'b0;
            id_stop <=1'b0;        
        end
        
        // else if (flush) begin
        //     ic_to_id_bus <= `IC_TO_ID_WD'b0;
        // end
        
        else if (stall[1]==`Stop && stall[2]==`NoStop) begin
            if_to_id_bus_r <= `IF_TO_ID_WD'b0;
            id_stop <=1'b0;  
        end
        else if (stall[1]==`NoStop) begin
            if_to_id_bus_r <= if_to_id_bus;
            id_stop <=1'b0;  
        end 
        else if (stall[2]==`Stop)begin
            id_stop <= 1'b1;
        end
    end
    

    
    assign inst = (~id_stop)?inst_sram_rdata:inst;
    assign {
        ce,
        id_pc
    } = if_to_id_bus_r;
    assign {
        wb_rf_we,
        wb_rf_waddr,
        wb_rf_wdata
    } = wb_to_rf_bus;

    wire [5:0] opcode;
    wire [4:0] rs,rt,rd,sa;
    wire [5:0] func;
    wire [15:0] imm;
    wire [25:0] instr_index;
    wire [19:0] code;
    wire [4:0] base;
    wire [15:0] offset;
    wire [2:0] sel;

    wire [63:0] op_d, func_d;
    wire [31:0] rs_d, rt_d, rd_d, sa_d;

    wire [2:0] sel_alu_src1;
    wire [3:0] sel_alu_src2;
    wire [11:0] alu_op;

    wire data_ram_en;
    wire stop_div_mul;
    wire [3:0] data_ram_wen;
    
    wire rf_we;
    wire [4:0] rf_waddr;
    wire sel_rf_res;
    wire [2:0] sel_rf_dst;//modified

    wire [31:0] rdata1, rdata2;
    wire [31:0] rdata1_1, rdata2_1;
   

    assign opcode = inst[31:26];
    assign rs = inst[25:21];//reg1_addr_o
    assign rt = inst[20:16];//reg2_addr_o
    assign rd = inst[15:11];
    assign sa = inst[10:6];
    assign func = inst[5:0];
    assign imm = inst[15:0];
    assign instr_index = inst[25:0];
    assign code = inst[25:6];
    assign base = inst[25:21];
    assign offset = inst[15:0];
    assign sel = inst[2:0];

    regfile u_regfile(
    	.clk    (clk    ),
        .raddr1 (rs ),
        .rdata1 (rdata1_1 ),
        .raddr2 (rt ),
        .rdata2 (rdata2_1 ),
        .we     (wb_rf_we     ),
        .waddr  (wb_rf_waddr  ),
        .wdata  (wb_rf_wdata  )
    ); 
     
    assign rdata1 = (ce == 1'b0) ? 32'b0 : ((ex_to_rf_we == 1'b1 ) && (ex_to_rf_waddr==rs)) ? 
                        ex_to_rf_wdata :((mem_to_rf_we == 1'b1) && (mem_to_rf_waddr==rs))? mem_to_rf_wdata : rdata1_1 ;
    assign rdata2 = (ce == 1'b0) ? 32'b0 : ((ex_to_rf_we == 1'b1 ) && (ex_to_rf_waddr==rt)) ? 
                        ex_to_rf_wdata :((mem_to_rf_we == 1'b1) && (mem_to_rf_waddr==rt))? mem_to_rf_wdata : rdata2_1 ;

    
    
    
    
    //Siri
    wire inst_ori, inst_lui, inst_addiu;
    wire inst_add,inst_addi,inst_addu;
    wire inst_sub,inst_subu;
    wire inst_slt,inst_slti,inst_sltu,inst_sltiu;
    wire inst_div,inst_divu,inst_mult,inst_multu;//乘除
    wire inst_and,inst_andi,inst_nor,inst_or,inst_xor,inst_xori;   //

    //移位
    wire inst_sllv,inst_sll;//逻辑左移
    wire inst_srav,inst_sra;//算术右移
    wire inst_srlv,inst_srl;//逻辑右移

    //分支跳转
    wire inst_bne;//不等跳转
    wire inst_bgez,inst_bgtz;//大于(&?等于)0跳转
    wire inst_blez,inst_bltz;//小于(&?等于)0跳转
    wire inst_bgezal;//大于等于0跳转,并保存pc值至通用寄存器
    wire inst_bltzal;//小于0跳转,并保存pc值至通用寄存器
    wire inst_beq,inst_beqz;

    wire inst_j,inst_jal,inst_jr,inst_jalr;//无条件跳转

    //数据移动
    wire inst_mfhi,inst_mflo,inst_mthi,inst_mtlo;

    //自陷指令
    wire inst_break,inst_syscall;

    //访存指令
    wire inst_lb,inst_lbu;
    wire inst_lh,inst_lhu;
    wire inst_lw;
    wire inst_sb,inst_sh,inst_sw;

    //特权指令
    wire inst_eret;
    wire inst_mfc0;
    wire inst_mtc0;
    //


    wire op_add, op_sub, op_slt, op_sltu;
    wire op_and, op_nor, op_or, op_xor;
    wire op_sll, op_srl, op_sra, op_lui;


    decoder_6_64 u0_decoder_6_64(
    	.in  (opcode  ),
        .out (op_d )
    );

    decoder_6_64 u1_decoder_6_64(
    	.in  (func  ),
        .out (func_d )
    );
    
    decoder_5_32 u0_decoder_5_32(
    	.in  (rs  ),
        .out (rs_d )
    );

    decoder_5_32 u1_decoder_5_32(
    	.in  (rt  ),
        .out (rt_d )
    );

    
    assign inst_add     = op_d[6'b00_0000]&func_d[6'b10_0000];
    assign inst_addi    = op_d[6'b00_1000];
    assign inst_addu    = op_d[6'b00_0000]&func_d[6'b10_0001];
    assign inst_addiu   = op_d[6'b00_1001];

    assign inst_sub     = op_d[6'b00_0000]&func_d[6'b10_0010];
    assign inst_subu    = op_d[6'b00_0000]&func_d[6'b10_0011];
    
    assign inst_slt     = op_d[6'b00_0000]&func_d[6'b10_1010];
    assign inst_slti    = op_d[6'b00_1010];
    assign inst_sltu    = op_d[6'b00_0000]&func_d[6'b10_1011];
    assign inst_sltiu   = op_d[6'b00_1011];

    assign inst_div     = op_d[6'b000000]&func_d[6'b011010];
    assign inst_divu    = op_d[6'b000000]&func_d[6'b011011];
    assign inst_mult    = op_d[6'b000000]&func_d[6'b011000];
    assign inst_multu   = op_d[6'b000000]&func_d[6'b011001];

    assign inst_and     = op_d[6'b00_0000]&func_d[6'b10_0100];
    assign inst_andi    = op_d[6'b00_1100];
    assign inst_lui     = op_d[6'b00_1111];
    assign inst_nor     = op_d[6'b00_0000]&func_d[6'b10_0111];
    assign inst_or      = op_d[6'b00_0000]&func_d[6'b10_0101];
    assign inst_ori     = op_d[6'b00_1101];
    assign inst_xor     = op_d[6'b00_0000]&func_d[6'b10_0110];
    assign inst_xori    = op_d[6'b00_1110];

    assign inst_sllv    = op_d[6'b00_0000]&func_d[6'b00_0100];
    assign inst_sll     = op_d[6'b00_0000]&func_d[6'b00_0000];

    assign inst_srav    = op_d[6'b00_0000]&func_d[6'b00_0111];
    assign inst_sra     = op_d[6'b00_0000]&func_d[6'b00_0011];

    assign inst_srlv    = op_d[6'b00_0000]&func_d[6'b00_0110];
    assign inst_srl     = op_d[6'b00_0000]&func_d[6'b00_0010];

    assign inst_beq     = op_d[6'b00_0100];
    assign inst_beqz    = op_d[6'b00_0100];   //*****************
    assign inst_bne     = op_d[6'b00_0101];
    assign inst_bgez    = op_d[6'b00_0001]&rt_d[5'b0_0001];
    assign inst_bgtz    = op_d[6'b00_0111];
    assign inst_blez    = op_d[6'b00_0110];
    assign inst_bltz    = op_d[6'b00_0001]&rt_d[5'b0_0000];
    assign inst_bgezal  = op_d[6'b00_0001]&rt_d[5'b1_0001];
    assign inst_bltzal  = op_d[6'b00_0001]&rt_d[5'b1_0000];
    assign inst_j       = op_d[6'b00_0010];
    assign inst_jal     = op_d[6'b00_0011];
    assign inst_jr      = op_d[6'b00_0000]&func_d[6'b00_1000];
    assign inst_jalr    = op_d[6'b00_0000]&func_d[6'b00_1001];

    assign inst_mfhi    = op_d[6'b00_0000]&func_d[6'b01_0000];
    assign inst_mflo    = op_d[6'b00_0000]&func_d[6'b01_0010];
    assign inst_mthi    = op_d[6'b00_0000]&func_d[6'b01_0001];
    assign inst_mtlo    = op_d[6'b00_0000]&func_d[6'b01_0011];

    assign inst_break   = op_d[6'b00_0000]&func_d[6'b00_1101];
    assign inst_syscall = op_d[6'b00_0000]&func_d[6'b00_1100];

    assign inst_lb      = op_d[6'b10_0000];
    assign inst_lbu     = op_d[6'b10_0100];
    assign inst_lh      = op_d[6'b10_0001];
    assign inst_lhu     = op_d[6'b10_0101];
    assign inst_lw      = op_d[6'b10_0011];
    assign inst_sb      = op_d[6'b10_1000];
    assign inst_sh      = op_d[6'b10_1001];
    assign inst_sw      = op_d[6'b10_1011];

    assign inst_eret    = op_d[6'b01_0000]&inst[25];
    assign inst_mfc0    = op_d[6'b01_0000]&rs_d[5'b0_0000];
    assign inst_mtc0    = op_d[6'b01_0000]&rs_d[5'b0_0100];
    //Siri

    assign id_pc_plus8 = id_pc+32'h8;
    wire  [31:0] idc1;
    wire [31:0] idc2;

    // rs to reg1
    assign sel_alu_src1[0] = inst_add|inst_addi|inst_addu|inst_addiu|
                             inst_sub|inst_subu|
                             inst_div|inst_divu|inst_mult|inst_multu|
                             inst_slt|inst_slti|inst_sltu|inst_sltiu|
                             inst_and|inst_andi|inst_nor|inst_or|inst_ori|inst_xor|inst_xori|
                             inst_sllv|inst_srav|inst_srlv|
                             inst_jr|inst_bgez|
                             inst_lw|inst_sw|
                             inst_jalr|
                             inst_mthi|inst_mtlo|
                             inst_lb|inst_sb|inst_sh|inst_lh|inst_lbu|inst_lhu;//除了第一行都是新加的

    // pc to reg1
    assign sel_alu_src1[1] = inst_jal|inst_bgezal|inst_bltzal|inst_jalr;
    

    // sa_zero_extend to reg1
    assign sel_alu_src1[2] = inst_sll|inst_sra|inst_srl;
   
    
    // rt to reg2
    assign sel_alu_src2[0] = inst_add|inst_addu|
                             inst_sub|inst_subu|
                             inst_div|inst_divu|inst_mult|inst_multu|
                             inst_slt|inst_sltu|inst_sltiu|
                             inst_and|inst_nor|inst_or|inst_xor|inst_sll|
                             inst_sw|inst_sllv|inst_sra|inst_srav|inst_srl|inst_srlv|inst_sb|inst_sh;
    
    // imm_sign_extend to reg2
    assign sel_alu_src2[1] = inst_lui|inst_addiu|
                             inst_addi|
                             inst_slti|inst_sltiu;
    
    

    // 32'h8 to reg2
    assign sel_alu_src2[2] = inst_jal|inst_bgezal|inst_bltzal|inst_jalr;
    

    // imm_zero_extend to reg2
    assign sel_alu_src2[3] = inst_ori|inst_andi|inst_xori;




    assign op_add = inst_addiu|inst_add|inst_addi|inst_addu
                    |inst_jal|inst_jalr|inst_bgezal|inst_bltzal;
    assign op_sub = inst_sub|inst_subu;
    assign op_slt = inst_slt|inst_slti;
    assign op_sltu = inst_sltiu|inst_sltu;
    assign op_and = inst_and|inst_andi;
    assign op_nor = inst_nor;//或非
    assign op_or = inst_ori|inst_or;//或
    assign op_xor = inst_xor|inst_xori;//异或
    assign op_sll = inst_sll|inst_sllv;
    assign op_srl = inst_srl|inst_srlv;
    assign op_sra = inst_sra|inst_srav;
    assign op_lui = inst_lui;

    assign alu_op = {op_add, op_sub, op_slt, op_sltu,
                     op_and, op_nor, op_or, op_xor,
                     op_sll, op_srl, op_sra, op_lui};



    // load and store enable
    assign data_ram_en = inst_sw|inst_lw|inst_lb|inst_sb|inst_sh|inst_lh|inst_lbu|inst_lhu;
    assign stop_div_mul = inst_divu|inst_div;
    // |inst_mult|inst_multu;

    // write enable
    assign data_ram_wen = inst_sw?4'b1111:inst_sb?4'b0001:inst_sh?4'b0011:4'b0;
    wire [3:0] lb_lh_lw;
    assign lb_lh_lw = inst_lw?4'b1111:inst_lh?4'b0011:inst_lb?4'b0001:inst_lbu?4'b0101:inst_lhu?4'b0111:4'b0;
    // wire [1:0]sb_sh_en;
    // assign sb_sh_en = {inst_sb,inst_sh};



    // regfile store enable
    assign rf_we = inst_ori|inst_lui| inst_addiu | inst_beq
                |inst_add|inst_addi|inst_addu
                |inst_sub|inst_subu
                |inst_slt|inst_slti|inst_sltu|inst_sltiu
                |inst_and|inst_andi|inst_nor|inst_or|inst_xor|inst_xori
                |inst_sllv|inst_sll  //逻辑左移
                |inst_srav|inst_sra  //算术右移
                | inst_srlv|inst_srl  //逻辑右移
                |inst_bgezal  //大于等于0跳转,并保存pc值至通用寄存器
                |inst_bltzal  //小于0跳转,并保存pc值至通用寄存器
                |inst_jal|inst_jalr //无条件跳转
                |inst_lw
                |inst_mfhi|inst_mflo|
                inst_lb|inst_lh|inst_lbu|inst_lhu;  


    // store in [rd]
    assign sel_rf_dst[0] = inst_add|inst_addu|
                           inst_sub|inst_subu|
                           inst_slt|inst_sltu|
                           inst_and|inst_nor|inst_or|inst_xor|inst_sll|inst_sllv|
                           inst_sra|inst_srav|
                           inst_srl|inst_srlv|
                           inst_jalr|
                           inst_mfhi|inst_mflo;    
    // store in [rt] 
    assign sel_rf_dst[1] = inst_ori | inst_lui | inst_addiu|
                           inst_slti|inst_sltiu|inst_andi|inst_ori|inst_xori
                           |inst_lw|inst_addi|inst_lb|inst_lh|inst_lbu|inst_lhu;
    // store in [31]
    assign sel_rf_dst[2] = inst_jal|inst_bltzal|inst_bgezal;


    // sel for regfile address
    assign rf_waddr = {5{sel_rf_dst[0]}} & rd 
                    | {5{sel_rf_dst[1]}} & rt
                    | {5{sel_rf_dst[2]}} & 32'd31;
        

    // 0 from alu_res ; 1 from ld_res
    assign sel_rf_res = inst_lw|inst_lb|inst_lh|inst_lbu|inst_lhu; 


    //hilo
    wire hilo_we;
    wire [1:0] hilo_read;
    wire [1:0] hilo_write;
    wire signed_mul_i;//是否为有符号乘法运算,1为有符号
    wire [1:0]div_divu;
    // read from hi lo
    assign hilo_read = {inst_mfhi,inst_mflo};
    
    // write to hi lo
    assign hilo_write = {inst_mthi,inst_mtlo};
    assign hilo_we = inst_mthi|inst_mtlo|inst_divu|inst_div|inst_mult|inst_multu;
    
    assign signed_mul_i = inst_mult;
    assign div_divu = {inst_div,inst_divu};

    /

    assign id_to_ex_bus = {
        lb_lh_lw,       //171:168
        signed_mul_i,   //167
        stop_div_mul,   //166
        div_divu,       //165:164   
        hilo_write,     //163:162
        hilo_we,        //161
        hilo_read,      //160:159
        id_pc,          // 158:127
        inst,           // 126:95
        alu_op,         // 94:83
        sel_alu_src1,   // 82:80
        sel_alu_src2,   // 79:76
        data_ram_en,    // 75
        data_ram_wen,   // 74:71
        rf_we,          // 70
        rf_waddr,       // 69:65
        sel_rf_res,     // 64
        rdata1,         // 63:32
        rdata2          // 31:0
    };

    wire br_e;
    wire [31:0] br_addr;
    wire rs_eq_rt;
    wire rs_ge_z;
    wire rs_gt_z;
    wire rs_le_z;
    wire rs_lt_z;
    wire rs_eq_z;
    wire [31:0] pc_plus_4;
    assign pc_plus_4 = id_pc + 32'h4;

    assign rs_eq_rt = (rdata1 == rdata2);
    assign rs_ge_z  = (rdata1 >= 0 & rdata1[31] != 1);
    assign rs_gt_z  = (rdata1 >  0 & rdata1[31] != 1);
    assign rs_le_z  = (rdata1[31]==1|rdata1==32'b0);
    assign rs_lt_z  = (rdata1[31]==1);
    assign rs_eq_z  = ~rdata1;

    assign br_e = inst_beq & rs_eq_rt|
                  inst_bne & !rs_eq_rt|
                  (inst_bgez|inst_bgezal) & rs_ge_z|
                  inst_bgtz & rs_gt_z|
                  inst_blez & rs_le_z|
                  (inst_bltz|inst_bltzal) & rs_lt_z|
                  inst_j|inst_jal|inst_jr|inst_jalr;
                  //|inst_beqz & rs_eq_z;   *********************
    assign br_addr = inst_beq|inst_bne|inst_bgez|inst_bgtz|inst_blez|inst_bltz|inst_bgezal|inst_bltzal ?
                     (pc_plus_4 + {{14{inst[15]}},inst[15:0],2'b0}) : 
                     inst_j|inst_jal ?
                     {pc_plus_4[31:28],instr_index,2'b0} :
                     inst_jr|inst_jalr ?
                     rdata1 :
                     32'b0;
    assign br_bus = {
        br_e,//是否执行相等的跳转
        br_addr//跳转位置
    };

    //stall相关
    wire load_stop;
    assign load_stop = (ex_op==6'b10_0011) | (ex_op==6'b10_0000) | (ex_op==6'b10_1011)| (ex_op==6'b10_1001)| (ex_op==6'b10_1000)|
                       (ex_op==6'b10_0001) | (ex_op==6'b10_0100) | (ex_op==6'b10_0101);
    assign stallreq=(load_stop&&(ce==1'b1)&&(ex_to_rf_we==1'b1)&&(ex_to_rf_waddr==rs))?
    `Stop :(load_stop&&(ce==1'b1)&&(ex_to_rf_we==1'b1)&&(ex_to_rf_waddr==rt))? `Stop: `NoStop;



    
    

endmodule

EX模块

`include "lib/defines.vh"
module EX(
    input wire clk,//传入时钟周期
    input wire rst,//复位信号,负责初始化各项数据
    input wire [`StallBus-1:0] stall,//停止信号,负责暂停流水线
    input wire [`ID_TO_EX_WD-1:0] id_to_ex_bus,//ID段到EX段的总线
    output wire [`EX_TO_MEM_WD-1:0] ex_to_mem_bus,//EX段到MEM段的总线
    output wire data_sram_en,//是否对内存有操作
    output wire [3:0] data_sram_wen,//写入内存的使能
    output wire [31:0] data_sram_addr,//写入的内存的地址
    output wire [31:0] data_sram_wdata,//写入内存的数据
    output wire [`EX_TO_RF_BUS-1:0] ex_to_rf_bus,//EX段到ID段的总线
    output wire stallreq_for_ex // 判断是否需要暂停(乘法,除法)
    // input wire flush,
);

    reg [`ID_TO_EX_WD-1:0] id_to_ex_bus_r;

    always @ (posedge clk) begin
        if (rst) begin
            id_to_ex_bus_r <= `ID_TO_EX_WD'b0;
        end
        // else if (flush) begin
        //     id_to_ex_bus_r <= `ID_TO_EX_WD'b0;
        // end
        else if (stall[2]==`Stop && stall[3]==`NoStop) begin
            id_to_ex_bus_r <= `ID_TO_EX_WD'b0;
        end
        else if (stall[2]==`NoStop) begin
            id_to_ex_bus_r <= id_to_ex_bus;
        end
    end

    wire [31:0] ex_pc, inst;
    wire [11:0] alu_op;
    wire [2:0] sel_alu_src1;
    wire [3:0] sel_alu_src2;
    //wire data_ram_en;
    //wire [3:0] data_ram_wen;
    wire rf_we;
    wire [4:0] rf_waddr;
    wire sel_rf_res;
    wire [31:0] rf_rdata1, rf_rdata2;
    wire [1:0] hilo_read;
    wire hilo_we;
    wire [1:0] hilo_write;
    wire stop_div_mul;
    wire signed_mul_i;
    wire [1:0]div_divu;
    wire [1:0]sb_sh_en;
    wire [1:0]mul_mulu;
    //reg is_in_delayslot;
    wire [3:0]new_data_sram_wen;
    wire [3:0]lb_lh_lw;
    assign {
        mul_mulu,
        lb_lh_lw,
        signed_mul_i,
        stop_div_mul,
        div_divu,       //166:165
        // signed_div_i,
        hilo_write,
        hilo_we,
        hilo_read,      
        ex_pc,          // 148:117
        inst,           // 116:85
        alu_op,         // 84:83
        sel_alu_src1,   // 82:80
        sel_alu_src2,   // 79:76
        data_sram_en,    // 75
        new_data_sram_wen,   // 74:71
        rf_we,          // 70
        rf_waddr,       // 69:65
        sel_rf_res,     // 64
        rf_rdata1,         // 63:32
        rf_rdata2          // 31:0
    } = id_to_ex_bus_r;

    //load store相关
    wire [5:0] ld_st_op;
    assign ld_st_op=data_sram_en?inst[31:26]: 6'b00_0000;
    assign data_sram_addr=data_sram_en?rf_rdata1+{{16{inst[15]}},inst[15:0]}:32'b0;
    assign data_sram_wen=    (new_data_sram_wen == 4'b1111)?4'b1111:
                             ((new_data_sram_wen == 4'b0011)&(data_sram_addr[1:0]==2'b00))?4'b0011:
                             ((new_data_sram_wen == 4'b0011)&(data_sram_addr[1:0]==2'b10))?4'b1100:
                             ((new_data_sram_wen == 4'b0001)&(data_sram_addr[1:0]==2'b00))?4'b0001:
                             ((new_data_sram_wen == 4'b0001)&(data_sram_addr[1:0]==2'b01))?4'b0010:
                             ((new_data_sram_wen == 4'b0001)&(data_sram_addr[1:0]==2'b10))?4'b0100:
                             ((new_data_sram_wen == 4'b0001)&(data_sram_addr[1:0]==2'b11))?4'b1000:4'b0;

    assign data_sram_wdata=(data_sram_wen == 4'b1111)?rf_rdata2:
                           (data_sram_wen == 4'b0011)?{16'b0,rf_rdata2[15:0]}:
                           (data_sram_wen == 4'b1100)?{rf_rdata2[15:0],16'b0}:
                           (data_sram_wen == 4'b1000)?{rf_rdata2[7:0],24'b0}:
                           (data_sram_wen == 4'b0100)?{8'b0,rf_rdata2[7:0],16'b0}:
                           (data_sram_wen == 4'b0010)?{16'b0,rf_rdata2[7:0],8'b0}:
                           (data_sram_wen == 4'b0001)?{24'b0,rf_rdata2[7:0]}:32'b0;
    
    


    // {
    //                            new_data_sram_wen[3]?rf_rdata2[31:24]:8'b0,
    //                            new_data_sram_wen[2]?rf_rdata2[23:16]:8'b0,
    //                            new_data_sram_wen[1]?rf_rdata2[15:8]:8'b0,
    //                            new_data_sram_wen[0]?rf_rdata2[7:0]:8'b0
    //                        };

    wire [4:0] new_lb_lw_lh;
    assign new_lb_lw_lh =    ( lb_lh_lw == 4'b1111)?5'b1_1111:
                             ((lb_lh_lw == 4'b0011)&(data_sram_addr[1:0]==2'b00))?5'b1_1100:
                             ((lb_lh_lw == 4'b0011)&(data_sram_addr[1:0]==2'b10))?5'b1_0011:
                             ((lb_lh_lw == 4'b0001)&(data_sram_addr[1:0]==2'b00))?5'b1_1000:
                             ((lb_lh_lw == 4'b0001)&(data_sram_addr[1:0]==2'b01))?5'b1_0100:
                             ((lb_lh_lw == 4'b0001)&(data_sram_addr[1:0]==2'b10))?5'b1_0010:
                             ((lb_lh_lw == 4'b0001)&(data_sram_addr[1:0]==2'b11))?5'b1_0001:
                             ((lb_lh_lw == 4'b0111)&(data_sram_addr[1:0]==2'b00))?5'b0_1100:
                             ((lb_lh_lw == 4'b0111)&(data_sram_addr[1:0]==2'b10))?5'b0_0011:
                             ((lb_lh_lw == 4'b0101)&(data_sram_addr[1:0]==2'b00))?5'b0_1000:
                             ((lb_lh_lw == 4'b0101)&(data_sram_addr[1:0]==2'b01))?5'b0_0100:
                             ((lb_lh_lw == 4'b0101)&(data_sram_addr[1:0]==2'b10))?5'b0_0010:
                             ((lb_lh_lw == 4'b0101)&(data_sram_addr[1:0]==2'b11))?5'b0_0001:5'b0_0000;

     



    wire [31:0] imm_sign_extend, imm_zero_extend, sa_zero_extend;
    assign imm_sign_extend = {{16{inst[15]}},inst[15:0]};
    assign imm_zero_extend = {16'b0, inst[15:0]};
    assign sa_zero_extend = {27'b0,inst[10:6]};

    //数据移动指令相关
    
    

    wire [31:0] alu_src1, alu_src2;
    wire [31:0] alu_result, ex_result;
    wire [2:0] lsa_data;
    assign lsa_data = inst[7:6] + 1'b1;

   

    assign alu_src1 = sel_alu_src1[1] ? ex_pc :
                      sel_alu_src1[2] ? sa_zero_extend : 
                      (inst[31:26] == 6'b011100)? rf_rdata1 << lsa_data :rf_rdata1;

    assign alu_src2 = sel_alu_src2[1] ? imm_sign_extend :
                      sel_alu_src2[2] ? 32'h8 :
                      sel_alu_src2[3] ? imm_zero_extend : rf_rdata2;
    
    alu u_alu(
    	.alu_control (alu_op ), // 进行哪种运算
        .alu_src1    (alu_src1    ),// 第一个操作数
        .alu_src2    (alu_src2    ),// 第二个操作数
        .alu_result  (alu_result  ) // 计算结果
    );
///
    wire [63:0]hilo_data;
    wire [31:0]hi;
    wire [31:0]lo;



   

    
    

     // MUL part
    wire [63:0] mul_result;
    wire mul_signed; // 有符号乘法标记
    wire inst_mul, inst_mulu;
    assign {inst_mul,inst_mulu} = mul_mulu;
    assign mul_signed = signed_mul_i;
    wire mul_ready_i;
    reg mul_start_o;
    reg [31:0] mul_opdata1_o;
    reg [31:0] mul_opdata2_o;
    reg signed_mul_o;
     reg stallreq_for_mul;
    mul u_mul(
    	.clk        (clk            ), //时钟
        .resetn     (~rst           ), //复位信号
        .mul_signed (signed_mul_o     ),//是否是有符号的乘法
        .ina        (mul_opdata1_o      ), // 乘法源操作数1
        .inb        (mul_opdata2_o      ), // 乘法源操作数2
        .start_i    (mul_start_o  ),//乘法开始信号
        .ready_o    (mul_ready_i    ),//乘法结束信号
        .result     (mul_result     ) // 乘法结果 64bit
    );
    always @ (*) begin
        if (rst) begin
            stallreq_for_mul = `NoStop;
            mul_opdata1_o = `ZeroWord;
            mul_opdata2_o = `ZeroWord;
            mul_start_o = `DivStop;
            signed_mul_o = 1'b0;
        end
        else begin
            stallreq_for_mul = `NoStop;
            mul_opdata1_o = `ZeroWord;
            mul_opdata2_o = `ZeroWord;
            mul_start_o = `DivStop;
            signed_mul_o = 1'b0;
            case ({inst_mul,inst_mulu})
                2'b10:begin
                    if (mul_ready_i == `DivResultNotReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `DivStart;
                        signed_mul_o = 1'b1;
                        stallreq_for_mul = `Stop;
                    end
                    else if (mul_ready_i == `DivResultReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `DivStop;
                        signed_mul_o = 1'b1;
                        stallreq_for_mul = `NoStop;
                    end
                    else begin
                        mul_opdata1_o = `ZeroWord;
                        mul_opdata2_o = `ZeroWord;
                        mul_start_o = `DivStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                end
                2'b01:begin
                    if (mul_ready_i == `DivResultNotReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `DivStart;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `Stop;
                    end
                    else if (mul_ready_i == `DivResultReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `DivStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                    else begin
                        mul_opdata1_o = `ZeroWord;
                        mul_opdata2_o = `ZeroWord;
                        mul_start_o = `DivStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                end
                default:begin
                end
            endcase
        end
    end














    // DIV part
    wire [63:0] div_result;
    wire inst_div, inst_divu;
    wire div_ready_i;
    ///
    assign {inst_div,inst_divu} = div_divu;
    ///
    reg stallreq_for_div;
    assign stallreq_for_ex = stallreq_for_div|stallreq_for_mul;

    reg [31:0] div_opdata1_o;
    reg [31:0] div_opdata2_o;
    reg div_start_o;
    reg signed_div_o;
   div u_div(
    	.rst          (rst          ),//复位
        .clk          (clk          ),//时钟
        .signed_div_i (signed_div_o ),//是否为有符号除法运算
        .opdata1_i    (div_opdata1_o    ),//被除数
        .opdata2_i    (div_opdata2_o    ),//除数
        .start_i      (div_start_o      ),//是否开始除法运算
        .annul_i      (1'b0      ),//是否取消除法运算
        .result_o     (div_result     ), // 除法结果 64bit
        .ready_o      (div_ready_i      )//除法运算是否结束
    );

    always @ (*) begin
        if (rst) begin
            stallreq_for_div = `NoStop;
            div_opdata1_o = `ZeroWord;
            div_opdata2_o = `ZeroWord;
            div_start_o = `DivStop;
            signed_div_o = 1'b0;
        end
        else begin
            stallreq_for_div = `NoStop;
            div_opdata1_o = `ZeroWord;
            div_opdata2_o = `ZeroWord;
            div_start_o = `DivStop;
            signed_div_o = 1'b0;
            case ({inst_div,inst_divu})
                2'b10:begin
                    if (div_ready_i == `DivResultNotReady) begin
                        div_opdata1_o = rf_rdata1;
                        div_opdata2_o = rf_rdata2;
                        div_start_o = `DivStart;
                        signed_div_o = 1'b1;
                        stallreq_for_div = `Stop;
                    end
                    else if (div_ready_i == `DivResultReady) begin
                        div_opdata1_o = rf_rdata1;
                        div_opdata2_o = rf_rdata2;
                        div_start_o = `DivStop;
                        signed_div_o = 1'b1;
                        stallreq_for_div = `NoStop;
                    end
                    else begin
                        div_opdata1_o = `ZeroWord;
                        div_opdata2_o = `ZeroWord;
                        div_start_o = `DivStop;
                        signed_div_o = 1'b0;
                        stallreq_for_div = `NoStop;
                    end
                end
                2'b01:begin
                    if (div_ready_i == `DivResultNotReady) begin
                        div_opdata1_o = rf_rdata1;
                        div_opdata2_o = rf_rdata2;
                        div_start_o = `DivStart;
                        signed_div_o = 1'b0;
                        stallreq_for_div = `Stop;
                    end
                    else if (div_ready_i == `DivResultReady) begin
                        div_opdata1_o = rf_rdata1;
                        div_opdata2_o = rf_rdata2;
                        div_start_o = `DivStop;
                        signed_div_o = 1'b0;
                        stallreq_for_div = `NoStop;
                    end
                    else begin
                        div_opdata1_o = `ZeroWord;
                        div_opdata2_o = `ZeroWord;
                        div_start_o = `DivStop;
                        signed_div_o = 1'b0;
                        stallreq_for_div = `NoStop;
                    end
                end
                default:begin
                end
            endcase
        end
    end




    

    assign hilo_data =  (hilo_we & (inst[5:1]==5'b01101))? div_result:
                        (hilo_we & (inst[5:1]==5'b01100))? mul_result:
                        hilo_write[0]? {32'b0,rf_rdata1}:
                        hilo_write[1]? {rf_rdata1,32'b0} : 64'b0 ;

    hilo u_hilo(
    	.clk        (clk            ),//传入时钟周期
        .rst        (rst            ),//复位信号,负责初始化各项数据
        .we         (hilo_we        ),//是否写入hilo寄存器
        .hilo_data  (hilo_data      ),//写入hilo寄存器的地址
        .hi         (hi             ),//写入hi寄存器的数据
        .lo         (lo             ) //写入lo寄存器的数据
    ); 
    ///
    assign ex_result = data_sram_en ?data_sram_wdata: hilo_read[1]?hi: hilo_read[0]?lo:alu_result;

    assign ex_to_mem_bus = {
        new_lb_lw_lh,    //86:82
        ld_st_op,       // 81:76
        ex_pc,          // 75:44
        data_sram_en,    // 43
        data_sram_wen,   // 42:39
        sel_rf_res,     // 38
        rf_we,          // 37
        rf_waddr,       // 36:32
        ex_result       // 31:0
    };

    //Siri
    wire ex_to_rf_we;
    wire [4:0] ex_to_rf_waddr;
    wire [31:0] ex_to_rf_wdata;
    assign ex_to_rf_we =rf_we;
    assign ex_to_rf_waddr=rf_waddr;
    assign ex_to_rf_wdata=ex_result;
    assign ex_to_rf_bus={
        ld_st_op,
        ex_to_rf_we,
        ex_to_rf_waddr,
        ex_to_rf_wdata
    };
    //Siri
   
    
    
endmodule

MEM模块

`include "lib/defines.vh"
module MEM(
    input wire clk,//传入时钟周期
    input wire rst,//复位信号,负责初始化各项数据
    input wire [`StallBus-1:0] stall,//停止信号,负责暂停流水线
    input wire [`EX_TO_MEM_WD-1:0] ex_to_mem_bus,//EX段到MEM段的总线
    input wire [31:0] data_sram_rdata,//从内存读入的数据
    output wire [`MEM_TO_WB_WD-1:0] mem_to_wb_bus,//MEM段到WB段的总线
    output wire [`MEM_TO_RF_BUS-1:0] mem_to_rf_bus//MEM段到ID段的总线
     // input wire flush,
);

    reg [`EX_TO_MEM_WD-1:0] ex_to_mem_bus_r;

    always @ (posedge clk) begin
        if (rst) begin
            ex_to_mem_bus_r <= `EX_TO_MEM_WD'b0;
        end
        // else if (flush) begin
        //     ex_to_mem_bus_r <= `EX_TO_MEM_WD'b0;
        // end
        else if (stall[3]==`Stop && stall[4]==`NoStop) begin
            ex_to_mem_bus_r <= `EX_TO_MEM_WD'b0;
        end
        else if (stall[3]==`NoStop) begin
            ex_to_mem_bus_r <= ex_to_mem_bus;
        end
        // else begin
        //     pass;
        // end
    end
                                                                        
    wire [31:0] mem_pc;
    wire data_ram_en;
    wire [3:0] data_ram_wen;
    wire sel_rf_res;
    wire rf_we;
    wire [4:0] rf_waddr;
    wire [31:0] rf_wdata;
    wire [31:0] ex_result;
    wire [31:0] mem_result;
    wire [5:0] ld_st_op;
    wire[4:0]new_lb_lw_lh;
    assign {
        new_lb_lw_lh,
        ld_st_op,       // 81:76
        mem_pc,         // 75:44                                                                                                                                              
        data_ram_en,    // 43
        data_ram_wen,   // 42:39
        sel_rf_res,     // 38
        rf_we,          // 37
        rf_waddr,       // 36:32
        ex_result       // 31:0
    } =  ex_to_mem_bus_r;

    //load store 相关
    wire mem_inst_lw;
    assign mem_inst_lw=(ld_st_op==6'b10_0011);
    // wire mem_inst_sw;
    // assign mem_inst_sw=(ld_st_op==6'b10_1011);
    wire mem_inst_lb;
    assign mem_inst_lb=(ld_st_op==6'b100000)|(ld_st_op==6'b100100);
    wire mem_inst_lh;
    assign mem_inst_lh=(ld_st_op==6'b100001)|(ld_st_op==6'b100101);
    

    assign mem_result=mem_inst_lw?data_sram_rdata: 
                      (mem_inst_lb&(new_lb_lw_lh==5'b1_1000))?{{24{data_sram_rdata[7]}},data_sram_rdata[7:0]}:
                      (mem_inst_lb&(new_lb_lw_lh==5'b1_0100))?{{24{data_sram_rdata[15]}},data_sram_rdata[15:8]}:
                      (mem_inst_lb&(new_lb_lw_lh==5'b1_0010))?{{24{data_sram_rdata[23]}},data_sram_rdata[23:16]}:
                      (mem_inst_lb&(new_lb_lw_lh==5'b1_0001))?{{24{data_sram_rdata[31]}},data_sram_rdata[31:24]}:
                      (mem_inst_lh&(new_lb_lw_lh==5'b1_1100))?{{16{data_sram_rdata[15]}},data_sram_rdata[15:0]}:
                      (mem_inst_lh&(new_lb_lw_lh==5'b1_0011))?{{16{data_sram_rdata[31]}},data_sram_rdata[31:16]}:
                      (mem_inst_lb&(new_lb_lw_lh==5'b0_1000))?{24'b0,data_sram_rdata[7:0]}:
                      (mem_inst_lb&(new_lb_lw_lh==5'b0_0100))?{24'b0,data_sram_rdata[15:8]}:
                      (mem_inst_lb&(new_lb_lw_lh==5'b0_0010))?{24'b0,data_sram_rdata[23:16]}:
                      (mem_inst_lb&(new_lb_lw_lh==5'b0_0001))?{24'b0,data_sram_rdata[31:24]}:
                      (mem_inst_lh&(new_lb_lw_lh==5'b0_1100))?{16'b0,data_sram_rdata[15:0]}:
                      (mem_inst_lh&(new_lb_lw_lh==5'b0_0011))?{16'b0,data_sram_rdata[31:16]}:32'b0;


    assign rf_wdata = sel_rf_res ? mem_result : ex_result;

    assign mem_to_wb_bus = {
        mem_pc,     // 41:38
        rf_we,      // 37
        rf_waddr,   // 36:32
        rf_wdata    // 31:0
    };
    
    
    //Siri
    wire mem_to_rf_we;
    wire [4:0] mem_to_rf_waddr;
    wire [31:0] mem_to_rf_wdata;
    assign mem_to_rf_we =rf_we;
    assign mem_to_rf_waddr=rf_waddr;
    assign mem_to_rf_wdata=rf_wdata;
    assign mem_to_rf_bus={
        mem_to_rf_we,
        mem_to_rf_waddr,
        mem_to_rf_wdata
    };
    //Siri



endmodule

WB模块

`include "lib/defines.vh"
module WB(
    input wire clk,//传入时钟周期
    input wire rst,//复位信号,负责初始化各项数据
    input wire [`StallBus-1:0] stall,//停止信号,负责暂停流水线
    input wire [`MEM_TO_WB_WD-1:0] mem_to_wb_bus,//MEM段到WB段的总线
    output wire [`WB_TO_RF_WD-1:0] wb_to_rf_bus,//WB段到ID段的总线
    //debug用来判断程序是否正确运行
    output wire [31:0] debug_wb_pc, // 当前的指令
    output wire [3:0] debug_wb_rf_wen,//当前的写入使能
    output wire [4:0] debug_wb_rf_wnum,//当前的写入地址
    output wire [31:0] debug_wb_rf_wdata //当前的写入数据
    // input wire flush,
);

    reg [`MEM_TO_WB_WD-1:0] mem_to_wb_bus_r;

    always @ (posedge clk) begin
        if (rst) begin
            mem_to_wb_bus_r <= `MEM_TO_WB_WD'b0;
        end
        // else if (flush) begin
        //     mem_to_wb_bus_r <= `MEM_TO_WB_WD'b0;
        // end
        else if (stall[4]==`Stop && stall[5]==`NoStop) begin
            mem_to_wb_bus_r <= `MEM_TO_WB_WD'b0;
        end
        else if (stall[4]==`NoStop) begin
            mem_to_wb_bus_r <= mem_to_wb_bus;
        end
    end

    wire [31:0] wb_pc;
    wire rf_we;
    wire [4:0] rf_waddr;
    wire [31:0] rf_wdata;

    assign {
        wb_pc,
        rf_we,
        rf_waddr,
        rf_wdata
    } = mem_to_wb_bus_r;

    // assign wb_to_rf_bus = mem_to_wb_bus_r[`WB_TO_RF_WD-1:0];

    assign wb_to_rf_bus = {
        rf_we,
        rf_waddr,
        rf_wdata
    };

    assign debug_wb_pc = wb_pc;
    assign debug_wb_rf_wen = {4{rf_we}};
    assign debug_wb_rf_wnum = rf_waddr;
    assign debug_wb_rf_wdata = rf_wdata;

    
endmodule

 regfile模块

`include "defines.vh"
module regfile(
    input wire clk,


    //读端口1
    input wire [4:0] raddr1,
    output wire [31:0] rdata1,

    //读端口2
    input wire [4:0] raddr2,
    output wire [31:0] rdata2,
    
    //写端口
    input wire we,
    input wire [4:0] waddr,
    input wire [31:0] wdata
);
    reg [31:0] reg_array [31:0];
    // write
    always @ (posedge clk) begin
        if (we && waddr!=5'b0) begin //也就是we不为000000,waddr不为000000时。
            reg_array[waddr] <= wdata;
        end
    end
    
    // read out 1
    assign rdata1 = (raddr1 == 5'b0) ? 32'b0 : (raddr1==waddr)&&(we==1'b1)? wdata :reg_array[raddr1];

    // read out2
    assign rdata2 = (raddr2 == 5'b0) ? 32'b0 : (raddr2==waddr)&&(we==1'b1)? wdata :reg_array[raddr2];

endmodule

mul.v模块

`include "..\defines.vh"
module mul (
    input wire clk,
    input wire resetn,
    input wire mul_signed, //signed is 1, unsigned is 0
    input wire [31:0] ina,
    input wire [31:0] inb,
    input wire start_i,
    output reg signed [63:0] result,
    output reg ready_o

);
`define Signed 1'b1
`define UnSigned 1'b0

reg [63:0] my_result;
reg [63:0] add_;
reg [31:0] ex_ina;
reg [31:0] ex_inb;
reg reverse;

  reg [62 :0] temp0;
  reg [61 :0] temp1;
  reg [60 :0] temp2;
  reg [59 :0] temp3;
  reg [58 :0] temp4;
  reg [57 :0] temp5;
  reg [56 :0] temp6;
  reg [55 :0] temp7;
  reg [54 :0] temp8;
  reg [53 :0] temp9;
  reg [52 :0] temp10;
  reg [51 :0] temp11;
  reg [50 :0] temp12;
  reg [49 :0] temp13;
  reg [48 :0] temp14;
  reg [47 :0] temp15;
  reg [46 :0] temp16;
  reg [45 :0] temp17;
  reg [44 :0] temp18;
  reg [43 :0] temp19;
  reg [42 :0] temp20;
  reg [41 :0] temp21;
  reg [40 :0] temp22;
  reg [39 :0] temp23;
  reg [38 :0] temp24;
  reg [37 :0] temp25;
  reg [36 :0] temp26;
  reg [35 :0] temp27;
  reg [34 :0] temp28;
  reg [33 :0] temp29;
  reg [32 :0] temp30;
  reg [31 :0] temp31;

  reg [63:0] out1_0;//
  reg [61:0] out1_1;
  reg [59:0] out1_2;
  reg [57:0] out1_3;
  reg [55:0] out1_4;
  reg [53:0] out1_5;
  reg [51:0] out1_6;
  reg [49:0] out1_7;
  reg [47:0] out1_8;
  reg [45:0] out1_9;
  reg [43:0] out1_10;
  reg [41:0] out1_11;
  reg [39:0] out1_12;
  reg [37:0] out1_13;
  reg [35:0] out1_14;
  reg [33:0] out1_15;

  reg [63:0] out2_0;
	reg [59:0] out2_1;
	reg [55:0] out2_2;
	reg [51:0] out2_3;
	reg [47:0] out2_4;
	reg [43:0] out2_5;
	reg [39:0] out2_6;
	reg [35:0] out2_7;

  reg [63:0] out3_0;
	reg [55:0] out3_1;
	reg [47:0] out3_2;
	reg [39:0] out3_3;

  reg [63:0] out4_0;
	reg [47:0] out4_1;

    reg [63:0]final_result;

  reg [2:0] count; 
    
  // 32*1乘法器

  function [31:0] mut32_1;
  input [31:0] operand;
  input sel;

  begin
    mut32_1 = sel ? operand : 32'b0;
  end
  endfunction

  always @ (posedge clk) begin
    if (!resetn) begin
      count<=3'b0;
      ready_o <= `DivResultNotReady;
      temp0<=63'b0;
      temp1<=62'b0;
      temp2<=61'b0;
      temp3<=60'b0;
      temp4<=59'b0;
      temp5<=58'b0;
      temp6<=57'b0;
      temp7<=56'b0;
      temp8<=55'b0;
      temp9<=54'b0;
      temp10<=53'b0;
      temp11<=52'b0;
      temp12<=51'b0;
      temp13<=50'b0;
      temp14<=49'b0;
      temp15<=48'b0;
      temp16<=47'b0;
      temp17<=46'b0;
      temp18<=45'b0;
      temp19<=44'b0;
      temp20<=43'b0;
      temp21<=42'b0;
      temp22<=41'b0;
      temp23<=40'b0;
      temp24<=39'b0;
      temp25<=38'b0;
      temp26<=37'b0;
      temp27<=36'b0;
      temp28<=35'b0;
      temp29<=34'b0;
      temp30<=33'b0;
      temp31<=32'b0;

    end
    else begin
        case (count)
            3'd0:begin
                if(start_i==1'b1)begin
                    if (mul_signed==`UnSigned) begin
                        ex_ina<=ina;
                        ex_inb<=inb;
                        reverse<=1'b0;
                    end else begin
                        ex_ina<=ina;
                        ex_inb<=inb;
                        if(ina[31]==1'b1) begin
                        ex_ina<=~(ina-1);
                        end
                        if (inb[31]==1'b1) begin
                        ex_inb<=~(inb-1);
                        end
                        reverse<=ina[31]+inb[31];
                    end
                    count<=3'd1;
                    
                end
                else begin
                  ready_o <= `DivResultNotReady;
                  result <= 64'b0;
                end
            end
            3'd1:begin
                temp31<=mut32_1(ex_ina,ex_inb[0]);
                temp30<=mut32_1(ex_ina,ex_inb[1])<<1;
                temp29<=mut32_1(ex_ina,ex_inb[2])<<2;
                temp28<=mut32_1(ex_ina,ex_inb[3])<<3;
                temp27<=mut32_1(ex_ina,ex_inb[4])<<4;
                temp26<=mut32_1(ex_ina,ex_inb[5])<<5;
                temp25<=mut32_1(ex_ina,ex_inb[6])<<6;
                temp24<=mut32_1(ex_ina,ex_inb[7])<<7;
                temp23<=mut32_1(ex_ina,ex_inb[8])<<8;
                temp22<=mut32_1(ex_ina,ex_inb[9])<<9;
                temp21<=mut32_1(ex_ina,ex_inb[10])<<10;
                temp20<=mut32_1(ex_ina,ex_inb[11])<<11;
                temp19<=mut32_1(ex_ina,ex_inb[12])<<12;
                temp18<=mut32_1(ex_ina,ex_inb[13])<<13;
                temp17<=mut32_1(ex_ina,ex_inb[14])<<14;
                temp16<=mut32_1(ex_ina,ex_inb[15])<<15;
                temp15<=mut32_1(ex_ina,ex_inb[16])<<16;
                temp14<=mut32_1(ex_ina,ex_inb[17])<<17;
                temp13<=mut32_1(ex_ina,ex_inb[18])<<18;
                temp12<=mut32_1(ex_ina,ex_inb[19])<<19;
                temp11<=mut32_1(ex_ina,ex_inb[20])<<20;
                temp10<=mut32_1(ex_ina,ex_inb[21])<<21;
                temp9<=mut32_1(ex_ina,ex_inb[22])<<22;
                temp8<=mut32_1(ex_ina,ex_inb[23])<<23;
                temp7<=mut32_1(ex_ina,ex_inb[24])<<24;
                temp6<=mut32_1(ex_ina,ex_inb[25])<<25;
                temp5<=mut32_1(ex_ina,ex_inb[26])<<26;
                temp4<=mut32_1(ex_ina,ex_inb[27])<<27;
                temp3<=mut32_1(ex_ina,ex_inb[28])<<28;
                temp2<=mut32_1(ex_ina,ex_inb[29])<<29;
                temp1<=mut32_1(ex_ina,ex_inb[30])<<30;
                temp0<=mut32_1(ex_ina,ex_inb[31])<<31;
                count<=3'd2;
                // ready_o<=1'b0;
            end
            3'd2:begin
                out1_0  <= temp0+temp1;
                out1_1  <= temp2+temp3;
                out1_2  <= temp4+temp5;
                out1_3  <= temp6+temp7;
                out1_4  <= temp8+temp9;
                out1_5  <= temp10+temp11;
                out1_6  <= temp12+temp13;
                out1_7  <= temp14+temp15;
                out1_8  <= temp16+temp17;
                out1_9  <= temp18+temp19;
                out1_10  <= temp20+temp21;
                out1_11  <= temp22+temp23;
                out1_12  <= temp24+temp25;
                out1_13  <= temp26+temp27;
                out1_14  <= temp28+temp29;
                out1_15  <= temp30+temp31;
                count<=3'd3;
                // ready_o<=1'b0;
            end
            3'd3:begin
                out2_0  <= out1_0+out1_1;
                out2_1  <= out1_2+out1_3;
                out2_2  <= out1_4+out1_5;
                out2_3  <= out1_6+out1_7;
                out2_4  <= out1_8+out1_9;
                out2_5  <= out1_10+out1_11;
                out2_6  <= out1_12+out1_13;
                out2_7  <= out1_14+out1_15;
                count<=3'd4;
                // ready_o<=1'b0;
            end
            3'd4:begin
                out3_0 <= out2_0+out2_1;
                out3_1 <= out2_2+out2_3;
                out3_2 <= out2_4+out2_5;
                out3_3 <= out2_6+out2_7;
                count <= 3'd5;
                // ready_o<=1'b0;
            end
            3'd5:begin
                out4_0 <= out3_0+out3_1;
	            out4_1 <= out3_2+out3_3;
                count<=3'd6;
                // ready_o<=1'b0;
            end
            3'd6:begin
                final_result<=out4_0+out4_1;
                count<=3'd7;
                // ready_o<=1'b0;
            end
            3'd7:begin
                result<=reverse?~(final_result)+1'b1:final_result;
                // count<=3'd0;
                ready_o <= `DivResultReady;

                if (start_i == `DivStop) begin
                    count <= 3'b0;
                    ready_o <= `DivResultNotReady;
                    result <= {`ZeroWord,`ZeroWord};
                end

            end
        endcase 
    end        
end
endmodule

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程思睿Siri

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值