data/full_repos/permissive/433389019/EX.v
1: b'%Error: data/full_repos/permissive/433389019/EX.v:1: Cannot find include file: lib/defines.vh\n`include "lib/defines.vh" \n         ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/433389019,data/full_repos/permissive/433389019/lib/defines.vh\n             data/full_repos/permissive/433389019,data/full_repos/permissive/433389019/lib/defines.vh.v\n             data/full_repos/permissive/433389019,data/full_repos/permissive/433389019/lib/defines.vh.sv\n             lib/defines.vh\n             lib/defines.vh.v\n             lib/defines.vh.sv\n             obj_dir/lib/defines.vh\n             obj_dir/lib/defines.vh.v\n             obj_dir/lib/defines.vh.sv\n%Error: data/full_repos/permissive/433389019/EX.v:6: Define or directive not defined: \'`StallBus\'\n    input wire [`StallBus-1:0] stall,\n                ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:8: Define or directive not defined: \'`ID_TO_EX_WD\'\n    input wire [`ID_TO_EX_WD-1:0] id_to_ex_bus,\n                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:9: Define or directive not defined: \'`EX_TO_MEM_WD\'\n    output wire [`EX_TO_MEM_WD-1:0] ex_to_mem_bus,\n                 ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:14: Define or directive not defined: \'`EX_TO_ID_WD\'\n    output wire [`EX_TO_ID_WD-1:0] ex_to_id_bus,\n                 ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:22: Define or directive not defined: \'`ID_TO_EX_WD\'\n    reg [`ID_TO_EX_WD-1:0] id_to_ex_bus_r;\n         ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:26: Define or directive not defined: \'`ID_TO_EX_WD\'\n            id_to_ex_bus_r <= `ID_TO_EX_WD\'b0;\n                              ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:31: Define or directive not defined: \'`Stop\'\n        else if (stall[2]==`Stop && stall[3]==`NoStop) begin\n                           ^~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:31: syntax error, unexpected &&, expecting TYPE-IDENTIFIER\n        else if (stall[2]==`Stop && stall[3]==`NoStop) begin\n                                 ^~\n%Error: data/full_repos/permissive/433389019/EX.v:31: Define or directive not defined: \'`NoStop\'\n        else if (stall[2]==`Stop && stall[3]==`NoStop) begin\n                                              ^~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:32: Define or directive not defined: \'`ID_TO_EX_WD\'\n            id_to_ex_bus_r <= `ID_TO_EX_WD\'b0;\n                              ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:34: Define or directive not defined: \'`NoStop\'\n        else if (stall[2]==`NoStop) begin\n                           ^~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:206: Define or directive not defined: \'`NoStop\'\n            stallreq_for_mul = `NoStop;\n                               ^~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:206: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            stallreq_for_mul = `NoStop;\n                                      ^\n%Error: data/full_repos/permissive/433389019/EX.v:207: Define or directive not defined: \'`ZeroWord\'\n            mul_opdata1_o = `ZeroWord;\n                            ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:207: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            mul_opdata1_o = `ZeroWord;\n                                     ^\n%Error: data/full_repos/permissive/433389019/EX.v:208: Define or directive not defined: \'`ZeroWord\'\n            mul_opdata2_o = `ZeroWord;\n                            ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:208: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            mul_opdata2_o = `ZeroWord;\n                                     ^\n%Error: data/full_repos/permissive/433389019/EX.v:209: Define or directive not defined: \'`MulStop\'\n            mul_start_o = `MulStop;\n                          ^~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:209: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            mul_start_o = `MulStop;\n                                  ^\n%Error: data/full_repos/permissive/433389019/EX.v:213: Define or directive not defined: \'`NoStop\'\n            stallreq_for_mul = `NoStop;\n                               ^~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:213: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            stallreq_for_mul = `NoStop;\n                                      ^\n%Error: data/full_repos/permissive/433389019/EX.v:214: Define or directive not defined: \'`ZeroWord\'\n            mul_opdata1_o = `ZeroWord;\n                            ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:214: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            mul_opdata1_o = `ZeroWord;\n                                     ^\n%Error: data/full_repos/permissive/433389019/EX.v:215: Define or directive not defined: \'`ZeroWord\'\n            mul_opdata2_o = `ZeroWord;\n                            ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:215: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            mul_opdata2_o = `ZeroWord;\n                                     ^\n%Error: data/full_repos/permissive/433389019/EX.v:216: Define or directive not defined: \'`MulStop\'\n            mul_start_o = `MulStop;\n                          ^~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:216: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            mul_start_o = `MulStop;\n                                  ^\n%Error: data/full_repos/permissive/433389019/EX.v:220: Define or directive not defined: \'`MulResultNotReady\'\n                    if (mul_ready_i == `MulResultNotReady) begin\n                                       ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:220: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n                    if (mul_ready_i == `MulResultNotReady) begin\n                                                         ^\n%Error: data/full_repos/permissive/433389019/EX.v:223: Define or directive not defined: \'`MulStart\'\n                        mul_start_o = `MulStart;\n                                      ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:223: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n                        mul_start_o = `MulStart;\n                                               ^\n%Error: data/full_repos/permissive/433389019/EX.v:225: Define or directive not defined: \'`Stop\'\n                        stallreq_for_mul = `Stop;\n                                           ^~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:225: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n                        stallreq_for_mul = `Stop;\n                                                ^\n%Error: data/full_repos/permissive/433389019/EX.v:227: Define or directive not defined: \'`MulResultReady\'\n                    else if (mul_ready_i == `MulResultReady) begin\n                                            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:230: Define or directive not defined: \'`MulStop\'\n                        mul_start_o = `MulStop;\n                                      ^~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:230: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n                        mul_start_o = `MulStop;\n                                              ^\n%Error: data/full_repos/permissive/433389019/EX.v:232: Define or directive not defined: \'`NoStop\'\n                        stallreq_for_mul = `NoStop;\n                                           ^~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:232: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n                        stallreq_for_mul = `NoStop;\n                                                  ^\n%Error: data/full_repos/permissive/433389019/EX.v:235: Define or directive not defined: \'`ZeroWord\'\n                        mul_opdata1_o = `ZeroWord;\n                                        ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:236: Define or directive not defined: \'`ZeroWord\'\n                        mul_opdata2_o = `ZeroWord;\n                                        ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:236: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n                        mul_opdata2_o = `ZeroWord;\n                                                 ^\n%Error: data/full_repos/permissive/433389019/EX.v:237: Define or directive not defined: \'`MulStop\'\n                        mul_start_o = `MulStop;\n                                      ^~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:237: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n                        mul_start_o = `MulStop;\n                                              ^\n%Error: data/full_repos/permissive/433389019/EX.v:239: Define or directive not defined: \'`NoStop\'\n                        stallreq_for_mul = `NoStop;\n                                           ^~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:239: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n                        stallreq_for_mul = `NoStop;\n                                                  ^\n%Error: data/full_repos/permissive/433389019/EX.v:243: Define or directive not defined: \'`MulResultNotReady\'\n                    if (mul_ready_i == `MulResultNotReady) begin\n                                       ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:246: Define or directive not defined: \'`MulStart\'\n                        mul_start_o = `MulStart;\n                                      ^~~~~~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:248: Define or directive not defined: \'`Stop\'\n                        stallreq_for_mul = `Stop;\n                                           ^~~~~\n%Error: data/full_repos/permissive/433389019/EX.v:250: Define or directive not defined: \'`MulResultReady\'\n                    else if (mul_ready_i == `MulResultReady) begin\n                                            ^~~~~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
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,
    output wire [`EX_TO_MEM_WD-1:0] ex_to_mem_bus,
    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_ID_WD-1:0] ex_to_id_bus,
    output wire stallreq_for_ex,
    output wire div_ready_to_id,

    output wire pre_inst_data_sram_en,
    output wire [3:0] pre_inst_data_sram_wen
);

    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 (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 [3:0] data_ram_readen;
    wire rf_we;
    wire [4:0] rf_waddr;
    wire sel_rf_res;
    wire [31:0] rf_rdata1, rf_rdata2;
    reg is_in_delayslot;

    wire [31:0] hi_out_file;         
    wire [31:0] lo_out_file;       
    wire hi_read; 
    wire lo_read; 
    wire hi_write;
    wire lo_write;
    wire w_lo_we;
    wire w_hi_we;
    wire [31:0] w_lo_i;
    wire [31:0] w_hi_i;
    wire is_lsa;

    assign {
        is_lsa,
        data_ram_readen,
        hi_read,
        lo_read,
        hi_write,
        lo_write,
        hi_out_file,
        lo_out_file,
        ex_pc,
        inst,
        alu_op,
        sel_alu_src1,
        sel_alu_src2,
        data_ram_en,
        data_ram_wen,
        rf_we,
        rf_waddr,
        sel_rf_res,
        rf_rdata1,
        rf_rdata2
    } = id_to_ex_bus_r;

    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;

    assign alu_src1 = sel_alu_src1[1] ? ex_pc :
                      sel_alu_src1[2] ? sa_zero_extend : rf_rdata1;

    assign alu_src2 = sel_alu_src2[1] ? imm_sign_extend :
                      sel_alu_src2[2] ? 32'd8 :
                      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  )
    );

    assign ex_result =  (hi_read) ?  hi_out_file :
                        (lo_read) ?  lo_out_file : alu_result;



    assign data_sram_en = data_ram_en;
    assign data_sram_wen =   (data_ram_readen==4'b0101 && ex_result[1:0] == 2'b00 )? 4'b0001 
                            :(data_ram_readen==4'b0101 && ex_result[1:0] == 2'b01 )? 4'b0010
                            :(data_ram_readen==4'b0101 && ex_result[1:0] == 2'b10 )? 4'b0100
                            :(data_ram_readen==4'b0101 && ex_result[1:0] == 2'b11 )? 4'b1000
                            :(data_ram_readen==4'b0111 && ex_result[1:0] == 2'b00 )? 4'b0011
                            :(data_ram_readen==4'b0111 && ex_result[1:0] == 2'b10 )? 4'b1100
                            : data_ram_wen;
    assign data_sram_addr = ex_result;
    
    assign data_sram_wdata = data_sram_wen==4'b1111 ? rf_rdata2 
                            :data_sram_wen==4'b0001 ? {24'b0,rf_rdata2[7:0]}
                            :data_sram_wen==4'b0010 ? {16'b0,rf_rdata2[7:0],8'b0}
                            :data_sram_wen==4'b0100 ? {8'b0,rf_rdata2[7:0],16'b0}
                            :data_sram_wen==4'b1000 ? {rf_rdata2[7:0],24'b0}
                            :data_sram_wen==4'b0011 ? {16'b0,rf_rdata2[15:0]}
                            :data_sram_wen==4'b1100 ? {rf_rdata2[15:0],16'b0}
                            :32'b0;
    assign pre_inst_data_sram_en = data_ram_en;
    assign pre_inst_data_sram_wen = data_ram_wen; 
    

    wire [63:0] mul_result;
    wire inst_mult, inst_multu;
    wire mul_ready_i;



    reg stallreq_for_mul;
    assign inst_mult = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1000);
    assign inst_multu = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1001);




    reg [31:0] mul_opdata1_o;
    reg [31:0] mul_opdata2_o;
    reg mul_start_o;
    reg signed_mul_o;









    mul u_mul(
    	.rst          (rst          ),
        .clk          (clk          ),
        .signed_mul_i (signed_mul_o ),
        .opdata1_i    (mul_opdata1_o    ),
        .opdata2_i    (mul_opdata2_o    ),
        .start_i      (mul_start_o      ),
        .annul_i      (1'b0      ),
        .result_o     (mul_result     ),
        .ready_o      (mul_ready_i      )
    );
    

    wire [63:0] div_result;
    wire inst_div, inst_divu;
    wire div_ready_i;
    reg stallreq_for_div;
    assign stallreq_for_ex = (stallreq_for_div && (div_ready_i==1'b0)) || (stallreq_for_mul && (mul_ready_i==1'b0));

    assign div_ready_to_id = div_ready_i; 
    assign inst_div = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1010);
    assign inst_divu = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1011);

    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     ),
        .ready_o      (div_ready_i      )
    );

    always @ (*) begin
        if (rst) begin
            stallreq_for_mul = `NoStop;
            mul_opdata1_o = `ZeroWord;
            mul_opdata2_o = `ZeroWord;
            mul_start_o = `MulStop;
            signed_mul_o = 1'b0;
        end
        else begin
            stallreq_for_mul = `NoStop;
            mul_opdata1_o = `ZeroWord;
            mul_opdata2_o = `ZeroWord;
            mul_start_o = `MulStop;
            signed_mul_o = 1'b0;
            case ({inst_mult,inst_multu})
                2'b10:begin
                    if (mul_ready_i == `MulResultNotReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStart;
                        signed_mul_o = 1'b1;
                        stallreq_for_mul = `Stop;
                    end
                    else if (mul_ready_i == `MulResultReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b1;
                        stallreq_for_mul = `NoStop;
                    end
                    else begin
                        mul_opdata1_o = `ZeroWord;
                        mul_opdata2_o = `ZeroWord;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                end
                2'b01:begin
                    if (mul_ready_i == `MulResultNotReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStart;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `Stop;
                    end
                    else if (mul_ready_i == `MulResultReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                    else begin
                        mul_opdata1_o = `ZeroWord;
                        mul_opdata2_o = `ZeroWord;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                end
                default:begin
                end
            endcase
        end
    end

    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
    wire inst_mthi;
    wire inst_mtlo;
    assign inst_mthi    = (inst[31:26]==6'b00_0000)&(inst[20:6]==15'b00000_00000_00000)&(inst[5:0]==6'b01_0001);
    assign inst_mtlo    = (inst[31:26]==6'b00_0000)&(inst[20:6]==15'b00000_00000_00000)&(inst[5:0]==6'b01_0011);
    assign w_hi_we = inst_mult | inst_multu | inst_div | inst_divu | inst_mthi;
    assign w_lo_we = inst_mult | inst_multu | inst_div | inst_divu | inst_mtlo;
    assign w_hi_i = (inst_mult | inst_multu) ?  mul_result[63:32] :
                    (inst_div | inst_divu ) ? div_result[63:32] : 
                    (hi_write) ? rf_rdata1:32'b0;
    assign w_lo_i = (inst_mult | inst_multu) ?  mul_result[31:0] :
                    (inst_div | inst_divu ) ? div_result[31:0] :
                    (lo_write) ? rf_rdata1 : 32'b0;
    assign ex_to_mem_bus = {
        data_ram_readen,
        w_hi_we,
        w_hi_i,
        w_lo_we,
        w_lo_i,
        ex_pc,
        data_ram_en,
        data_ram_wen,
        sel_rf_res,
        rf_we,
        rf_waddr,
        ex_result
    };

    assign ex_to_id_bus = {
        w_hi_we,
        w_hi_i,
        w_lo_we,
        w_lo_i,
        rf_we,
        rf_waddr,
        ex_result
    };
endmodule
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,
    output wire [`EX_TO_MEM_WD-1:0] ex_to_mem_bus,
    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_ID_WD-1:0] ex_to_id_bus,
    output wire stallreq_for_ex,
    output wire div_ready_to_id,

    output wire pre_inst_data_sram_en,
    output wire [3:0] pre_inst_data_sram_wen
);


    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 (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 [3:0] data_ram_readen;
    wire rf_we;
    wire [4:0] rf_waddr;
    wire sel_rf_res;
    wire [31:0] rf_rdata1, rf_rdata2;
    reg is_in_delayslot;

    wire [31:0] hi_out_file;         
    wire [31:0] lo_out_file;       
    wire hi_read; 
    wire lo_read; 
    wire hi_write;
    wire lo_write;
    wire w_lo_we;
    wire w_hi_we;
    wire [31:0] w_lo_i;
    wire [31:0] w_hi_i;
    wire is_lsa;

    assign {
        is_lsa,
        data_ram_readen,
        hi_read,
        lo_read,
        hi_write,
        lo_write,
        hi_out_file,
        lo_out_file,
        ex_pc,
        inst,
        alu_op,
        sel_alu_src1,
        sel_alu_src2,
        data_ram_en,
        data_ram_wen,
        rf_we,
        rf_waddr,
        sel_rf_res,
        rf_rdata1,
        rf_rdata2
    } = id_to_ex_bus_r;

    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;

    assign alu_src1 = sel_alu_src1[1] ? ex_pc :
                      sel_alu_src1[2] ? sa_zero_extend : rf_rdata1;

    assign alu_src2 = sel_alu_src2[1] ? imm_sign_extend :
                      sel_alu_src2[2] ? 32'd8 :
                      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  )
    );

    assign ex_result =  (hi_read) ?  hi_out_file :
                        (lo_read) ?  lo_out_file : alu_result;



    assign data_sram_en = data_ram_en;
    assign data_sram_wen =   (data_ram_readen==4'b0101 && ex_result[1:0] == 2'b00 )? 4'b0001 
                            :(data_ram_readen==4'b0101 && ex_result[1:0] == 2'b01 )? 4'b0010
                            :(data_ram_readen==4'b0101 && ex_result[1:0] == 2'b10 )? 4'b0100
                            :(data_ram_readen==4'b0101 && ex_result[1:0] == 2'b11 )? 4'b1000
                            :(data_ram_readen==4'b0111 && ex_result[1:0] == 2'b00 )? 4'b0011
                            :(data_ram_readen==4'b0111 && ex_result[1:0] == 2'b10 )? 4'b1100
                            : data_ram_wen;
    assign data_sram_addr = ex_result;
    
    assign data_sram_wdata = data_sram_wen==4'b1111 ? rf_rdata2 
                            :data_sram_wen==4'b0001 ? {24'b0,rf_rdata2[7:0]}
                            :data_sram_wen==4'b0010 ? {16'b0,rf_rdata2[7:0],8'b0}
                            :data_sram_wen==4'b0100 ? {8'b0,rf_rdata2[7:0],16'b0}
                            :data_sram_wen==4'b1000 ? {rf_rdata2[7:0],24'b0}
                            :data_sram_wen==4'b0011 ? {16'b0,rf_rdata2[15:0]}
                            :data_sram_wen==4'b1100 ? {rf_rdata2[15:0],16'b0}
                            :32'b0;
    assign pre_inst_data_sram_en = data_ram_en;
    assign pre_inst_data_sram_wen = data_ram_wen; 
    

    wire [63:0] mul_result;
    wire inst_mult, inst_multu;
    wire mul_ready_i;



    reg stallreq_for_mul;
    assign inst_mult = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1000);
    assign inst_multu = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1001);




    reg [31:0] mul_opdata1_o;
    reg [31:0] mul_opdata2_o;
    reg mul_start_o;
    reg signed_mul_o;









    mul u_mul(
    	.rst          (rst          ),
        .clk          (clk          ),
        .signed_mul_i (signed_mul_o ),
        .opdata1_i    (mul_opdata1_o    ),
        .opdata2_i    (mul_opdata2_o    ),
        .start_i      (mul_start_o      ),
        .annul_i      (1'b0      ),
        .result_o     (mul_result     ),
        .ready_o      (mul_ready_i      )
    );
    

    wire [63:0] div_result;
    wire inst_div, inst_divu;
    wire div_ready_i;
    reg stallreq_for_div;
    assign stallreq_for_ex = (stallreq_for_div && (div_ready_i==1'b0)) || (stallreq_for_mul && (mul_ready_i==1'b0));

    assign div_ready_to_id = div_ready_i; 
    assign inst_div = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1010);
    assign inst_divu = (inst[31:26] == 6'b00_0000) & (inst[15:6] == 10'b00000_00000) & (inst[5:0] == 6'b01_1011);

    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     ),
        .ready_o      (div_ready_i      )
    );

    always @ (*) begin
        if (rst) begin
            stallreq_for_mul = `NoStop;
            mul_opdata1_o = `ZeroWord;
            mul_opdata2_o = `ZeroWord;
            mul_start_o = `MulStop;
            signed_mul_o = 1'b0;
        end
        else begin
            stallreq_for_mul = `NoStop;
            mul_opdata1_o = `ZeroWord;
            mul_opdata2_o = `ZeroWord;
            mul_start_o = `MulStop;
            signed_mul_o = 1'b0;
            case ({inst_mult,inst_multu})
                2'b10:begin
                    if (mul_ready_i == `MulResultNotReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStart;
                        signed_mul_o = 1'b1;
                        stallreq_for_mul = `Stop;
                    end
                    else if (mul_ready_i == `MulResultReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b1;
                        stallreq_for_mul = `NoStop;
                    end
                    else begin
                        mul_opdata1_o = `ZeroWord;
                        mul_opdata2_o = `ZeroWord;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                end
                2'b01:begin
                    if (mul_ready_i == `MulResultNotReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStart;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `Stop;
                    end
                    else if (mul_ready_i == `MulResultReady) begin
                        mul_opdata1_o = rf_rdata1;
                        mul_opdata2_o = rf_rdata2;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                    else begin
                        mul_opdata1_o = `ZeroWord;
                        mul_opdata2_o = `ZeroWord;
                        mul_start_o = `MulStop;
                        signed_mul_o = 1'b0;
                        stallreq_for_mul = `NoStop;
                    end
                end
                default:begin
                end
            endcase
        end
    end

    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
    wire inst_mthi;
    wire inst_mtlo;
    assign inst_mthi    = (inst[31:26]==6'b00_0000)&(inst[20:6]==15'b00000_00000_00000)&(inst[5:0]==6'b01_0001);
    assign inst_mtlo    = (inst[31:26]==6'b00_0000)&(inst[20:6]==15'b00000_00000_00000)&(inst[5:0]==6'b01_0011);
    assign w_hi_we = inst_mult | inst_multu | inst_div | inst_divu | inst_mthi;
    assign w_lo_we = inst_mult | inst_multu | inst_div | inst_divu | inst_mtlo;
    assign w_hi_i = (inst_mult | inst_multu) ?  mul_result[63:32] :
                    (inst_div | inst_divu ) ? div_result[63:32] : 
                    (hi_write) ? rf_rdata1:32'b0;
    assign w_lo_i = (inst_mult | inst_multu) ?  mul_result[31:0] :
                    (inst_div | inst_divu ) ? div_result[31:0] :
                    (lo_write) ? rf_rdata1 : 32'b0;
    assign ex_to_mem_bus = {
        data_ram_readen,
        w_hi_we,
        w_hi_i,
        w_lo_we,
        w_lo_i,
        ex_pc,
        data_ram_en,
        data_ram_wen,
        sel_rf_res,
        rf_we,
        rf_waddr,
        ex_result
    };

    assign ex_to_id_bus = {
        w_hi_we,
        w_hi_i,
        w_lo_we,
        w_lo_i,
        rf_we,
        rf_waddr,
        ex_result
    };
endmodule