data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v
1: b'%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:1: Cannot find include file: common.vh\n`include "common.vh" \n         ^~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core,data/full_repos/permissive/200650987/common.vh\n             data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core,data/full_repos/permissive/200650987/common.vh.v\n             data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core,data/full_repos/permissive/200650987/common.vh.sv\n             common.vh\n             common.vh.v\n             common.vh.sv\n             obj_dir/common.vh\n             obj_dir/common.vh.v\n             obj_dir/common.vh.sv\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:71: Define or directive not defined: \'`I_MAX\'\n    output reg [`I_MAX-1:0]     ctrl_o,\n                ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:131: Define or directive not defined: \'`I_MAX\'\n    wire [`I_MAX-1:0] ctrl_sig;\n          ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:138: Define or directive not defined: \'`STATUS_CU0\'\n    wire cp0_avail = status[`STATUS_CU0] || !status[`STATUS_UM] || status[`STATUS_EXL];\n                            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:138: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    wire cp0_avail = status[`STATUS_CU0] || !status[`STATUS_UM] || status[`STATUS_EXL];\n                                       ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:138: Define or directive not defined: \'`STATUS_UM\'\n    wire cp0_avail = status[`STATUS_CU0] || !status[`STATUS_UM] || status[`STATUS_EXL];\n                                                    ^~~~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:138: Define or directive not defined: \'`STATUS_EXL\'\n    wire cp0_avail = status[`STATUS_CU0] || !status[`STATUS_UM] || status[`STATUS_EXL];\n                                                                          ^~~~~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:154: Define or directive not defined: \'`I_MEM_R\'\n    wire inst_rt_wwb              = ctrl_sig[`I_MEM_R];\n                                             ^~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:154: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    wire inst_rt_wwb              = ctrl_sig[`I_MEM_R];\n                                                     ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:161: Define or directive not defined: \'`I_LB\'\n    assign ctrl_sig[`I_LB]        = op_lb;\n                    ^~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:161: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_LB]        = op_lb;\n                         ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:162: Define or directive not defined: \'`I_LH\'\n    assign ctrl_sig[`I_LH]        = op_lh;\n                    ^~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:162: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_LH]        = op_lh;\n                         ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:163: Define or directive not defined: \'`I_LWL\'\n    assign ctrl_sig[`I_LWL]       = op_lwl;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:163: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_LWL]       = op_lwl;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:164: Define or directive not defined: \'`I_LW\'\n    assign ctrl_sig[`I_LW]        = op_lw;\n                    ^~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:164: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_LW]        = op_lw;\n                         ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:165: Define or directive not defined: \'`I_LBU\'\n    assign ctrl_sig[`I_LBU]       = op_lbu;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:165: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_LBU]       = op_lbu;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:166: Define or directive not defined: \'`I_LHU\'\n    assign ctrl_sig[`I_LHU]       = op_lhu;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:166: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_LHU]       = op_lhu;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:167: Define or directive not defined: \'`I_LWR\'\n    assign ctrl_sig[`I_LWR]       = op_lwr;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:167: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_LWR]       = op_lwr;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:168: Define or directive not defined: \'`I_SB\'\n    assign ctrl_sig[`I_SB]        = op_sb;\n                    ^~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:168: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_SB]        = op_sb;\n                         ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:169: Define or directive not defined: \'`I_SH\'\n    assign ctrl_sig[`I_SH]        = op_sh;\n                    ^~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:169: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_SH]        = op_sh;\n                         ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:170: Define or directive not defined: \'`I_SWL\'\n    assign ctrl_sig[`I_SWL]       = op_swl;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:170: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_SWL]       = op_swl;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:171: Define or directive not defined: \'`I_SW\'\n    assign ctrl_sig[`I_SW]        = op_sw;\n                    ^~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:171: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_SW]        = op_sw;\n                         ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:172: Define or directive not defined: \'`I_SWR\'\n    assign ctrl_sig[`I_SWR]       = op_swr;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:172: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_SWR]       = op_swr;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:175: Define or directive not defined: \'`I_MEM_R\'\n    assign ctrl_sig[`I_MEM_R]     = op_lb||op_lh||op_lwl||op_lw||op_lbu||op_lhu||op_lwr||op_ll;\n                    ^~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:175: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_MEM_R]     = op_lb||op_lh||op_lwl||op_lw||op_lbu||op_lhu||op_lwr||op_ll;\n                            ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:177: Define or directive not defined: \'`I_MEM_W\'\n    assign ctrl_sig[`I_MEM_W]     = op_sb||op_sh||op_swl||op_sw||op_swr||op_sc&&llbit;\n                    ^~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:177: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_MEM_W]     = op_sb||op_sh||op_swl||op_sw||op_swr||op_sc&&llbit;\n                            ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:179: Define or directive not defined: \'`I_WEX\'\n    assign ctrl_sig[`I_WEX]       = inst_rt_wex||inst_rd_wex||inst_r31_wex;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:179: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_WEX]       = inst_rt_wex||inst_rd_wex||inst_r31_wex;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:181: Define or directive not defined: \'`I_WWB\'\n    assign ctrl_sig[`I_WWB]       = inst_rt_wwb;\n                    ^~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:181: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign ctrl_sig[`I_WWB]       = inst_rt_wwb;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:187: Define or directive not defined: \'`I_MEM_R\'\n    wire alu_b_imm  = op_addi||op_addiu||op_slti||op_sltiu||op_andi||op_ori||op_xori||ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W];\n                                                                                               ^~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:187: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    wire alu_b_imm  = op_addi||op_addiu||op_slti||op_sltiu||op_andi||op_ori||op_xori||ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W];\n                                                                                                       ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:187: Define or directive not defined: \'`I_MEM_W\'\n    wire alu_b_imm  = op_addi||op_addiu||op_slti||op_sltiu||op_andi||op_ori||op_xori||ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W];\n                                                                                                                   ^~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:200: Define or directive not defined: \'`GET_RT\'\n    wire [4:0] waddr = {5{inst_rt_wex||inst_rt_wwb}}    & `GET_RT(inst_i)\n                                                          ^~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:201: Define or directive not defined: \'`GET_RD\'\n                     | {5{inst_rd_wex}}                 & `GET_RD(inst_i)\n                                                          ^~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:205: Define or directive not defined: \'`GET_IMM\'\n    wire [15:0] imm = `GET_IMM(inst_i);\n                      ^~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:212: Define or directive not defined: \'`ALU_ADD\'\n    assign alu_op[`ALU_ADD]   = op_add||op_addu||op_addi||op_addiu;\n                  ^~~~~~~~\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:212: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    assign alu_op[`ALU_ADD]   = op_add||op_addu||op_addi||op_addiu;\n                          ^\n%Error: data/full_repos/permissive/200650987/src/verilog/outdated/nscscc-mips-cpu/rtl/myCPU/core/execute_stage.v:213: Define or directive not defined: \'`ALU_SUB\'\n    assign alu_op[`ALU_SUB]   = op_sub||op_subu;\n                  ^~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module execute_stage(
    input                       clk,
    input                       resetn,


    output                      data_req,
    output                      data_cache,
    output                      data_wr,
    output  [3 :0]              data_wstrb,
    output  [31:0]              data_addr,
    output  [2 :0]              data_size,
    output  [31:0]              data_wdata,
    input                       data_addr_ok,
    

    output                      branch,
    input                       branch_ready,
    output  [31:0]              target_pc,
    

    output  [31:0]              tlb_vaddr,
    input   [31:0]              tlb_paddr,
    input                       tlb_miss,
    input                       tlb_invalid,
    input                       tlb_dirty,
    input   [2 :0]              tlb_cattr,
    
    input   [31:0]              status,
    input   [2: 0]              config_k0,
    

    input                       int_sig,
    

    output  [4 :0]              fwd_addr,
    output  [31:0]              fwd_data,
    output                      fwd_ok,
    

    output                      cp0_w,
    output  [31:0]              cp0_wdata,
    input   [31:0]              cp0_rdata,
    output  [7 :0]              cp0_addr,
    

    output                      tlbr,
    output                      tlbwi,
    output                      tlbwr,
    output                      tlbp,
    

    output                      cache_req,
    output  [6 :0]              cache_op,
    input                       cache_op_ok,

    output                      done_o,
    input                       valid_i,
    input   [31:0]              pc_i,
    input   [31:0]              inst_i,
    input   [99:0]              decoded_i,
    input   [31:0]              rdata1_i,
    input   [31:0]              rdata2_i,
    input   [31:0]              pc_j_i,
    input   [31:0]              pc_b_i,
    input                       ready_i,
    output reg                  valid_o,
    output reg [31:0]           pc_o,
    output reg [31:0]           inst_o,
    output reg [`I_MAX-1:0]     ctrl_o,
    output reg [31:0]           result_o,
    output reg [31:0]           eaddr_o,
    output reg [31:0]           rdata2_o,
    output reg [4 :0]           waddr_o,
    

    input                       exc_i,
    input                       exc_miss_i,
    input   [4 :0]              exccode_i,
    output                      commit,
    output                      commit_miss,
    output                      commit_int,
    output  [4 :0]              commit_code,
    output                      commit_bd,
    output  [31:0]              commit_epc,
    output  [31:0]              commit_bvaddr,
    output                      commit_eret,
    
    output reg [31:0]           perfcnt_load_waitreq,
    output reg [31:0]           perfcnt_store_waitreq
);

    wire valid;
    reg done;

    assign valid = valid_i && !done && !exc_i;
    

    
    wire
        op_sll,op_srl,op_sra,op_sllv,op_srlv,op_srav,
        op_jr,op_jalr,op_movz, op_movn, op_syscall,op_break,op_sync,
        op_mfhi,op_mthi,op_mflo,op_mtlo,op_mult,op_multu,op_div,op_divu,
        op_add,op_addu,op_sub,op_subu,op_and,op_or,op_xor,op_nor,op_slt,op_sltu,
        op_tge, op_tgeu, op_tlt, op_tltu, op_teq, op_tne, op_bltz,op_bgez,op_bltzl,op_bgezl,
        op_tgei, op_tgeiu, op_tlti, op_tltiu, op_teqi, op_tnei, op_bltzal,op_bgezal,op_bltzall,op_bgezall,
        op_j,op_jal,op_beq,op_bne,op_blez,op_bgtz,
        op_addi,op_addiu,op_slti,op_sltiu,op_andi,op_ori,op_xori,op_lui,
        op_mfc0,op_mtc0,op_tlbr,op_tlbwi,op_tlbwr,op_tlbp,op_eret,op_wait,
        op_beql,op_bnel,op_blezl,op_bgtzl,
        op_madd,op_maddu,op_mul,op_msub,op_msubu,op_clz,op_clo,
        op_lb,op_lh,op_lwl,op_lw,op_lbu,op_lhu,op_lwr,op_sb,op_sh,op_swl,op_sw,op_swr,op_cache,op_ll,op_pref,op_sc
    ;
    
    assign {
        op_sll,op_srl,op_sra,op_sllv,op_srlv,op_srav,
        op_jr,op_jalr,op_movz, op_movn, op_syscall,op_break,op_sync,
        op_mfhi,op_mthi,op_mflo,op_mtlo,op_mult,op_multu,op_div,op_divu,
        op_add,op_addu,op_sub,op_subu,op_and,op_or,op_xor,op_nor,op_slt,op_sltu,
        op_tge, op_tgeu, op_tlt, op_tltu, op_teq, op_tne, op_bltz,op_bgez,op_bltzl,op_bgezl,
        op_tgei, op_tgeiu, op_tlti, op_tltiu, op_teqi, op_tnei, op_bltzal,op_bgezal,op_bltzall,op_bgezall,
        op_j,op_jal,op_beq,op_bne,op_blez,op_bgtz,
        op_addi,op_addiu,op_slti,op_sltiu,op_andi,op_ori,op_xori,op_lui,
        op_mfc0,op_mtc0,op_tlbr,op_tlbwi,op_tlbwr,op_tlbp,op_eret,op_wait,
        op_beql,op_bnel,op_blezl,op_bgtzl,
        op_madd,op_maddu,op_mul,op_msub,op_msubu,op_clz,op_clo,
        op_lb,op_lh,op_lwl,op_lw,op_lbu,op_lhu,op_lwr,op_sb,op_sh,op_swl,op_sw,op_swr,op_cache,op_ll,op_pref,op_sc
    } = decoded_i;
    
    wire [`I_MAX-1:0] ctrl_sig;
    
    wire reserved = ~|decoded_i;
    

    
    wire cp0_inst = op_mfc0||op_mtc0||op_tlbr||op_tlbwi||op_tlbwr||op_tlbp||op_eret||op_wait||op_cache;
    wire cp0_avail = status[`STATUS_CU0] || !status[`STATUS_UM] || status[`STATUS_EXL];
    wire cp0u = cp0_inst && !cp0_avail;
    

    reg llbit;
    always @(posedge clk) begin
        if (!resetn) llbit <= 1'b0;
        else if (commit && commit_eret) llbit <= 1'b0;
        else if (valid && op_ll) llbit <= 1'b1;
    end
    

    wire cond_move                = op_movz && rdata2_i == 32'd0 || op_movn && rdata2_i != 32'd0;

    wire inst_rt_wex              = op_addi||op_addiu||op_slti||op_sltiu||op_andi||op_ori||op_xori||op_lui||op_mfc0||op_clz||op_clo||op_sc;

    wire inst_rt_wwb              = ctrl_sig[`I_MEM_R];

    wire inst_rd_wex              = op_sll||op_srl||op_sra||op_sllv||op_srlv||op_srav||op_jr||op_jalr||op_mfhi||op_mflo||
                                    op_add||op_addu||op_sub||op_subu||op_and||op_or||op_xor||op_nor||op_slt||op_sltu||op_mul||cond_move;

    wire inst_r31_wex             = op_bltzal||op_bgezal||op_bltzall||op_bgezall||op_jal;
    
    assign ctrl_sig[`I_LB]        = op_lb;
    assign ctrl_sig[`I_LH]        = op_lh;
    assign ctrl_sig[`I_LWL]       = op_lwl;
    assign ctrl_sig[`I_LW]        = op_lw;
    assign ctrl_sig[`I_LBU]       = op_lbu;
    assign ctrl_sig[`I_LHU]       = op_lhu;
    assign ctrl_sig[`I_LWR]       = op_lwr;
    assign ctrl_sig[`I_SB]        = op_sb;
    assign ctrl_sig[`I_SH]        = op_sh;
    assign ctrl_sig[`I_SWL]       = op_swl;
    assign ctrl_sig[`I_SW]        = op_sw;
    assign ctrl_sig[`I_SWR]       = op_swr;
    

    assign ctrl_sig[`I_MEM_R]     = op_lb||op_lh||op_lwl||op_lw||op_lbu||op_lhu||op_lwr||op_ll;

    assign ctrl_sig[`I_MEM_W]     = op_sb||op_sh||op_swl||op_sw||op_swr||op_sc&&llbit;

    assign ctrl_sig[`I_WEX]       = inst_rt_wex||inst_rd_wex||inst_r31_wex;

    assign ctrl_sig[`I_WWB]       = inst_rt_wwb;

    wire imm_is_sx  = !(op_andi||op_ori||op_xori);

    wire alu_a_sa   = op_sll||op_srl||op_sra;

    wire alu_b_imm  = op_addi||op_addiu||op_slti||op_sltiu||op_andi||op_ori||op_xori||ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W];
    wire do_link    = op_jal||op_jalr||op_bgezal||op_bltzal||op_bgezall||op_bltzall;
    wire exc_on_of  = op_add || op_sub || op_addi;
    
    wire do_bne     = op_bne||op_bnel;
    wire do_beq     = op_beq||op_beql;
    wire do_bgez    = op_bgez||op_bgezl||op_bgezal||op_bgezall;
    wire do_blez    = op_blez||op_blezl;
    wire do_bgtz    = op_bgtz||op_bgtzl;
    wire do_bltz    = op_bltz||op_bltzl||op_bltzal||op_bltzall;
    wire do_j       = op_j||op_jal;
    wire do_jr      = op_jr||op_jalr;
    
    wire [4:0] waddr = {5{inst_rt_wex||inst_rt_wwb}}    & `GET_RT(inst_i)
                     | {5{inst_rd_wex}}                 & `GET_RD(inst_i)
                     | {5{inst_r31_wex}}                & 5'd31;


    wire [15:0] imm = `GET_IMM(inst_i);
    wire [31:0] imm_sx = {{16{imm[15]}}, imm};
    wire [31:0] imm_zx = {16'd0, imm};
    wire [31:0] imm_32 = imm_is_sx ? imm_sx : imm_zx;
    

    wire [10:0] alu_op;
    assign alu_op[`ALU_ADD]   = op_add||op_addu||op_addi||op_addiu;
    assign alu_op[`ALU_SUB]   = op_sub||op_subu;
    assign alu_op[`ALU_AND]   = op_and||op_andi;
    assign alu_op[`ALU_OR]    = op_or||op_ori;
    assign alu_op[`ALU_XOR]   = op_xor||op_xori;
    assign alu_op[`ALU_NOR]   = op_nor;
    assign alu_op[`ALU_SLT]   = op_slt||op_slti;
    assign alu_op[`ALU_SLTU]  = op_sltu||op_sltiu;
    assign alu_op[`ALU_SLL]   = op_sll||op_sllv;
    assign alu_op[`ALU_SRL]   = op_srl||op_srlv;
    assign alu_op[`ALU_SRA]   = op_sra||op_srav;
    

    wire [31:0] alu_a, alu_b, alu_res_wire;
    wire alu_of;
    alu alu_instance(
        .A          (alu_a),
        .B          (alu_b),
        .ALUop      (alu_op),
        .CarryOut   (),
        .Overflow   (alu_of),
        .Zero       (),
        .Result     (alu_res_wire)
    );


    assign alu_a = alu_a_sa ? {27'd0, `GET_SA(inst_i)} : rdata1_i;
    assign alu_b = alu_b_imm ? imm_32 : rdata2_i;
    
    wire alu_of_exc = exc_on_of && alu_of;
    

    wire trap_b_imm = op_tgei||op_tgeiu||op_tlti||op_tltiu||op_teqi||op_tnei;
    wire [31:0] trap_a = rdata1_i;
    wire [31:0] trap_b = trap_b_imm ? imm_sx : rdata2_i;
    wire [32:0] trap_res = trap_a - trap_b;
    wire trap_ge    = ~(trap_a[31] ^ trap_b[31] ^ trap_res[32]);
    wire trap_geu   = ~trap_res[32];
    wire trap_lt    = trap_a[31] ^ trap_b[31] ^ trap_res[32];
    wire trap_ltu   = trap_res[32];
    wire trap_eq    = ~|(trap_a ^ trap_b);
    wire trap_ne    = |(trap_a ^ trap_b);
    wire trap       = op_tge && trap_ge
                   || op_tgei && trap_ge
                   || op_tgeu && trap_geu
                   || op_tgeiu && trap_geu
                   || op_tlt && trap_lt
                   || op_tlti && trap_lt
                   || op_tltu && trap_ltu
                   || op_tltiu && trap_ltu
                   || op_teq && trap_eq
                   || op_teqi && trap_eq
                   || op_tne && trap_ne
                   || op_tnei && trap_ne;

    reg muldiv;
    


    wire [63:0] mul_res;
    reg [0:0] mul_flag;
    reg [1:0] maddsub_flag;
    reg maddsub;
    reg mul_start;
    always @(posedge clk) begin
        if (!resetn) mul_flag <= 1'b0;
        else if ((op_div||op_divu) && valid) mul_flag <= 1'b0;
        else mul_flag <= {(op_mult||op_multu||op_mul) && valid && !mul_start};
        
        if (!resetn) maddsub_flag <= 2'b00;
        else if ((op_div||op_divu||op_mult||op_multu) && valid) maddsub_flag <= 2'b00;
        else maddsub_flag <= {maddsub_flag[0:0], (op_madd||op_maddu||op_msub||op_msubu) && valid && !mul_start && !muldiv};
        
        if (op_madd||op_maddu||op_msub||op_msubu) maddsub <= op_madd||op_maddu;
        
        if (!resetn) mul_start <= 1'b0;
        else if (done_o && ready_i) mul_start <= 1'b0;
        else if ((op_mult||op_multu||op_mul||!muldiv&&(op_madd||op_maddu||op_msub||op_msubu)) && valid) mul_start <= 1'b1;
    end
    
    mul u_mul(
        .mul_clk(clk),
        .resetn(resetn),
        .mul_signed(op_mult||op_mul||op_madd||op_msub),
        .x(rdata1_i),
        .y(rdata2_i),
        .result(mul_res)
    );
    

    wire [31:0] div_s, div_r;
    wire div_complete;
    div u_div(
        .div_clk(clk),
        .resetn(resetn),
        .div((op_div||op_divu) && valid),
        .div_signed(op_div),
        .x(rdata1_i),
        .y(rdata2_i),
        .s(div_s),
        .r(div_r),
        .complete(div_complete),
        .cancel((op_mult||op_multu) && valid)
    );
    
    always @(posedge clk) begin
        if (!resetn) muldiv <= 1'b0;
        else if (mul_flag[0] || maddsub_flag[1] || div_complete) muldiv <= 1'b0;
        else if ((op_mult||op_multu||op_div||op_divu||op_madd||op_maddu||op_msub||op_msubu) && valid) muldiv <= 1'b1;
    end
    
    reg [63:0] maddsub_temp;
    always @(posedge clk) if (maddsub_flag[0]) maddsub_temp <= mul_res;
    

    reg [31:0] hi, lo;
    always @(posedge clk) begin
        if (mul_flag[0] && !op_mul) begin
            hi <= mul_res[63:32];
            lo <= mul_res[31:0];
        end
        else if (maddsub_flag[1]) begin
            {hi, lo} <= maddsub ? {hi, lo} + maddsub_temp : {hi, lo} - maddsub_temp;
        end
        else if (div_complete) begin
            hi <= div_r;
            lo <= div_s;
        end
        else begin
            if (valid && op_mthi) hi <= rdata1_i;
            if (valid && op_mtlo) lo <= rdata1_i;
        end
    end
    

    reg clo_start;
    reg [31:0] clo_data, clo_result;
    reg [4 :0] clo_cnt;
    wire do_cloz = op_clo||op_clz;
    
    always @(posedge clk) begin
        if (!resetn) clo_start <= 1'b0;
        else if (done_o && ready_i) clo_start <= 1'b0;
        else if (valid && do_cloz) clo_start <= 1'b1;
        
        if (!resetn) clo_cnt <= 5'd0;
        else if (valid && do_cloz && !clo_start) clo_cnt <= 5'd0;
        else if (clo_start) clo_cnt <= clo_cnt + 5'd1;
        
        if (!resetn) clo_data <= 32'd0;
        else if (valid && do_cloz && !clo_start) clo_data <= op_clo ? rdata1_i : ~rdata1_i;
        else if (clo_start) clo_data <= clo_data << 1;
        
        if (!resetn) clo_result <= 32'd0;
        else if (valid && do_cloz && !clo_start) clo_result <= 32'd0;
        else if (clo_start && clo_data[31]) clo_result <= clo_result + 32'd1;
    end
    
    wire cloz_ok = clo_start && ~clo_data[31];
    

    wire branch_taken   = (do_bne && (rdata1_i != rdata2_i))
                       || (do_beq && (rdata1_i == rdata2_i))
                       || (do_bgez && !rdata1_i[31])
                       || (do_blez && (rdata1_i[31] || rdata1_i == 32'd0))
                       || (do_bgtz && !(rdata1_i[31] || rdata1_i == 32'd0))
                       || (do_bltz && rdata1_i[31]);

    assign branch       = valid && branch_ready && (do_j||do_jr||branch_taken);
    
    assign target_pc    = {32{!(do_j||do_jr)}} & pc_b_i
                        | {32{do_jr}} & rdata1_i
                        | {32{do_j}} & pc_j_i;
    

    assign cp0_w = valid && !cp0u && op_mtc0;
    assign cp0_wdata = rdata2_i;
    assign cp0_addr = {`GET_RD(inst_i), inst_i[2:0]};
    

    assign tlbr = valid && !cp0u && op_tlbr;
    assign tlbwi = valid && !cp0u && op_tlbwi;
    assign tlbwr = valid && !cp0u && op_tlbwr;
    assign tlbp = valid && !cp0u && op_tlbp;
    

    

    reg [1:0] qstate, qstate_next;
    

    reg tlbc_valid;
    reg [19:0] tlbc_vaddr_hi, tlbc_paddr_hi;
    reg tlbc_miss, tlbc_invalid, tlbc_dirty;
    reg [2:0] tlbc_cattr;
    

    wire [31:0] eaddr = rdata1_i + imm_sx;
    wire [31:0] ea_aligned = eaddr & 32'hfffffffc;
    wire [1:0] mem_byte_offset = eaddr[1:0];
    wire [1:0] mem_byte_offsetn = ~mem_byte_offset;
    
    wire kseg01 = ea_aligned[31:30] == 2'b10;
    wire kseg0 = ea_aligned[31:29] == 3'b100;
    wire kseg = ea_aligned[31];
    wire kernelmode = !status[`STATUS_UM] || status[`STATUS_EXL];
    wire mem_adel   = (op_lw||op_ll) && eaddr[1:0] != 2'd0
                   || (op_lh||op_lhu) && eaddr[0] != 1'd0
                   || (ctrl_sig[`I_MEM_R] || op_cache) && kseg && !kernelmode;
    wire mem_ades   = (op_sw||op_sc) && eaddr[1:0] != 2'd0
                   || op_sh && eaddr[0] != 1'd0
                   || ctrl_sig[`I_MEM_W] && kseg && !kernelmode;
    wire mem_read = ctrl_sig[`I_MEM_R] && !mem_adel;
    wire mem_write = ctrl_sig[`I_MEM_W] && !mem_ades;
    
    wire tlbc_hit = tlbc_valid && tlbc_vaddr_hi == ea_aligned[31:12];
    
    wire tlbc_ok = qstate == 2'd0 && tlbc_hit
                || qstate == 2'd2;
    
    wire tlbl = (ctrl_sig[`I_MEM_R] || op_cache) && tlbc_ok && (tlbc_miss || tlbc_invalid);
    wire tlbs = ctrl_sig[`I_MEM_W] && tlbc_ok && (tlbc_miss || tlbc_invalid);
    wire tlbm = ctrl_sig[`I_MEM_W] && tlbc_ok && !tlbc_miss && !tlbc_invalid && !tlbc_dirty;
    
    wire mem_exc = qstate == 2'd0 && (mem_adel || mem_ades) || tlbl || tlbs || tlbm;
    
    always @(posedge clk) begin
        if (!resetn) qstate <= 2'd0;
        else qstate <= qstate_next;
    end
    
    always @(*) begin
        case (qstate)
        2'd0:       qstate_next = (kseg01 || tlbc_hit || !valid_i || !mem_read && !mem_write && !(op_cache && !cp0u)) ? 2'd0 : 2'd1;
        2'd1:       qstate_next = 2'd2;
        2'd2:       qstate_next = mem_exc || data_addr_ok ? 2'd0 : 2'd2;
        default:    qstate_next = 2'd0;
        endcase
    end
    

    reg [31:0] ea_aligned_save;
    always @(posedge clk) if (qstate_next == 2'd1) ea_aligned_save <= ea_aligned;
    
    assign tlb_vaddr = ea_aligned_save;
    
    always @(posedge clk) begin
        if (!resetn) tlbc_valid <= 1'b0;
        else if (tlbwi || tlbwr) tlbc_valid <= 1'b0;
        else if (qstate == 2'd1) tlbc_valid <= 1'b1;
    end
    
    always @(posedge clk) begin
        if (qstate == 2'd1) begin
            tlbc_vaddr_hi <= ea_aligned_save[31:12];
            tlbc_paddr_hi <= tlb_paddr[31:12];
            tlbc_miss <= tlb_miss;
            tlbc_invalid <= tlb_invalid;
            tlbc_dirty <= tlb_dirty;
            tlbc_cattr <= tlb_cattr;
        end
    end
    
    wire req_state = qstate == 2'd0 && (kseg01 || tlbc_hit)
                  || qstate == 2'd2;
    
    assign data_req = valid && (mem_read || mem_write) && !mem_exc && req_state;
    assign data_cache = qstate == 2'd0 ? (kseg0 && config_k0[0]) : tlbc_cattr[0];
    assign data_wr = mem_write;
    

    assign data_wstrb =
        {4{op_sw||op_sc}} & 4'b1111 |
        {4{op_sh}} & (4'b0011 << mem_byte_offset) |
        {4{op_sb}} & (4'b0001 << mem_byte_offset) |
        {4{op_swl}} & (4'b1111 >> mem_byte_offsetn) |
        {4{op_swr}} & (4'b1111 << mem_byte_offset);
    

    assign data_wdata =
        {32{op_sw||op_sc}} & rdata2_i |
        {32{op_sh}} & {rdata2_i[15:0], rdata2_i[15:0]} |
        {32{op_sb}} & {rdata2_i[7:0], rdata2_i[7:0], rdata2_i[7:0], rdata2_i[7:0]} |
        {32{op_swl}} & (rdata2_i >> (8 * mem_byte_offsetn)) |
        {32{op_swr}} & (rdata2_i << (8 * mem_byte_offset));
    
    assign data_addr[31:12] = (qstate == 2'd0 && kseg01) ? {3'd0, ea_aligned[28:12]} : tlbc_paddr_hi;
    assign data_addr[11:0]  = qstate == 2'd0 ? ea_aligned[11:0] : ea_aligned_save[11:0];
    
    assign data_size =
        {3{op_sw||op_sc||op_swl||op_swr||op_lw||op_ll||op_lwl||op_lwr}} & 3'd2 |
        {3{op_sh||op_lh||op_lhu}} & 3'd1 |
        {3{op_sb||op_lb||op_lbu}} & 3'd0;
    

    assign cache_req = valid && op_cache && !cp0u && !mem_exc  && req_state;
    assign cache_op[0] = `GET_RT(inst_i) == 5'b00000;
    assign cache_op[1] = `GET_RT(inst_i) == 5'b01000;
    assign cache_op[2] = `GET_RT(inst_i) == 5'b10000;
    assign cache_op[3] = `GET_RT(inst_i) == 5'b00001;
    assign cache_op[4] = `GET_RT(inst_i) == 5'b01001;
    assign cache_op[5] = `GET_RT(inst_i) == 5'b10001;
    assign cache_op[6] = `GET_RT(inst_i) == 5'b10101;

    always @(posedge clk) begin
        if (!resetn) done <= 1'b0;
        else if (ready_i) done <= 1'b0;
        else if (valid_i && done_o) done <= 1'b1;
    end

    wire br_inst = op_jr||op_jalr||op_bltz||op_bgez||op_bltzl||op_bgezl||op_bltzal||op_bgezal||op_bltzall||op_bgezall
                ||op_j||op_jal||op_beq||op_bne||op_blez||op_bgtz||op_beql||op_bnel||op_blezl||op_bgtzl;


    reg prev_branch;
    always @(posedge clk) begin
        if (!resetn) prev_branch <= 1'b0;
        else if (valid_i && done_o && ready_i) prev_branch <= br_inst && !(valid_i && exc_i);
    end


    wire exc = int_sig || reserved || cp0u
            || op_syscall || op_break || op_eret || trap
            || alu_of_exc || mem_adel || mem_ades
            || valid_i && (tlbl || tlbs || tlbm);

    wire [4:0] exccode = {5{int_sig}} & `EXC_INT
                       | {5{reserved}} & `EXC_RI
                       | {5{cp0u}} & `EXC_CPU
                       | {5{op_syscall}} & `EXC_SYS
                       | {5{op_break}} & `EXC_BP
                       | {5{trap}} & `EXC_TR
                       | {5{alu_of_exc}} & `EXC_OV
                       | {5{mem_adel}} & `EXC_ADEL
                       | {5{mem_ades}} & `EXC_ADES
                       | {5{tlbl}} & `EXC_TLBL
                       | {5{tlbs}} & `EXC_TLBS
                       | {5{tlbm}} & `EXC_MOD;
    assign commit = valid && exc || valid_i && exc_i;
    assign commit_miss = !cp0u && valid && (mem_read || mem_write || op_cache) && (qstate == 2'd0 && tlbc_hit || qstate == 2'd2) && tlbc_miss
                      || valid_i && exc_i && exc_miss_i;
    assign commit_int = !cp0u && int_sig;
    assign commit_code = valid && exc ? exccode : exccode_i;
    assign commit_bd = prev_branch;
    assign commit_epc = prev_branch ? pc_i - 32'd4 : pc_i;
    assign commit_bvaddr = exc_i ? pc_i : eaddr;
    assign commit_eret = !cp0u && op_eret;
    
    wire done_nonmem = ((op_mfhi||op_mflo||op_mthi||op_mtlo||op_madd||op_maddu||op_msub||op_msubu) && !muldiv
                    ||  (do_j||do_jr||branch_taken) && branch_ready
                    ||  (op_mul) && mul_flag[0]
                    ||  (do_cloz) && cloz_ok
                    || !(op_mfhi||op_mflo||op_mthi||op_mtlo||op_madd||op_maddu||op_msub||op_msubu||
                         do_j||do_jr||branch_taken||op_mul||do_cloz||ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W]||op_cache));
    assign done_o   = done_nonmem
                   || (ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W]) && (data_addr_ok)
                   || op_cache && cache_op_ok
                   || exc_i || exc;
    
    assign fwd_addr = {5{valid_i}} & waddr;
    assign fwd_data = {32{op_mfhi}} & hi
                    | {32{op_mflo}} & lo
                    | {32{op_lui}} & {imm, 16'd0}
                    | {32{do_link}} & (pc_i + 32'd8)
                    | {32{op_mfc0}} & cp0_rdata
                    | {32{op_movz||op_movn}} & rdata1_i
                    | {32{op_mul}} & mul_res[31:0]
                    | {32{do_cloz}} & clo_result
                    | {32{op_sc}} & {32'd0, llbit}
                    | {32{!(op_mfhi||op_mflo||op_lui||do_link||op_mfc0||op_movz||op_movn||op_mul||do_cloz||op_sc)}} & alu_res_wire;

    assign fwd_ok   = valid && done_nonmem && ready_i && ctrl_sig[`I_WEX];

    always @(posedge clk) begin
        if (!resetn) begin
            valid_o     <= 1'b0;
            pc_o        <= 32'd0;
            inst_o      <= 32'd0;
            ctrl_o      <= `I_MAX'd0;
            waddr_o     <= 5'd0;
            result_o    <= 32'd0;
            eaddr_o     <= 32'd0;
            rdata2_o    <= 32'd0;
        end
        else if (ready_i) begin
            valid_o     <= valid_i && done_o && !exc_i && !exc;
            pc_o        <= pc_i;
            inst_o      <= inst_i;
            ctrl_o      <= ctrl_sig;
            waddr_o     <= waddr;
            result_o    <= fwd_data;
            eaddr_o     <= eaddr;
            rdata2_o    <= rdata2_i;
        end
    end
    

    always @(posedge clk) begin

        if (!resetn) perfcnt_load_waitreq <= 32'd0;
        else if (valid && data_req && !done_o && ctrl_sig[`I_MEM_R]) perfcnt_load_waitreq <= perfcnt_load_waitreq + 32'd1;

        if (!resetn) perfcnt_store_waitreq <= 32'd0;
        else if (valid && data_req && !done_o && ctrl_sig[`I_MEM_W]) perfcnt_store_waitreq <= perfcnt_store_waitreq + 32'd1;
    end

endmodule
module execute_stage(
    input                       clk,
    input                       resetn,


    output                      data_req,
    output                      data_cache,
    output                      data_wr,
    output  [3 :0]              data_wstrb,
    output  [31:0]              data_addr,
    output  [2 :0]              data_size,
    output  [31:0]              data_wdata,
    input                       data_addr_ok,
    

    output                      branch,
    input                       branch_ready,
    output  [31:0]              target_pc,
    

    output  [31:0]              tlb_vaddr,
    input   [31:0]              tlb_paddr,
    input                       tlb_miss,
    input                       tlb_invalid,
    input                       tlb_dirty,
    input   [2 :0]              tlb_cattr,
    
    input   [31:0]              status,
    input   [2: 0]              config_k0,
    

    input                       int_sig,
    

    output  [4 :0]              fwd_addr,
    output  [31:0]              fwd_data,
    output                      fwd_ok,
    

    output                      cp0_w,
    output  [31:0]              cp0_wdata,
    input   [31:0]              cp0_rdata,
    output  [7 :0]              cp0_addr,
    

    output                      tlbr,
    output                      tlbwi,
    output                      tlbwr,
    output                      tlbp,
    

    output                      cache_req,
    output  [6 :0]              cache_op,
    input                       cache_op_ok,

    output                      done_o,
    input                       valid_i,
    input   [31:0]              pc_i,
    input   [31:0]              inst_i,
    input   [99:0]              decoded_i,
    input   [31:0]              rdata1_i,
    input   [31:0]              rdata2_i,
    input   [31:0]              pc_j_i,
    input   [31:0]              pc_b_i,
    input                       ready_i,
    output reg                  valid_o,
    output reg [31:0]           pc_o,
    output reg [31:0]           inst_o,
    output reg [`I_MAX-1:0]     ctrl_o,
    output reg [31:0]           result_o,
    output reg [31:0]           eaddr_o,
    output reg [31:0]           rdata2_o,
    output reg [4 :0]           waddr_o,
    

    input                       exc_i,
    input                       exc_miss_i,
    input   [4 :0]              exccode_i,
    output                      commit,
    output                      commit_miss,
    output                      commit_int,
    output  [4 :0]              commit_code,
    output                      commit_bd,
    output  [31:0]              commit_epc,
    output  [31:0]              commit_bvaddr,
    output                      commit_eret,
    
    output reg [31:0]           perfcnt_load_waitreq,
    output reg [31:0]           perfcnt_store_waitreq
);


    wire valid;
    reg done;

    assign valid = valid_i && !done && !exc_i;
    

    
    wire
        op_sll,op_srl,op_sra,op_sllv,op_srlv,op_srav,
        op_jr,op_jalr,op_movz, op_movn, op_syscall,op_break,op_sync,
        op_mfhi,op_mthi,op_mflo,op_mtlo,op_mult,op_multu,op_div,op_divu,
        op_add,op_addu,op_sub,op_subu,op_and,op_or,op_xor,op_nor,op_slt,op_sltu,
        op_tge, op_tgeu, op_tlt, op_tltu, op_teq, op_tne, op_bltz,op_bgez,op_bltzl,op_bgezl,
        op_tgei, op_tgeiu, op_tlti, op_tltiu, op_teqi, op_tnei, op_bltzal,op_bgezal,op_bltzall,op_bgezall,
        op_j,op_jal,op_beq,op_bne,op_blez,op_bgtz,
        op_addi,op_addiu,op_slti,op_sltiu,op_andi,op_ori,op_xori,op_lui,
        op_mfc0,op_mtc0,op_tlbr,op_tlbwi,op_tlbwr,op_tlbp,op_eret,op_wait,
        op_beql,op_bnel,op_blezl,op_bgtzl,
        op_madd,op_maddu,op_mul,op_msub,op_msubu,op_clz,op_clo,
        op_lb,op_lh,op_lwl,op_lw,op_lbu,op_lhu,op_lwr,op_sb,op_sh,op_swl,op_sw,op_swr,op_cache,op_ll,op_pref,op_sc
    ;
    
    assign {
        op_sll,op_srl,op_sra,op_sllv,op_srlv,op_srav,
        op_jr,op_jalr,op_movz, op_movn, op_syscall,op_break,op_sync,
        op_mfhi,op_mthi,op_mflo,op_mtlo,op_mult,op_multu,op_div,op_divu,
        op_add,op_addu,op_sub,op_subu,op_and,op_or,op_xor,op_nor,op_slt,op_sltu,
        op_tge, op_tgeu, op_tlt, op_tltu, op_teq, op_tne, op_bltz,op_bgez,op_bltzl,op_bgezl,
        op_tgei, op_tgeiu, op_tlti, op_tltiu, op_teqi, op_tnei, op_bltzal,op_bgezal,op_bltzall,op_bgezall,
        op_j,op_jal,op_beq,op_bne,op_blez,op_bgtz,
        op_addi,op_addiu,op_slti,op_sltiu,op_andi,op_ori,op_xori,op_lui,
        op_mfc0,op_mtc0,op_tlbr,op_tlbwi,op_tlbwr,op_tlbp,op_eret,op_wait,
        op_beql,op_bnel,op_blezl,op_bgtzl,
        op_madd,op_maddu,op_mul,op_msub,op_msubu,op_clz,op_clo,
        op_lb,op_lh,op_lwl,op_lw,op_lbu,op_lhu,op_lwr,op_sb,op_sh,op_swl,op_sw,op_swr,op_cache,op_ll,op_pref,op_sc
    } = decoded_i;
    
    wire [`I_MAX-1:0] ctrl_sig;
    
    wire reserved = ~|decoded_i;
    

    
    wire cp0_inst = op_mfc0||op_mtc0||op_tlbr||op_tlbwi||op_tlbwr||op_tlbp||op_eret||op_wait||op_cache;
    wire cp0_avail = status[`STATUS_CU0] || !status[`STATUS_UM] || status[`STATUS_EXL];
    wire cp0u = cp0_inst && !cp0_avail;
    

    reg llbit;
    always @(posedge clk) begin
        if (!resetn) llbit <= 1'b0;
        else if (commit && commit_eret) llbit <= 1'b0;
        else if (valid && op_ll) llbit <= 1'b1;
    end
    

    wire cond_move                = op_movz && rdata2_i == 32'd0 || op_movn && rdata2_i != 32'd0;

    wire inst_rt_wex              = op_addi||op_addiu||op_slti||op_sltiu||op_andi||op_ori||op_xori||op_lui||op_mfc0||op_clz||op_clo||op_sc;

    wire inst_rt_wwb              = ctrl_sig[`I_MEM_R];

    wire inst_rd_wex              = op_sll||op_srl||op_sra||op_sllv||op_srlv||op_srav||op_jr||op_jalr||op_mfhi||op_mflo||
                                    op_add||op_addu||op_sub||op_subu||op_and||op_or||op_xor||op_nor||op_slt||op_sltu||op_mul||cond_move;

    wire inst_r31_wex             = op_bltzal||op_bgezal||op_bltzall||op_bgezall||op_jal;
    
    assign ctrl_sig[`I_LB]        = op_lb;
    assign ctrl_sig[`I_LH]        = op_lh;
    assign ctrl_sig[`I_LWL]       = op_lwl;
    assign ctrl_sig[`I_LW]        = op_lw;
    assign ctrl_sig[`I_LBU]       = op_lbu;
    assign ctrl_sig[`I_LHU]       = op_lhu;
    assign ctrl_sig[`I_LWR]       = op_lwr;
    assign ctrl_sig[`I_SB]        = op_sb;
    assign ctrl_sig[`I_SH]        = op_sh;
    assign ctrl_sig[`I_SWL]       = op_swl;
    assign ctrl_sig[`I_SW]        = op_sw;
    assign ctrl_sig[`I_SWR]       = op_swr;
    

    assign ctrl_sig[`I_MEM_R]     = op_lb||op_lh||op_lwl||op_lw||op_lbu||op_lhu||op_lwr||op_ll;

    assign ctrl_sig[`I_MEM_W]     = op_sb||op_sh||op_swl||op_sw||op_swr||op_sc&&llbit;

    assign ctrl_sig[`I_WEX]       = inst_rt_wex||inst_rd_wex||inst_r31_wex;

    assign ctrl_sig[`I_WWB]       = inst_rt_wwb;

    wire imm_is_sx  = !(op_andi||op_ori||op_xori);

    wire alu_a_sa   = op_sll||op_srl||op_sra;

    wire alu_b_imm  = op_addi||op_addiu||op_slti||op_sltiu||op_andi||op_ori||op_xori||ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W];
    wire do_link    = op_jal||op_jalr||op_bgezal||op_bltzal||op_bgezall||op_bltzall;
    wire exc_on_of  = op_add || op_sub || op_addi;
    
    wire do_bne     = op_bne||op_bnel;
    wire do_beq     = op_beq||op_beql;
    wire do_bgez    = op_bgez||op_bgezl||op_bgezal||op_bgezall;
    wire do_blez    = op_blez||op_blezl;
    wire do_bgtz    = op_bgtz||op_bgtzl;
    wire do_bltz    = op_bltz||op_bltzl||op_bltzal||op_bltzall;
    wire do_j       = op_j||op_jal;
    wire do_jr      = op_jr||op_jalr;
    
    wire [4:0] waddr = {5{inst_rt_wex||inst_rt_wwb}}    & `GET_RT(inst_i)
                     | {5{inst_rd_wex}}                 & `GET_RD(inst_i)
                     | {5{inst_r31_wex}}                & 5'd31;


    wire [15:0] imm = `GET_IMM(inst_i);
    wire [31:0] imm_sx = {{16{imm[15]}}, imm};
    wire [31:0] imm_zx = {16'd0, imm};
    wire [31:0] imm_32 = imm_is_sx ? imm_sx : imm_zx;
    

    wire [10:0] alu_op;
    assign alu_op[`ALU_ADD]   = op_add||op_addu||op_addi||op_addiu;
    assign alu_op[`ALU_SUB]   = op_sub||op_subu;
    assign alu_op[`ALU_AND]   = op_and||op_andi;
    assign alu_op[`ALU_OR]    = op_or||op_ori;
    assign alu_op[`ALU_XOR]   = op_xor||op_xori;
    assign alu_op[`ALU_NOR]   = op_nor;
    assign alu_op[`ALU_SLT]   = op_slt||op_slti;
    assign alu_op[`ALU_SLTU]  = op_sltu||op_sltiu;
    assign alu_op[`ALU_SLL]   = op_sll||op_sllv;
    assign alu_op[`ALU_SRL]   = op_srl||op_srlv;
    assign alu_op[`ALU_SRA]   = op_sra||op_srav;
    

    wire [31:0] alu_a, alu_b, alu_res_wire;
    wire alu_of;
    alu alu_instance(
        .A          (alu_a),
        .B          (alu_b),
        .ALUop      (alu_op),
        .CarryOut   (),
        .Overflow   (alu_of),
        .Zero       (),
        .Result     (alu_res_wire)
    );


    assign alu_a = alu_a_sa ? {27'd0, `GET_SA(inst_i)} : rdata1_i;
    assign alu_b = alu_b_imm ? imm_32 : rdata2_i;
    
    wire alu_of_exc = exc_on_of && alu_of;
    

    wire trap_b_imm = op_tgei||op_tgeiu||op_tlti||op_tltiu||op_teqi||op_tnei;
    wire [31:0] trap_a = rdata1_i;
    wire [31:0] trap_b = trap_b_imm ? imm_sx : rdata2_i;
    wire [32:0] trap_res = trap_a - trap_b;
    wire trap_ge    = ~(trap_a[31] ^ trap_b[31] ^ trap_res[32]);
    wire trap_geu   = ~trap_res[32];
    wire trap_lt    = trap_a[31] ^ trap_b[31] ^ trap_res[32];
    wire trap_ltu   = trap_res[32];
    wire trap_eq    = ~|(trap_a ^ trap_b);
    wire trap_ne    = |(trap_a ^ trap_b);
    wire trap       = op_tge && trap_ge
                   || op_tgei && trap_ge
                   || op_tgeu && trap_geu
                   || op_tgeiu && trap_geu
                   || op_tlt && trap_lt
                   || op_tlti && trap_lt
                   || op_tltu && trap_ltu
                   || op_tltiu && trap_ltu
                   || op_teq && trap_eq
                   || op_teqi && trap_eq
                   || op_tne && trap_ne
                   || op_tnei && trap_ne;

    reg muldiv;
    


    wire [63:0] mul_res;
    reg [0:0] mul_flag;
    reg [1:0] maddsub_flag;
    reg maddsub;
    reg mul_start;
    always @(posedge clk) begin
        if (!resetn) mul_flag <= 1'b0;
        else if ((op_div||op_divu) && valid) mul_flag <= 1'b0;
        else mul_flag <= {(op_mult||op_multu||op_mul) && valid && !mul_start};
        
        if (!resetn) maddsub_flag <= 2'b00;
        else if ((op_div||op_divu||op_mult||op_multu) && valid) maddsub_flag <= 2'b00;
        else maddsub_flag <= {maddsub_flag[0:0], (op_madd||op_maddu||op_msub||op_msubu) && valid && !mul_start && !muldiv};
        
        if (op_madd||op_maddu||op_msub||op_msubu) maddsub <= op_madd||op_maddu;
        
        if (!resetn) mul_start <= 1'b0;
        else if (done_o && ready_i) mul_start <= 1'b0;
        else if ((op_mult||op_multu||op_mul||!muldiv&&(op_madd||op_maddu||op_msub||op_msubu)) && valid) mul_start <= 1'b1;
    end
    
    mul u_mul(
        .mul_clk(clk),
        .resetn(resetn),
        .mul_signed(op_mult||op_mul||op_madd||op_msub),
        .x(rdata1_i),
        .y(rdata2_i),
        .result(mul_res)
    );
    

    wire [31:0] div_s, div_r;
    wire div_complete;
    div u_div(
        .div_clk(clk),
        .resetn(resetn),
        .div((op_div||op_divu) && valid),
        .div_signed(op_div),
        .x(rdata1_i),
        .y(rdata2_i),
        .s(div_s),
        .r(div_r),
        .complete(div_complete),
        .cancel((op_mult||op_multu) && valid)
    );
    
    always @(posedge clk) begin
        if (!resetn) muldiv <= 1'b0;
        else if (mul_flag[0] || maddsub_flag[1] || div_complete) muldiv <= 1'b0;
        else if ((op_mult||op_multu||op_div||op_divu||op_madd||op_maddu||op_msub||op_msubu) && valid) muldiv <= 1'b1;
    end
    
    reg [63:0] maddsub_temp;
    always @(posedge clk) if (maddsub_flag[0]) maddsub_temp <= mul_res;
    

    reg [31:0] hi, lo;
    always @(posedge clk) begin
        if (mul_flag[0] && !op_mul) begin
            hi <= mul_res[63:32];
            lo <= mul_res[31:0];
        end
        else if (maddsub_flag[1]) begin
            {hi, lo} <= maddsub ? {hi, lo} + maddsub_temp : {hi, lo} - maddsub_temp;
        end
        else if (div_complete) begin
            hi <= div_r;
            lo <= div_s;
        end
        else begin
            if (valid && op_mthi) hi <= rdata1_i;
            if (valid && op_mtlo) lo <= rdata1_i;
        end
    end
    

    reg clo_start;
    reg [31:0] clo_data, clo_result;
    reg [4 :0] clo_cnt;
    wire do_cloz = op_clo||op_clz;
    
    always @(posedge clk) begin
        if (!resetn) clo_start <= 1'b0;
        else if (done_o && ready_i) clo_start <= 1'b0;
        else if (valid && do_cloz) clo_start <= 1'b1;
        
        if (!resetn) clo_cnt <= 5'd0;
        else if (valid && do_cloz && !clo_start) clo_cnt <= 5'd0;
        else if (clo_start) clo_cnt <= clo_cnt + 5'd1;
        
        if (!resetn) clo_data <= 32'd0;
        else if (valid && do_cloz && !clo_start) clo_data <= op_clo ? rdata1_i : ~rdata1_i;
        else if (clo_start) clo_data <= clo_data << 1;
        
        if (!resetn) clo_result <= 32'd0;
        else if (valid && do_cloz && !clo_start) clo_result <= 32'd0;
        else if (clo_start && clo_data[31]) clo_result <= clo_result + 32'd1;
    end
    
    wire cloz_ok = clo_start && ~clo_data[31];
    

    wire branch_taken   = (do_bne && (rdata1_i != rdata2_i))
                       || (do_beq && (rdata1_i == rdata2_i))
                       || (do_bgez && !rdata1_i[31])
                       || (do_blez && (rdata1_i[31] || rdata1_i == 32'd0))
                       || (do_bgtz && !(rdata1_i[31] || rdata1_i == 32'd0))
                       || (do_bltz && rdata1_i[31]);

    assign branch       = valid && branch_ready && (do_j||do_jr||branch_taken);
    
    assign target_pc    = {32{!(do_j||do_jr)}} & pc_b_i
                        | {32{do_jr}} & rdata1_i
                        | {32{do_j}} & pc_j_i;
    

    assign cp0_w = valid && !cp0u && op_mtc0;
    assign cp0_wdata = rdata2_i;
    assign cp0_addr = {`GET_RD(inst_i), inst_i[2:0]};
    

    assign tlbr = valid && !cp0u && op_tlbr;
    assign tlbwi = valid && !cp0u && op_tlbwi;
    assign tlbwr = valid && !cp0u && op_tlbwr;
    assign tlbp = valid && !cp0u && op_tlbp;
    

    

    reg [1:0] qstate, qstate_next;
    

    reg tlbc_valid;
    reg [19:0] tlbc_vaddr_hi, tlbc_paddr_hi;
    reg tlbc_miss, tlbc_invalid, tlbc_dirty;
    reg [2:0] tlbc_cattr;
    

    wire [31:0] eaddr = rdata1_i + imm_sx;
    wire [31:0] ea_aligned = eaddr & 32'hfffffffc;
    wire [1:0] mem_byte_offset = eaddr[1:0];
    wire [1:0] mem_byte_offsetn = ~mem_byte_offset;
    
    wire kseg01 = ea_aligned[31:30] == 2'b10;
    wire kseg0 = ea_aligned[31:29] == 3'b100;
    wire kseg = ea_aligned[31];
    wire kernelmode = !status[`STATUS_UM] || status[`STATUS_EXL];
    wire mem_adel   = (op_lw||op_ll) && eaddr[1:0] != 2'd0
                   || (op_lh||op_lhu) && eaddr[0] != 1'd0
                   || (ctrl_sig[`I_MEM_R] || op_cache) && kseg && !kernelmode;
    wire mem_ades   = (op_sw||op_sc) && eaddr[1:0] != 2'd0
                   || op_sh && eaddr[0] != 1'd0
                   || ctrl_sig[`I_MEM_W] && kseg && !kernelmode;
    wire mem_read = ctrl_sig[`I_MEM_R] && !mem_adel;
    wire mem_write = ctrl_sig[`I_MEM_W] && !mem_ades;
    
    wire tlbc_hit = tlbc_valid && tlbc_vaddr_hi == ea_aligned[31:12];
    
    wire tlbc_ok = qstate == 2'd0 && tlbc_hit
                || qstate == 2'd2;
    
    wire tlbl = (ctrl_sig[`I_MEM_R] || op_cache) && tlbc_ok && (tlbc_miss || tlbc_invalid);
    wire tlbs = ctrl_sig[`I_MEM_W] && tlbc_ok && (tlbc_miss || tlbc_invalid);
    wire tlbm = ctrl_sig[`I_MEM_W] && tlbc_ok && !tlbc_miss && !tlbc_invalid && !tlbc_dirty;
    
    wire mem_exc = qstate == 2'd0 && (mem_adel || mem_ades) || tlbl || tlbs || tlbm;
    
    always @(posedge clk) begin
        if (!resetn) qstate <= 2'd0;
        else qstate <= qstate_next;
    end
    
    always @(*) begin
        case (qstate)
        2'd0:       qstate_next = (kseg01 || tlbc_hit || !valid_i || !mem_read && !mem_write && !(op_cache && !cp0u)) ? 2'd0 : 2'd1;
        2'd1:       qstate_next = 2'd2;
        2'd2:       qstate_next = mem_exc || data_addr_ok ? 2'd0 : 2'd2;
        default:    qstate_next = 2'd0;
        endcase
    end
    

    reg [31:0] ea_aligned_save;
    always @(posedge clk) if (qstate_next == 2'd1) ea_aligned_save <= ea_aligned;
    
    assign tlb_vaddr = ea_aligned_save;
    
    always @(posedge clk) begin
        if (!resetn) tlbc_valid <= 1'b0;
        else if (tlbwi || tlbwr) tlbc_valid <= 1'b0;
        else if (qstate == 2'd1) tlbc_valid <= 1'b1;
    end
    
    always @(posedge clk) begin
        if (qstate == 2'd1) begin
            tlbc_vaddr_hi <= ea_aligned_save[31:12];
            tlbc_paddr_hi <= tlb_paddr[31:12];
            tlbc_miss <= tlb_miss;
            tlbc_invalid <= tlb_invalid;
            tlbc_dirty <= tlb_dirty;
            tlbc_cattr <= tlb_cattr;
        end
    end
    
    wire req_state = qstate == 2'd0 && (kseg01 || tlbc_hit)
                  || qstate == 2'd2;
    
    assign data_req = valid && (mem_read || mem_write) && !mem_exc && req_state;
    assign data_cache = qstate == 2'd0 ? (kseg0 && config_k0[0]) : tlbc_cattr[0];
    assign data_wr = mem_write;
    

    assign data_wstrb =
        {4{op_sw||op_sc}} & 4'b1111 |
        {4{op_sh}} & (4'b0011 << mem_byte_offset) |
        {4{op_sb}} & (4'b0001 << mem_byte_offset) |
        {4{op_swl}} & (4'b1111 >> mem_byte_offsetn) |
        {4{op_swr}} & (4'b1111 << mem_byte_offset);
    

    assign data_wdata =
        {32{op_sw||op_sc}} & rdata2_i |
        {32{op_sh}} & {rdata2_i[15:0], rdata2_i[15:0]} |
        {32{op_sb}} & {rdata2_i[7:0], rdata2_i[7:0], rdata2_i[7:0], rdata2_i[7:0]} |
        {32{op_swl}} & (rdata2_i >> (8 * mem_byte_offsetn)) |
        {32{op_swr}} & (rdata2_i << (8 * mem_byte_offset));
    
    assign data_addr[31:12] = (qstate == 2'd0 && kseg01) ? {3'd0, ea_aligned[28:12]} : tlbc_paddr_hi;
    assign data_addr[11:0]  = qstate == 2'd0 ? ea_aligned[11:0] : ea_aligned_save[11:0];
    
    assign data_size =
        {3{op_sw||op_sc||op_swl||op_swr||op_lw||op_ll||op_lwl||op_lwr}} & 3'd2 |
        {3{op_sh||op_lh||op_lhu}} & 3'd1 |
        {3{op_sb||op_lb||op_lbu}} & 3'd0;
    

    assign cache_req = valid && op_cache && !cp0u && !mem_exc  && req_state;
    assign cache_op[0] = `GET_RT(inst_i) == 5'b00000;
    assign cache_op[1] = `GET_RT(inst_i) == 5'b01000;
    assign cache_op[2] = `GET_RT(inst_i) == 5'b10000;
    assign cache_op[3] = `GET_RT(inst_i) == 5'b00001;
    assign cache_op[4] = `GET_RT(inst_i) == 5'b01001;
    assign cache_op[5] = `GET_RT(inst_i) == 5'b10001;
    assign cache_op[6] = `GET_RT(inst_i) == 5'b10101;

    always @(posedge clk) begin
        if (!resetn) done <= 1'b0;
        else if (ready_i) done <= 1'b0;
        else if (valid_i && done_o) done <= 1'b1;
    end

    wire br_inst = op_jr||op_jalr||op_bltz||op_bgez||op_bltzl||op_bgezl||op_bltzal||op_bgezal||op_bltzall||op_bgezall
                ||op_j||op_jal||op_beq||op_bne||op_blez||op_bgtz||op_beql||op_bnel||op_blezl||op_bgtzl;


    reg prev_branch;
    always @(posedge clk) begin
        if (!resetn) prev_branch <= 1'b0;
        else if (valid_i && done_o && ready_i) prev_branch <= br_inst && !(valid_i && exc_i);
    end


    wire exc = int_sig || reserved || cp0u
            || op_syscall || op_break || op_eret || trap
            || alu_of_exc || mem_adel || mem_ades
            || valid_i && (tlbl || tlbs || tlbm);

    wire [4:0] exccode = {5{int_sig}} & `EXC_INT
                       | {5{reserved}} & `EXC_RI
                       | {5{cp0u}} & `EXC_CPU
                       | {5{op_syscall}} & `EXC_SYS
                       | {5{op_break}} & `EXC_BP
                       | {5{trap}} & `EXC_TR
                       | {5{alu_of_exc}} & `EXC_OV
                       | {5{mem_adel}} & `EXC_ADEL
                       | {5{mem_ades}} & `EXC_ADES
                       | {5{tlbl}} & `EXC_TLBL
                       | {5{tlbs}} & `EXC_TLBS
                       | {5{tlbm}} & `EXC_MOD;
    assign commit = valid && exc || valid_i && exc_i;
    assign commit_miss = !cp0u && valid && (mem_read || mem_write || op_cache) && (qstate == 2'd0 && tlbc_hit || qstate == 2'd2) && tlbc_miss
                      || valid_i && exc_i && exc_miss_i;
    assign commit_int = !cp0u && int_sig;
    assign commit_code = valid && exc ? exccode : exccode_i;
    assign commit_bd = prev_branch;
    assign commit_epc = prev_branch ? pc_i - 32'd4 : pc_i;
    assign commit_bvaddr = exc_i ? pc_i : eaddr;
    assign commit_eret = !cp0u && op_eret;
    
    wire done_nonmem = ((op_mfhi||op_mflo||op_mthi||op_mtlo||op_madd||op_maddu||op_msub||op_msubu) && !muldiv
                    ||  (do_j||do_jr||branch_taken) && branch_ready
                    ||  (op_mul) && mul_flag[0]
                    ||  (do_cloz) && cloz_ok
                    || !(op_mfhi||op_mflo||op_mthi||op_mtlo||op_madd||op_maddu||op_msub||op_msubu||
                         do_j||do_jr||branch_taken||op_mul||do_cloz||ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W]||op_cache));
    assign done_o   = done_nonmem
                   || (ctrl_sig[`I_MEM_R]||ctrl_sig[`I_MEM_W]) && (data_addr_ok)
                   || op_cache && cache_op_ok
                   || exc_i || exc;
    
    assign fwd_addr = {5{valid_i}} & waddr;
    assign fwd_data = {32{op_mfhi}} & hi
                    | {32{op_mflo}} & lo
                    | {32{op_lui}} & {imm, 16'd0}
                    | {32{do_link}} & (pc_i + 32'd8)
                    | {32{op_mfc0}} & cp0_rdata
                    | {32{op_movz||op_movn}} & rdata1_i
                    | {32{op_mul}} & mul_res[31:0]
                    | {32{do_cloz}} & clo_result
                    | {32{op_sc}} & {32'd0, llbit}
                    | {32{!(op_mfhi||op_mflo||op_lui||do_link||op_mfc0||op_movz||op_movn||op_mul||do_cloz||op_sc)}} & alu_res_wire;

    assign fwd_ok   = valid && done_nonmem && ready_i && ctrl_sig[`I_WEX];

    always @(posedge clk) begin
        if (!resetn) begin
            valid_o     <= 1'b0;
            pc_o        <= 32'd0;
            inst_o      <= 32'd0;
            ctrl_o      <= `I_MAX'd0;
            waddr_o     <= 5'd0;
            result_o    <= 32'd0;
            eaddr_o     <= 32'd0;
            rdata2_o    <= 32'd0;
        end
        else if (ready_i) begin
            valid_o     <= valid_i && done_o && !exc_i && !exc;
            pc_o        <= pc_i;
            inst_o      <= inst_i;
            ctrl_o      <= ctrl_sig;
            waddr_o     <= waddr;
            result_o    <= fwd_data;
            eaddr_o     <= eaddr;
            rdata2_o    <= rdata2_i;
        end
    end
    

    always @(posedge clk) begin

        if (!resetn) perfcnt_load_waitreq <= 32'd0;
        else if (valid && data_req && !done_o && ctrl_sig[`I_MEM_R]) perfcnt_load_waitreq <= perfcnt_load_waitreq + 32'd1;

        if (!resetn) perfcnt_store_waitreq <= 32'd0;
        else if (valid && data_req && !done_o && ctrl_sig[`I_MEM_W]) perfcnt_store_waitreq <= perfcnt_store_waitreq + 32'd1;
    end

endmodule