data/full_repos/permissive/431474762/ID.v
1: b'%Error: data/full_repos/permissive/431474762/ID.v:1: Cannot find include file: lib/defines.vh\n`include "lib/defines.vh" \n         ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/431474762,data/full_repos/permissive/431474762/lib/defines.vh\n             data/full_repos/permissive/431474762,data/full_repos/permissive/431474762/lib/defines.vh.v\n             data/full_repos/permissive/431474762,data/full_repos/permissive/431474762/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/431474762/ID.v:6: Define or directive not defined: \'`StallBus\'\n    input wire [`StallBus-1:0] stall,  \n                ^~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:8: Define or directive not defined: \'`IF_TO_ID_WD\'\n    input wire [`IF_TO_ID_WD-1:0] if_to_id_bus,\n                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:10: Define or directive not defined: \'`WB_TO_RF_WD\'\n    input wire [`WB_TO_RF_WD-1:0] wb_to_rf_bus,\n                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:11: Define or directive not defined: \'`EX_TO_ID_WD\'\n    input wire [`EX_TO_ID_WD-1:0] ex_to_id_bus,\n                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:12: Define or directive not defined: \'`MEM_TO_ID_WD\'\n    input wire [`MEM_TO_ID_WD-1:0] mem_to_id_bus,\n                ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:13: Define or directive not defined: \'`ID_TO_EX_WD\'\n    output wire [`ID_TO_EX_WD-1:0] id_to_ex_bus,\n                 ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:14: Define or directive not defined: \'`BR_WD\'\n    output wire [`BR_WD-1:0] br_bus,  \n                 ^~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:23: Define or directive not defined: \'`IF_TO_ID_WD\'\n    reg [`IF_TO_ID_WD-1:0] if_to_id_bus_r; \n         ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:54: Define or directive not defined: \'`IF_TO_ID_WD\'\n            if_to_id_bus_r <= `IF_TO_ID_WD\'b0;\n                              ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:60: Define or directive not defined: \'`Stop\'\n        else if (stall[1]==`Stop && stall[2]==`NoStop) begin\n                           ^~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:60: syntax error, unexpected &&, expecting TYPE-IDENTIFIER\n        else if (stall[1]==`Stop && stall[2]==`NoStop) begin\n                                 ^~\n%Error: data/full_repos/permissive/431474762/ID.v:60: Define or directive not defined: \'`NoStop\'\n        else if (stall[1]==`Stop && stall[2]==`NoStop) begin\n                                              ^~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:61: Define or directive not defined: \'`IF_TO_ID_WD\'\n            if_to_id_bus_r <= `IF_TO_ID_WD\'b0;\n                              ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:64: syntax error, unexpected else\n        else if (stall[1]==`NoStop) begin\n        ^~~~\n%Error: data/full_repos/permissive/431474762/ID.v:64: Define or directive not defined: \'`NoStop\'\n        else if (stall[1]==`NoStop) begin\n                           ^~~~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:68: Define or directive not defined: \'`Stop\'\n        else if (stall[1]==`Stop && stall[2]==`Stop) begin\n                           ^~~~~\n%Error: data/full_repos/permissive/431474762/ID.v:68: Define or directive not defined: \'`Stop\'\n        else if (stall[1]==`Stop && stall[2]==`Stop) begin\n                                              ^~~~~\n%Error: Exiting due to 18 error(s)\n'
module ID(
    input wire clk,
    input wire rst,

    input wire [`StallBus-1:0] stall,  
    output wire stallreq,
    input wire [`IF_TO_ID_WD-1:0] if_to_id_bus,
    input wire [31:0] inst_sram_rdata,
    input wire [`WB_TO_RF_WD-1:0] wb_to_rf_bus,
    input wire [`EX_TO_ID_WD-1:0] ex_to_id_bus,
    input wire [`MEM_TO_ID_WD-1:0] mem_to_id_bus,
    output wire [`ID_TO_EX_WD-1:0] id_to_ex_bus,
    output wire [`BR_WD-1:0] br_bus,



    output wire stallreq_id,
    input wire [5:0] ex_aluop,
    input wire [4:0] ex_addr
);
    wire ex_inst_isload;
    reg [`IF_TO_ID_WD-1:0] if_to_id_bus_r;
    wire [31:0] inst;
    wire [31:0] id_pc;
    wire ce;
    

    wire wb_rf_we;
    wire [4:0] wb_rf_waddr;
    wire [31:0] wb_rf_wdata;
    wire wb_hl_we;
    wire [1:0]wb_hl_waddr;
    wire [63:0] wb_hl_wdata;
    
    wire ex_rf_we;
    wire [4:0] ex_rf_waddr;
    wire [31:0] ex_rf_wdata;
    wire ex_hl_we;
    wire [1:0]ex_hl_waddr;
    wire [63:0] ex_hl_wdata;
    
    wire mem_rf_we;
    wire [4:0] mem_rf_waddr;
    wire [31:0] mem_rf_wdata;
    wire mem_hl_we;
    wire [1:0]mem_hl_waddr;
    wire[63:0] mem_hl_wdata;
    

    reg id_stop;
    always @ (posedge clk) begin
        if (rst) begin
            if_to_id_bus_r <= `IF_TO_ID_WD'b0;
            id_stop <=1'b0;        
        end



        else if (stall[1]==`Stop && stall[2]==`NoStop) begin
            if_to_id_bus_r <= `IF_TO_ID_WD'b0;
            id_stop <=1'b1;
        end
        else if (stall[1]==`NoStop) begin
            if_to_id_bus_r <= if_to_id_bus;
            id_stop <=1'b0;
        end
        else if (stall[1]==`Stop && stall[2]==`Stop) begin
            id_stop <=1'b1;
        end
    end
    
    
    assign ex_inst_isload = (ex_aluop==6'b10_0000)|
                             (ex_aluop==6'b10_0100)|
                             (ex_aluop==6'b10_0001)|
                             (ex_aluop==6'b10_0101)|
                             (ex_aluop==6'b10_0011);
    assign stallreq_id=(ex_inst_isload==1'b0)?1'b0:
                        (ex_addr==rs|ex_addr==rt)?1'b1:1'b0;
    assign inst=id_stop?inst:inst_sram_rdata;
    assign {
        ce,
        id_pc
    } = if_to_id_bus_r;

    assign {
        wb_hl_wdata,
        wb_hl_waddr,
        wb_hl_we,
        wb_rf_we,
        wb_rf_waddr,
        wb_rf_wdata
    } = wb_to_rf_bus;
    assign {
        ex_hl_wdata,
        ex_hl_waddr,
        ex_hl_we,
        ex_rf_we,
        ex_rf_waddr,
        ex_rf_wdata
    }=ex_to_id_bus;
    assign {
        mem_hl_wdata,
        mem_hl_waddr,
        mem_hl_we,
        mem_rf_we,
        mem_rf_waddr,
        mem_rf_wdata
    }=mem_to_id_bus;
    
    
    
    wire [5:0] opcode;
    wire [4:0] rs,rt,rd,sa;
    wire [5:0] func;
    wire [15:0] imm;
    wire [25:0] instr_index;
    wire [19:0] code;
    wire [4:0] base;
    wire [15:0] offset;
    wire [2:0] sel;

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

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

    wire data_ram_en;
    wire [3:0] data_ram_wen;
    
    wire rf_we;
    wire [4:0] rf_waddr;
    wire hl_we;
    wire [1:0] hl_waddr;
    wire sel_rf_res;
    wire [2:0] sel_rf_dst;

    wire [31:0] rdata1, rdata2;
    
    wire hilo_addr;
    wire [31:0] p_rdata;
    wire [31:0] data1;
    wire [31:0] data2;
    wire [63:0] p_data;
    regfile u_regfile(
    	.clk    (clk          ),
        .raddr1 (rs           ),
        .rdata1 (rdata1       ),
        .raddr2 (rt           ),
        .rdata2 (rdata2       ),
        .we     (wb_rf_we     ),
        .waddr  (wb_rf_waddr  ),
        .wdata  (wb_rf_wdata  ),
        .p_raddr(hilo_addr    ),
        .hilo_o (p_rdata      ),
        .p_we   (wb_hl_we     ),
        .p_waddr(wb_hl_waddr  ),
        .p_wdata(wb_hl_wdata  )
    );
    assign hilo_addr = inst_mflo ? 1'b1:1'b0;

    assign p_data = (ex_hl_we==1'b1)&&(ex_hl_waddr[0]==1'b1)? ex_hl_wdata:
                     (ex_hl_we==1'b1)&&(ex_hl_waddr[1]==1'b1)&&(ex_hl_waddr[1]==hilo_addr)?{ex_hl_wdata[63:32],32'b0}:
                     (ex_hl_we==1'b1)&&(ex_hl_waddr[1]==1'b0)&&(ex_hl_waddr[1]==hilo_addr)?{32'b0,ex_hl_wdata[31:0]}:
                     (mem_hl_we==1'b1)&&(mem_hl_waddr[0]==1'b1)? mem_hl_wdata:
                     (mem_hl_we==1'b1)&&(mem_hl_waddr[1]==1'b1)&&(mem_hl_waddr[1]==hilo_addr)?{mem_hl_wdata[63:32],32'b0}:
                     (mem_hl_we==1'b1)&&(mem_hl_waddr[1]==1'b0)&&(mem_hl_waddr[1]==hilo_addr)?{32'b0,mem_hl_wdata[31:0]}:
                     (wb_hl_we==1'b1)&&(wb_hl_waddr[0]==1'b1)? wb_hl_wdata:
                     (wb_hl_we==1'b1)&&(wb_hl_waddr[1]==1'b1)&&(wb_hl_waddr[1]==hilo_addr)?{wb_hl_wdata[63:32],32'b0}:
                     (wb_hl_we==1'b1)&&(wb_hl_waddr[1]==1'b0)&&(wb_hl_waddr[1]==hilo_addr)?{32'b0,wb_hl_wdata[31:0]}:
                     hilo_addr?{p_rdata,32'b0}:{32'b0,p_rdata};
    

    assign data1=(ex_rf_we==1'b1)&&(ex_rf_waddr==rs)? ex_rf_wdata:
                 (mem_rf_we==1'b1)&&(mem_rf_waddr==rs)? mem_rf_wdata:
                 (wb_rf_we==1'b1)&&(wb_rf_waddr==rs)? wb_rf_wdata:rdata1;
                 
    assign data2=(ex_rf_we==1'b1)&&(ex_rf_waddr==rt)?ex_rf_wdata:
                 (mem_rf_we==1'b1)&&(mem_rf_waddr==rt)?mem_rf_wdata:
                 (wb_rf_we==1'b1)&&(wb_rf_waddr==rt)?wb_rf_wdata:rdata2;
    


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

    wire inst_ori, inst_lui, inst_addiu;
    wire inst_sub,inst_slt,inst_sltu,inst_slti,inst_sltiu;
    wire inst_and,inst_nor,inst_or,inst_xor;
    wire inst_sll,inst_srl,inst_sra;
    wire inst_subu;
    wire inst_addu;
    wire inst_add;
    wire inst_addi;
    wire inst_andi;
    wire inst_xori;
    wire inst_sllv;
    wire inst_srav;
    wire inst_srlv;

    wire inst_lb,inst_lbu,inst_lh,inst_lhu,inst_lw;
    wire inst_sb,inst_sh,inst_sw;
    wire op_add, op_sub, op_slt, op_sltu;
    wire op_and, op_nor, op_or, op_xor;
    wire op_sll, op_srl, op_sra, op_lui;

    wire inst_j,inst_jal,inst_jr,inst_jalr;

    wire inst_beq,inst_bne,inst_bgez,inst_bgtz,inst_blez,inst_bltz,inst_bgezal,inst_bltzal;

    wire inst_mfhi,inst_mflo,inst_mthi,inst_mtlo;

    wire inst_mult,inst_multu,inst_div,inst_divu;

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

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

    decoder_5_32 u1_decoder_5_32(
    	.in  (rt  ),
        .out (rt_d )
    );
    
    decoder_5_32 u2_decoder_5_32(
    	.in  (rd  ),
        .out (rd_d )
    );
    
    decoder_5_32 u3_decoder_5_32(
    	.in  (sa  ),
        .out (sa_d )
    );

    
    assign inst_ori     = op_d[6'b00_1101];

    assign inst_lui     = op_d[6'b00_1111];
    assign inst_addiu   = op_d[6'b00_1001];

    assign inst_sub     = op_d[6'b00_0000]&func_d[6'b10_0010];
    assign inst_subu    = op_d[6'b00_0000]&func_d[6'b10_0011];
    assign inst_slt     = op_d[6'b00_0000]&func_d[6'b10_1010];
    assign inst_sltu    = op_d[6'b00_0000]&func_d[6'b10_1011];
    assign inst_slti    = op_d[6'b00_1010];
    assign inst_sltiu   = op_d[6'b00_1011];
    assign inst_and     = op_d[6'b00_0000]&func_d[6'b10_0100];
    assign inst_nor     = op_d[6'b00_0000]&func_d[6'b10_0111];
    assign inst_or      = op_d[6'b00_0000]&func_d[6'b10_0101];
    assign inst_xor     = op_d[6'b00_0000]&func_d[6'b10_0110];
    assign inst_sll     = op_d[6'b00_0000]&func_d[6'b00_0000];
    assign inst_srl     = op_d[6'b00_0000]&func_d[6'b00_0010];
    assign inst_sra     = op_d[6'b00_0000]&func_d[6'b00_0011];
    assign inst_addu    = op_d[6'b00_0000]&func_d[6'b10_0001];
    assign inst_add     = op_d[6'b00_0000]&func_d[6'b10_0000];
    assign inst_addi    = op_d[6'b00_1000];
    assign inst_andi    = op_d[6'b00_1100];
    assign inst_xori    = op_d[6'b00_1110];
    assign inst_sllv    = op_d[6'b00_0000]&func_d[6'b00_0100];
    assign inst_srav    = op_d[6'b00_0000]&func_d[6'b00_0111];
    assign inst_srlv    = op_d[6'b00_0000]&func_d[6'b00_0110];

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

    assign inst_jr      =op_d[6'b00_0000]&&func_d[6'b00_1000];
    assign inst_jalr    =op_d[6'b00_0000]&&func_d[6'b00_1001];
    assign inst_jal     =op_d[6'b00_0011];
    assign inst_j       =op_d[6'b00_0010];

    assign inst_beq     = op_d[6'b00_0100];
    assign inst_bne     = op_d[6'b00_0101];
    assign inst_bgez    = op_d[6'b00_0001]&rt_d[5'b00001];
    assign inst_bgtz    = op_d[6'b00_0111];
    assign inst_blez    = op_d[6'b00_0110];
    assign inst_bltz    = op_d[6'b00_0001]&rt_d[5'b00000];
    assign inst_bgezal  = op_d[6'b00_0001]&rt_d[5'b10001];
    assign inst_bltzal  = op_d[6'b00_0001]&rt_d[5'b10000];

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

    assign inst_mult    = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1000];
    assign inst_multu   = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1001];
    assign inst_div     = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1010];
    assign inst_divu    = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1011];

    assign inst_lsa     = op_d[6'b01_1100]&func_d[6'b11_0111];

    assign sel_alu_src1[0] = inst_ori|inst_addiu|inst_add|inst_addu|inst_addi|inst_sllv|inst_srav|inst_srlv
                             |inst_sub|inst_subu|inst_slt|inst_sltu|inst_slti|inst_sltiu
                             |inst_and|inst_andi|inst_nor|inst_or|inst_xor|inst_xori
                             |inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw
                             |inst_mthi|inst_mtlo
                             |inst_mult|inst_multu|inst_div|inst_divu
                             |inst_lsa;
    

    assign sel_alu_src1[1] = 1'b0|inst_bgezal|inst_bltzal|inst_jal|inst_jalr;
    

    assign sel_alu_src1[2] = 1'b0|inst_sll|inst_srl|inst_sra;
    

    assign sel_alu_src2[0] = 1'b0|inst_sub|inst_subu|inst_slt|inst_sltu|inst_and|inst_srav|inst_srlv
                                  |inst_nor|inst_or|inst_xor|inst_sll|inst_srl|inst_sra|inst_addu|inst_add|inst_sllv
                                  |inst_mult|inst_multu|inst_div|inst_divu
                                  |inst_lsa;
    

    assign sel_alu_src2[1] = 1'b0|inst_lui|inst_addiu|inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw|inst_slti|inst_sltiu|inst_addi;


    assign sel_alu_src2[2] = 1'b0|inst_bgezal|inst_bltzal|inst_jal|inst_jalr;


    assign sel_alu_src2[3] = 1'b0|inst_ori|inst_andi|inst_xori;

    

    assign op_add = inst_addiu|inst_addu|inst_add|inst_addi
                              |inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw
                              |inst_bgezal|inst_bltzal|inst_jal|inst_jalr
                              |inst_mthi|inst_mtlo
                              |inst_lsa;
    assign op_sub = inst_sub |inst_subu;
    assign op_slt = inst_slt|inst_slti;
    assign op_sltu = inst_sltu|inst_sltiu;
    assign op_and = inst_and|inst_andi;
    assign op_nor = inst_nor;
    assign op_or = inst_ori|inst_or;
    assign op_xor = inst_xor|inst_xori;
    assign op_sll = inst_sll|inst_sllv;
    assign op_srl = inst_srl|inst_srlv;
    assign op_sra = inst_sra|inst_srav;
    assign op_lui = inst_lui;

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




    assign data_ram_en = inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw;


    assign data_ram_wen = inst_sb?4'b0001:
                           inst_sh?4'b0011:
                           inst_sw?4'b1111:
                           inst_lb|inst_lbu|inst_lh|inst_lhu|inst_lw?4'b0000:4'b1110;

    

    assign rf_we = inst_ori |inst_lui|inst_sub|inst_subu|inst_srav|inst_srlv
                             |inst_and|inst_andi|inst_nor|inst_or|inst_xor|inst_xori
                             |inst_add|inst_addi|inst_addiu|inst_addu|inst_sllv
                             |inst_slt|inst_slti|inst_sltiu|inst_sltu|inst_sll|inst_srl|inst_sra
                             |inst_bgezal|inst_bltzal|inst_jal|inst_jalr
                             |inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu
                             |inst_mfhi|inst_mflo
                             |inst_lsa;

    assign hl_we = inst_mthi|inst_mtlo
                   |inst_mult|inst_multu|inst_div|inst_divu;
    
    

    assign sel_rf_dst[0] = 1'b0|inst_sub|inst_subu|inst_addu|inst_and|inst_sllv|inst_srav|inst_srlv
                               |inst_nor|inst_or|inst_xor|inst_slt|inst_sltu|inst_sll|inst_srl|inst_sra|inst_add|inst_jalr
                               |inst_mfhi|inst_mflo
                               |inst_lsa;

    assign sel_rf_dst[1] = inst_ori|inst_lui|inst_addiu|inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_slti|inst_sltiu|inst_sltiu|inst_addi|inst_andi|inst_xori;

    assign sel_rf_dst[2] = 1'b0|inst_bgezal|inst_bltzal|inst_jal;


    assign rf_waddr = {5{sel_rf_dst[0]}} & rd 
                    | {5{sel_rf_dst[1]}} & rt
                    | {5{sel_rf_dst[2]}} & 32'd31;
    
    assign hl_waddr[0] = inst_mult|inst_multu|inst_div|inst_divu;
    assign hl_waddr[1] = inst_mtlo ? 1'b1:1'b0;
    
    

    assign sel_rf_res = 1'b0|inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu;
    
 
 
 
    assign id_to_ex_bus = {
        p_data,
        hl_waddr,
        hl_we,
        id_pc,
        inst,
        alu_op,
        sel_alu_src1,
        sel_alu_src2,
        data_ram_en,
        data_ram_wen,
        rf_we,
        rf_waddr,
        sel_rf_res,
        data1,
        data2
    };


    wire br_e;
    wire [31:0] br_addr;
    wire rs_eq_rt;
    wire rs_neq_rt;
    wire rs_ge_z;
    wire rs_gt_z;
    wire rs_le_z;
    wire rs_lt_z;
    wire [31:0] pc_plus_4;
    assign pc_plus_4 = id_pc + 32'h4;
    
    assign rs_eq_rt =   (data1 == data2);
    assign rs_neq_rt=   (data1!=data2);
    assign rs_ge_z=     (data1 == 32'b0)||(~data1[31]);
    assign rs_gt_z=     (~data1[31])&&(data1 != 32'b0);
    assign rs_le_z=     (data1 == 32'b0)||(data1[31]);
    assign rs_lt_z=     (data1[31]);
    

    assign br_e = inst_j|inst_jr|inst_jal|inst_jalr
                        |(inst_beq&rs_eq_rt)|(inst_bne&rs_neq_rt)
                        |(inst_bgez&rs_ge_z)|(inst_bgtz&rs_gt_z)
                        |(inst_blez&rs_le_z)|(inst_bltz&rs_lt_z)
                        |(inst_bgezal&rs_ge_z)|(inst_bltzal&rs_lt_z);
    assign br_addr =(inst_j|inst_jal)?{pc_plus_4[31:28],instr_index,2'b0}:
                    ((inst_jr|inst_jalr)?data1:
                    (inst_beq|inst_bne|inst_bgez|inst_bgtz|inst_blez|inst_bltz|inst_bgezal|inst_bltzal)?(pc_plus_4 + {{14{offset[15]}},offset,2'b0}):32'b0 );



    assign br_bus = {
        br_e,
        br_addr
    };
    
    
endmodule
module ID(
    input wire clk,
    input wire rst,

    input wire [`StallBus-1:0] stall,  
    output wire stallreq,
    input wire [`IF_TO_ID_WD-1:0] if_to_id_bus,
    input wire [31:0] inst_sram_rdata,
    input wire [`WB_TO_RF_WD-1:0] wb_to_rf_bus,
    input wire [`EX_TO_ID_WD-1:0] ex_to_id_bus,
    input wire [`MEM_TO_ID_WD-1:0] mem_to_id_bus,
    output wire [`ID_TO_EX_WD-1:0] id_to_ex_bus,
    output wire [`BR_WD-1:0] br_bus,



    output wire stallreq_id,
    input wire [5:0] ex_aluop,
    input wire [4:0] ex_addr
);

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

    wire wb_rf_we;
    wire [4:0] wb_rf_waddr;
    wire [31:0] wb_rf_wdata;
    wire wb_hl_we;
    wire [1:0]wb_hl_waddr;
    wire [63:0] wb_hl_wdata;
    
    wire ex_rf_we;
    wire [4:0] ex_rf_waddr;
    wire [31:0] ex_rf_wdata;
    wire ex_hl_we;
    wire [1:0]ex_hl_waddr;
    wire [63:0] ex_hl_wdata;
    
    wire mem_rf_we;
    wire [4:0] mem_rf_waddr;
    wire [31:0] mem_rf_wdata;
    wire mem_hl_we;
    wire [1:0]mem_hl_waddr;
    wire[63:0] mem_hl_wdata;
    

    reg id_stop;
    always @ (posedge clk) begin
        if (rst) begin
            if_to_id_bus_r <= `IF_TO_ID_WD'b0;
            id_stop <=1'b0;        
        end



        else if (stall[1]==`Stop && stall[2]==`NoStop) begin
            if_to_id_bus_r <= `IF_TO_ID_WD'b0;
            id_stop <=1'b1;
        end
        else if (stall[1]==`NoStop) begin
            if_to_id_bus_r <= if_to_id_bus;
            id_stop <=1'b0;
        end
        else if (stall[1]==`Stop && stall[2]==`Stop) begin
            id_stop <=1'b1;
        end
    end
    
    
    assign ex_inst_isload = (ex_aluop==6'b10_0000)|
                             (ex_aluop==6'b10_0100)|
                             (ex_aluop==6'b10_0001)|
                             (ex_aluop==6'b10_0101)|
                             (ex_aluop==6'b10_0011);
    assign stallreq_id=(ex_inst_isload==1'b0)?1'b0:
                        (ex_addr==rs|ex_addr==rt)?1'b1:1'b0;
    assign inst=id_stop?inst:inst_sram_rdata;
    assign {
        ce,
        id_pc
    } = if_to_id_bus_r;

    assign {
        wb_hl_wdata,
        wb_hl_waddr,
        wb_hl_we,
        wb_rf_we,
        wb_rf_waddr,
        wb_rf_wdata
    } = wb_to_rf_bus;
    assign {
        ex_hl_wdata,
        ex_hl_waddr,
        ex_hl_we,
        ex_rf_we,
        ex_rf_waddr,
        ex_rf_wdata
    }=ex_to_id_bus;
    assign {
        mem_hl_wdata,
        mem_hl_waddr,
        mem_hl_we,
        mem_rf_we,
        mem_rf_waddr,
        mem_rf_wdata
    }=mem_to_id_bus;
    
    
    
    wire [5:0] opcode;
    wire [4:0] rs,rt,rd,sa;
    wire [5:0] func;
    wire [15:0] imm;
    wire [25:0] instr_index;
    wire [19:0] code;
    wire [4:0] base;
    wire [15:0] offset;
    wire [2:0] sel;

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

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

    wire data_ram_en;
    wire [3:0] data_ram_wen;
    
    wire rf_we;
    wire [4:0] rf_waddr;
    wire hl_we;
    wire [1:0] hl_waddr;
    wire sel_rf_res;
    wire [2:0] sel_rf_dst;

    wire [31:0] rdata1, rdata2;
    
    wire hilo_addr;
    wire [31:0] p_rdata;
    wire [31:0] data1;
    wire [31:0] data2;
    wire [63:0] p_data;
    regfile u_regfile(
    	.clk    (clk          ),
        .raddr1 (rs           ),
        .rdata1 (rdata1       ),
        .raddr2 (rt           ),
        .rdata2 (rdata2       ),
        .we     (wb_rf_we     ),
        .waddr  (wb_rf_waddr  ),
        .wdata  (wb_rf_wdata  ),
        .p_raddr(hilo_addr    ),
        .hilo_o (p_rdata      ),
        .p_we   (wb_hl_we     ),
        .p_waddr(wb_hl_waddr  ),
        .p_wdata(wb_hl_wdata  )
    );
    assign hilo_addr = inst_mflo ? 1'b1:1'b0;

    assign p_data = (ex_hl_we==1'b1)&&(ex_hl_waddr[0]==1'b1)? ex_hl_wdata:
                     (ex_hl_we==1'b1)&&(ex_hl_waddr[1]==1'b1)&&(ex_hl_waddr[1]==hilo_addr)?{ex_hl_wdata[63:32],32'b0}:
                     (ex_hl_we==1'b1)&&(ex_hl_waddr[1]==1'b0)&&(ex_hl_waddr[1]==hilo_addr)?{32'b0,ex_hl_wdata[31:0]}:
                     (mem_hl_we==1'b1)&&(mem_hl_waddr[0]==1'b1)? mem_hl_wdata:
                     (mem_hl_we==1'b1)&&(mem_hl_waddr[1]==1'b1)&&(mem_hl_waddr[1]==hilo_addr)?{mem_hl_wdata[63:32],32'b0}:
                     (mem_hl_we==1'b1)&&(mem_hl_waddr[1]==1'b0)&&(mem_hl_waddr[1]==hilo_addr)?{32'b0,mem_hl_wdata[31:0]}:
                     (wb_hl_we==1'b1)&&(wb_hl_waddr[0]==1'b1)? wb_hl_wdata:
                     (wb_hl_we==1'b1)&&(wb_hl_waddr[1]==1'b1)&&(wb_hl_waddr[1]==hilo_addr)?{wb_hl_wdata[63:32],32'b0}:
                     (wb_hl_we==1'b1)&&(wb_hl_waddr[1]==1'b0)&&(wb_hl_waddr[1]==hilo_addr)?{32'b0,wb_hl_wdata[31:0]}:
                     hilo_addr?{p_rdata,32'b0}:{32'b0,p_rdata};
    

    assign data1=(ex_rf_we==1'b1)&&(ex_rf_waddr==rs)? ex_rf_wdata:
                 (mem_rf_we==1'b1)&&(mem_rf_waddr==rs)? mem_rf_wdata:
                 (wb_rf_we==1'b1)&&(wb_rf_waddr==rs)? wb_rf_wdata:rdata1;
                 
    assign data2=(ex_rf_we==1'b1)&&(ex_rf_waddr==rt)?ex_rf_wdata:
                 (mem_rf_we==1'b1)&&(mem_rf_waddr==rt)?mem_rf_wdata:
                 (wb_rf_we==1'b1)&&(wb_rf_waddr==rt)?wb_rf_wdata:rdata2;
    


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

    wire inst_ori, inst_lui, inst_addiu;
    wire inst_sub,inst_slt,inst_sltu,inst_slti,inst_sltiu;
    wire inst_and,inst_nor,inst_or,inst_xor;
    wire inst_sll,inst_srl,inst_sra;
    wire inst_subu;
    wire inst_addu;
    wire inst_add;
    wire inst_addi;
    wire inst_andi;
    wire inst_xori;
    wire inst_sllv;
    wire inst_srav;
    wire inst_srlv;

    wire inst_lb,inst_lbu,inst_lh,inst_lhu,inst_lw;
    wire inst_sb,inst_sh,inst_sw;
    wire op_add, op_sub, op_slt, op_sltu;
    wire op_and, op_nor, op_or, op_xor;
    wire op_sll, op_srl, op_sra, op_lui;

    wire inst_j,inst_jal,inst_jr,inst_jalr;

    wire inst_beq,inst_bne,inst_bgez,inst_bgtz,inst_blez,inst_bltz,inst_bgezal,inst_bltzal;

    wire inst_mfhi,inst_mflo,inst_mthi,inst_mtlo;

    wire inst_mult,inst_multu,inst_div,inst_divu;

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

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

    decoder_5_32 u1_decoder_5_32(
    	.in  (rt  ),
        .out (rt_d )
    );
    
    decoder_5_32 u2_decoder_5_32(
    	.in  (rd  ),
        .out (rd_d )
    );
    
    decoder_5_32 u3_decoder_5_32(
    	.in  (sa  ),
        .out (sa_d )
    );

    
    assign inst_ori     = op_d[6'b00_1101];

    assign inst_lui     = op_d[6'b00_1111];
    assign inst_addiu   = op_d[6'b00_1001];

    assign inst_sub     = op_d[6'b00_0000]&func_d[6'b10_0010];
    assign inst_subu    = op_d[6'b00_0000]&func_d[6'b10_0011];
    assign inst_slt     = op_d[6'b00_0000]&func_d[6'b10_1010];
    assign inst_sltu    = op_d[6'b00_0000]&func_d[6'b10_1011];
    assign inst_slti    = op_d[6'b00_1010];
    assign inst_sltiu   = op_d[6'b00_1011];
    assign inst_and     = op_d[6'b00_0000]&func_d[6'b10_0100];
    assign inst_nor     = op_d[6'b00_0000]&func_d[6'b10_0111];
    assign inst_or      = op_d[6'b00_0000]&func_d[6'b10_0101];
    assign inst_xor     = op_d[6'b00_0000]&func_d[6'b10_0110];
    assign inst_sll     = op_d[6'b00_0000]&func_d[6'b00_0000];
    assign inst_srl     = op_d[6'b00_0000]&func_d[6'b00_0010];
    assign inst_sra     = op_d[6'b00_0000]&func_d[6'b00_0011];
    assign inst_addu    = op_d[6'b00_0000]&func_d[6'b10_0001];
    assign inst_add     = op_d[6'b00_0000]&func_d[6'b10_0000];
    assign inst_addi    = op_d[6'b00_1000];
    assign inst_andi    = op_d[6'b00_1100];
    assign inst_xori    = op_d[6'b00_1110];
    assign inst_sllv    = op_d[6'b00_0000]&func_d[6'b00_0100];
    assign inst_srav    = op_d[6'b00_0000]&func_d[6'b00_0111];
    assign inst_srlv    = op_d[6'b00_0000]&func_d[6'b00_0110];

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

    assign inst_jr      =op_d[6'b00_0000]&&func_d[6'b00_1000];
    assign inst_jalr    =op_d[6'b00_0000]&&func_d[6'b00_1001];
    assign inst_jal     =op_d[6'b00_0011];
    assign inst_j       =op_d[6'b00_0010];

    assign inst_beq     = op_d[6'b00_0100];
    assign inst_bne     = op_d[6'b00_0101];
    assign inst_bgez    = op_d[6'b00_0001]&rt_d[5'b00001];
    assign inst_bgtz    = op_d[6'b00_0111];
    assign inst_blez    = op_d[6'b00_0110];
    assign inst_bltz    = op_d[6'b00_0001]&rt_d[5'b00000];
    assign inst_bgezal  = op_d[6'b00_0001]&rt_d[5'b10001];
    assign inst_bltzal  = op_d[6'b00_0001]&rt_d[5'b10000];

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

    assign inst_mult    = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1000];
    assign inst_multu   = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1001];
    assign inst_div     = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1010];
    assign inst_divu    = op_d[6'b00_0000]&sa_d[5'b00000]&func_d[6'b01_1011];

    assign inst_lsa     = op_d[6'b01_1100]&func_d[6'b11_0111];

    assign sel_alu_src1[0] = inst_ori|inst_addiu|inst_add|inst_addu|inst_addi|inst_sllv|inst_srav|inst_srlv
                             |inst_sub|inst_subu|inst_slt|inst_sltu|inst_slti|inst_sltiu
                             |inst_and|inst_andi|inst_nor|inst_or|inst_xor|inst_xori
                             |inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw
                             |inst_mthi|inst_mtlo
                             |inst_mult|inst_multu|inst_div|inst_divu
                             |inst_lsa;
    

    assign sel_alu_src1[1] = 1'b0|inst_bgezal|inst_bltzal|inst_jal|inst_jalr;
    

    assign sel_alu_src1[2] = 1'b0|inst_sll|inst_srl|inst_sra;
    

    assign sel_alu_src2[0] = 1'b0|inst_sub|inst_subu|inst_slt|inst_sltu|inst_and|inst_srav|inst_srlv
                                  |inst_nor|inst_or|inst_xor|inst_sll|inst_srl|inst_sra|inst_addu|inst_add|inst_sllv
                                  |inst_mult|inst_multu|inst_div|inst_divu
                                  |inst_lsa;
    

    assign sel_alu_src2[1] = 1'b0|inst_lui|inst_addiu|inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw|inst_slti|inst_sltiu|inst_addi;


    assign sel_alu_src2[2] = 1'b0|inst_bgezal|inst_bltzal|inst_jal|inst_jalr;


    assign sel_alu_src2[3] = 1'b0|inst_ori|inst_andi|inst_xori;

    

    assign op_add = inst_addiu|inst_addu|inst_add|inst_addi
                              |inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw
                              |inst_bgezal|inst_bltzal|inst_jal|inst_jalr
                              |inst_mthi|inst_mtlo
                              |inst_lsa;
    assign op_sub = inst_sub |inst_subu;
    assign op_slt = inst_slt|inst_slti;
    assign op_sltu = inst_sltu|inst_sltiu;
    assign op_and = inst_and|inst_andi;
    assign op_nor = inst_nor;
    assign op_or = inst_ori|inst_or;
    assign op_xor = inst_xor|inst_xori;
    assign op_sll = inst_sll|inst_sllv;
    assign op_srl = inst_srl|inst_srlv;
    assign op_sra = inst_sra|inst_srav;
    assign op_lui = inst_lui;

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




    assign data_ram_en = inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_sb|inst_sh|inst_sw;


    assign data_ram_wen = inst_sb?4'b0001:
                           inst_sh?4'b0011:
                           inst_sw?4'b1111:
                           inst_lb|inst_lbu|inst_lh|inst_lhu|inst_lw?4'b0000:4'b1110;

    

    assign rf_we = inst_ori |inst_lui|inst_sub|inst_subu|inst_srav|inst_srlv
                             |inst_and|inst_andi|inst_nor|inst_or|inst_xor|inst_xori
                             |inst_add|inst_addi|inst_addiu|inst_addu|inst_sllv
                             |inst_slt|inst_slti|inst_sltiu|inst_sltu|inst_sll|inst_srl|inst_sra
                             |inst_bgezal|inst_bltzal|inst_jal|inst_jalr
                             |inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu
                             |inst_mfhi|inst_mflo
                             |inst_lsa;

    assign hl_we = inst_mthi|inst_mtlo
                   |inst_mult|inst_multu|inst_div|inst_divu;
    
    

    assign sel_rf_dst[0] = 1'b0|inst_sub|inst_subu|inst_addu|inst_and|inst_sllv|inst_srav|inst_srlv
                               |inst_nor|inst_or|inst_xor|inst_slt|inst_sltu|inst_sll|inst_srl|inst_sra|inst_add|inst_jalr
                               |inst_mfhi|inst_mflo
                               |inst_lsa;

    assign sel_rf_dst[1] = inst_ori|inst_lui|inst_addiu|inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu|inst_slti|inst_sltiu|inst_sltiu|inst_addi|inst_andi|inst_xori;

    assign sel_rf_dst[2] = 1'b0|inst_bgezal|inst_bltzal|inst_jal;


    assign rf_waddr = {5{sel_rf_dst[0]}} & rd 
                    | {5{sel_rf_dst[1]}} & rt
                    | {5{sel_rf_dst[2]}} & 32'd31;
    
    assign hl_waddr[0] = inst_mult|inst_multu|inst_div|inst_divu;
    assign hl_waddr[1] = inst_mtlo ? 1'b1:1'b0;
    
    

    assign sel_rf_res = 1'b0|inst_lw|inst_lb|inst_lbu|inst_lh|inst_lhu;
    
 
 
 
    assign id_to_ex_bus = {
        p_data,
        hl_waddr,
        hl_we,
        id_pc,
        inst,
        alu_op,
        sel_alu_src1,
        sel_alu_src2,
        data_ram_en,
        data_ram_wen,
        rf_we,
        rf_waddr,
        sel_rf_res,
        data1,
        data2
    };


    wire br_e;
    wire [31:0] br_addr;
    wire rs_eq_rt;
    wire rs_neq_rt;
    wire rs_ge_z;
    wire rs_gt_z;
    wire rs_le_z;
    wire rs_lt_z;
    wire [31:0] pc_plus_4;
    assign pc_plus_4 = id_pc + 32'h4;
    
    assign rs_eq_rt =   (data1 == data2);
    assign rs_neq_rt=   (data1!=data2);
    assign rs_ge_z=     (data1 == 32'b0)||(~data1[31]);
    assign rs_gt_z=     (~data1[31])&&(data1 != 32'b0);
    assign rs_le_z=     (data1 == 32'b0)||(data1[31]);
    assign rs_lt_z=     (data1[31]);
    

    assign br_e = inst_j|inst_jr|inst_jal|inst_jalr
                        |(inst_beq&rs_eq_rt)|(inst_bne&rs_neq_rt)
                        |(inst_bgez&rs_ge_z)|(inst_bgtz&rs_gt_z)
                        |(inst_blez&rs_le_z)|(inst_bltz&rs_lt_z)
                        |(inst_bgezal&rs_ge_z)|(inst_bltzal&rs_lt_z);
    assign br_addr =(inst_j|inst_jal)?{pc_plus_4[31:28],instr_index,2'b0}:
                    ((inst_jr|inst_jalr)?data1:
                    (inst_beq|inst_bne|inst_bgez|inst_bgtz|inst_blez|inst_bltz|inst_bgezal|inst_bltzal)?(pc_plus_4 + {{14{offset[15]}},offset,2'b0}):32'b0 );



    assign br_bus = {
        br_e,
        br_addr
    };
    
    
endmodule