data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v
1: b"%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:101: Found definition of 'state' as a CELL but expected a variable\n        active = pc != 0 || state != STATE_FETCH;\n                            ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:101: Can't find definition of variable: 'STATE_FETCH'\n        active = pc != 0 || state != STATE_FETCH;\n                                     ^~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:104: Found definition of 'state' as a CELL but expected a variable\n        effective_ir = (state == STATE_EXECUTE && !waitrequest_prev) \n                        ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:104: Can't find definition of variable: 'STATE_EXECUTE'\n        effective_ir = (state == STATE_EXECUTE && !waitrequest_prev) \n                                 ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:107: Can't find definition of variable: 'OPCODE_RTYPE'\n        if(opcode == OPCODE_RTYPE) begin \n                     ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:108: Can't find definition of variable: 'FUNCT_SLL'\n            immediate_shift = rtype_fncode == FUNCT_SLL || \n                                              ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:109: Can't find definition of variable: 'FUNCT_SRL'\n                                                                   : ... Suggested alternative: 'FUNCT_SLL'\n                              rtype_fncode == FUNCT_SRL || \n                                              ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:110: Can't find definition of variable: 'FUNCT_SRA'\n                                                                   : ... Suggested alternative: 'FUNCT_SRL'\n                              rtype_fncode == FUNCT_SRA;\n                                              ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:112: Can't find definition of variable: 'RTYPE'\n            instr_type = RTYPE;\n                         ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:119: Can't find definition of variable: 'FUNCT_MFH'\n                                                                   : ... Suggested alternative: 'FUNCT_SLL'\n                FUNCT_MFH : begin\n                ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:121: Found definition of 'state' as a CELL but expected a variable\n                    reg_file_write = state == STATE_EXECUTE;\n                                     ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:123: Can't find definition of variable: 'FUNCT_MFL'\n                                                                   : ... Suggested alternative: 'FUNCT_MFH'\n                FUNCT_MFL : begin\n                ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:125: Found definition of 'state' as a CELL but expected a variable\n                    reg_file_write = state == STATE_EXECUTE;\n                                     ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:127: Can't find definition of variable: 'FUNCT_MULT'\n                                                                   : ... Suggested alternative: 'FUNCT_MFL'\n                FUNCT_MULT : begin\n                ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:130: Can't find definition of variable: 'FUNCT_MULTU'\n                                                                   : ... Suggested alternative: 'FUNCT_MULT'\n                FUNCT_MULTU : begin\n                ^~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:133: Can't find definition of variable: 'FUNCT_DIV'\n                                                                   : ... Suggested alternative: 'FUNCT_MFH'\n                FUNCT_DIV : begin\n                ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:136: Can't find definition of variable: 'FUNCT_DIVU'\n                                                                   : ... Suggested alternative: 'FUNCT_DIV'\n                FUNCT_DIVU : begin\n                ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:141: Found definition of 'state' as a CELL but expected a variable\n                    reg_file_write = state == STATE_EXECUTE;\n                                     ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:145: Can't find definition of variable: 'OPCODE_J'\n        else if(opcode == OPCODE_J || opcode == OPCODE_JAL) begin\n                          ^~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:145: Can't find definition of variable: 'OPCODE_JAL'\n                                                                   : ... Suggested alternative: 'OPCODE_J'\n        else if(opcode == OPCODE_J || opcode == OPCODE_JAL) begin\n                                                ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:146: Can't find definition of variable: 'JTYPE'\n                                                                   : ... Suggested alternative: 'RTYPE'\n            instr_type = JTYPE;\n                         ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:149: Can't find definition of variable: 'ITYPE'\n                                                                   : ... Suggested alternative: 'JTYPE'\n            instr_type = ITYPE;\n                         ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:162: Found definition of 'state' as a CELL but expected a variable\n        case(state) \n             ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:173: Can't find definition of variable: 'OPCODE_SW'\n                                                                   : ... Suggested alternative: 'OPCODE_J'\n                if(opcode == OPCODE_SW) begin\n                             ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:178: Can't find definition of variable: 'OPCODE_SB'\n                                                                   : ... Suggested alternative: 'OPCODE_SW'\n                else if(opcode == OPCODE_SB || opcode == OPCODE_SH) begin\n                                  ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:178: Can't find definition of variable: 'OPCODE_SH'\n                                                                   : ... Suggested alternative: 'OPCODE_SB'\n                else if(opcode == OPCODE_SB || opcode == OPCODE_SH) begin\n                                                         ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:183: Can't find definition of variable: 'OPCODE_BEQ'\n                                                                   : ... Suggested alternative: 'OPCODE_J'\n                else if(opcode == OPCODE_BEQ || opcode == OPCODE_BGTZ || opcode == OPCODE_BLEZ || opcode == OPCODE_BNE) begin\n                                  ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:183: Can't find definition of variable: 'OPCODE_BGTZ'\n                                                                   : ... Suggested alternative: 'OPCODE_BEQ'\n                else if(opcode == OPCODE_BEQ || opcode == OPCODE_BGTZ || opcode == OPCODE_BLEZ || opcode == OPCODE_BNE) begin\n                                                          ^~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:183: Can't find definition of variable: 'OPCODE_BLEZ'\n                                                                   : ... Suggested alternative: 'OPCODE_BEQ'\n                else if(opcode == OPCODE_BEQ || opcode == OPCODE_BGTZ || opcode == OPCODE_BLEZ || opcode == OPCODE_BNE) begin\n                                                                                   ^~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:183: Can't find definition of variable: 'OPCODE_BNE'\n                                                                   : ... Suggested alternative: 'OPCODE_BEQ'\n                else if(opcode == OPCODE_BEQ || opcode == OPCODE_BGTZ || opcode == OPCODE_BLEZ || opcode == OPCODE_BNE) begin\n                                                                                                            ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:188: Can't find definition of variable: 'OPCODE_REGIMM'\n                                                                   : ... Suggested alternative: 'OPCODE_BEQ'\n                else if(opcode == OPCODE_REGIMM) begin\n                                  ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:198: Can't find definition of variable: 'OPCODE_LW'\n                                                                   : ... Suggested alternative: 'OPCODE_SW'\n                else if(opcode == OPCODE_LW || opcode == OPCODE_LBU || opcode == OPCODE_LB || \n                                  ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:198: Can't find definition of variable: 'OPCODE_LBU'\n                                                                   : ... Suggested alternative: 'OPCODE_LW'\n                else if(opcode == OPCODE_LW || opcode == OPCODE_LBU || opcode == OPCODE_LB || \n                                                         ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:198: Can't find definition of variable: 'OPCODE_LB'\n                                                                   : ... Suggested alternative: 'OPCODE_LBU'\n                else if(opcode == OPCODE_LW || opcode == OPCODE_LBU || opcode == OPCODE_LB || \n                                                                                 ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:199: Can't find definition of variable: 'OPCODE_LHU'\n                                                                   : ... Suggested alternative: 'OPCODE_LBU'\n                        opcode == OPCODE_LHU || opcode == OPCODE_LH || \n                                  ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:199: Can't find definition of variable: 'OPCODE_LH'\n                                                                   : ... Suggested alternative: 'OPCODE_LB'\n                        opcode == OPCODE_LHU || opcode == OPCODE_LH || \n                                                          ^~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:200: Can't find definition of variable: 'OPCODE_LWL'\n                                                                   : ... Suggested alternative: 'OPCODE_LW'\n                        opcode == OPCODE_LWL || opcode == OPCODE_LWR) begin      \n                                  ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:200: Can't find definition of variable: 'OPCODE_LWR'\n                                                                   : ... Suggested alternative: 'OPCODE_LW'\n                        opcode == OPCODE_LWL || opcode == OPCODE_LWR) begin      \n                                                          ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:207: Can't find definition of variable: 'OPCODE_LUI'\n                                                                   : ... Suggested alternative: 'OPCODE_LB'\n                else if(opcode == OPCODE_LUI) begin\n                                  ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:226: Can't find definition of variable: 'FUNCT_JALR'\n                                                                   : ... Suggested alternative: 'FUNCT_MFL'\n                    else if(rtype_fncode == FUNCT_JALR) begin\n                                            ^~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:254: Can't find definition of variable: 'STATE_MEMORY'\n            STATE_MEMORY : begin\n            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:284: Found definition of 'state' as a CELL but expected a variable\n            state <= STATE_FETCH;\n            ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:286: Can't find definition of variable: 'BRANCH_NONE'\n            branch_delayed <= BRANCH_NONE;\n                              ^~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:286: Found definition of 'branch_delayed' as a CELL but expected a variable\n            branch_delayed <= BRANCH_NONE;\n            ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:291: Found definition of 'state' as a CELL but expected a variable\n            case(state)  \n                 ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:299: Found definition of 'state' as a CELL but expected a variable\n                        state <= STATE_EXECUTE;\n                        ^~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:316: Can't find definition of variable: 'FUNCT_JR'\n                                                                   : ... Suggested alternative: 'FUNCT_JALR'\n                            else if((rtype_fncode == FUNCT_JR || rtype_fncode == FUNCT_JALR) && branch_delayed == BRANCH_NONE) begin\n                                                     ^~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:316: Found definition of 'branch_delayed' as a CELL but expected a variable\n                            else if((rtype_fncode == FUNCT_JR || rtype_fncode == FUNCT_JALR) && branch_delayed == BRANCH_NONE) begin\n                                                                                                ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:318: Can't find definition of variable: 'BRANCH_DELAYED'\n                                branch_delayed <= BRANCH_DELAYED;\n                                                  ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/429782749/rtl/mips_cpu_bus.v:318: Found definition of 'branch_delayed' as a CELL but expected a variable\n                                branch_delayed <= BRANCH_DELAYED;\n                                ^~~~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n"
module mips_cpu_bus(

    input logic clk,
    input logic reset,
    output logic active,
    output logic[31:0] register_v0,


    output logic[31:0] address,
    output logic write,
    output logic read,
    input logic waitrequest,
    output logic[31:0] writedata,
    output logic[3:0] byteenable,
    input logic[31:0] readdata
);
    logic[31:0] address_unaligned;
    assign address = {address_unaligned[31:2], 2'b00};


    logic[31:0] readdata_eb;
    logic[31:0] writedata_eb;


    logic[31: 0] pc, pc_branch;
    logic[31:0] jjal_addr;
    assign jjal_addr = {pc[31:28], jtype_address, 2'b00};
    
    branch_delay_state_t branch_delayed;

    logic[31: 0] ir, effective_ir;
    state_t state;


    logic[31:0] hi, lo;


    logic[31:0] rs_val, rt_val;


    logic reg_file_write;
    logic[31:0] reg_file_data_in;
    logic[4:0] reg_file_rs;
    logic[4:0] reg_file_rt;
    logic[4:0] reg_file_rd;


    logic[31:0] alu_out, alu_out2;
    logic[5:0] alu_fncode;
    logic[31:0] alu_a;
    logic[31:0] alu_b;


    logic[2:0] instr_type;
    logic[5:0] opcode;


    logic[4:0] rtype_rs;
    logic[4:0] rtype_rt;
    logic[4:0] rtype_rd;
    logic[4:0] rtype_shamnt;
    logic[31:0] extended_shamnt;
    logic immediate_shift;
    logic[5:0] rtype_fncode;
    


    logic[4:0] itype_rs;
    logic[4:0] itype_rt;
    logic[31:0] itype_immediate;
    logic[31:0] loadstore_word;
    logic[3:0] bytes_byteenable;


    logic[25:0] jtype_address;

    logic waitrequest_prev;

    assign opcode = effective_ir[31:26];


    assign rtype_rs        = effective_ir[25:21];
    assign rtype_rt        = effective_ir[20:16];
    assign rtype_rd        = effective_ir[15:11];
    assign rtype_shamnt    = effective_ir[10:6];
    assign extended_shamnt = {27'b0, rtype_shamnt};
    assign rtype_fncode    = effective_ir[5:0];


    assign itype_rs     = effective_ir[25:21];
    assign itype_rt     = effective_ir[20:16];


    assign jtype_address = effective_ir[25:0];


    always_comb begin
        

        active = pc != 0 || state != STATE_FETCH;


        effective_ir = (state == STATE_EXECUTE && !waitrequest_prev) 
                       ? readdata_eb : ir;

        if(opcode == OPCODE_RTYPE) begin 
            immediate_shift = rtype_fncode == FUNCT_SLL || 
                              rtype_fncode == FUNCT_SRL || 
                              rtype_fncode == FUNCT_SRA;

            instr_type = RTYPE;
            reg_file_rs = rtype_rs;
            reg_file_rt = rtype_rt;
            reg_file_rd = rtype_rd;
            alu_a = immediate_shift ? extended_shamnt : rs_val;
            alu_b = rt_val;
            case(rtype_fncode)
                FUNCT_MFH : begin
                    reg_file_data_in = hi;
                    reg_file_write = state == STATE_EXECUTE;
                end
                FUNCT_MFL : begin
                    reg_file_data_in = lo;
                    reg_file_write = state == STATE_EXECUTE;
                end
                FUNCT_MULT : begin
                    reg_file_write = 0;
                end
                FUNCT_MULTU : begin
                    reg_file_write = 0;
                end
                FUNCT_DIV : begin
                    reg_file_write = 0;
                end
                FUNCT_DIVU : begin
                    reg_file_write = 0;
                end
                default   : begin
                    reg_file_data_in = alu_out; 
                    reg_file_write = state == STATE_EXECUTE;
                end
            endcase
        end
        else if(opcode == OPCODE_J || opcode == OPCODE_JAL) begin
            instr_type = JTYPE;
        end
        else begin
            instr_type = ITYPE;
            reg_file_rs = itype_rs;
            reg_file_rt = itype_rt;
            reg_file_rd = itype_rt;

            if(reg_file_rt == 5'b10001 ||  reg_file_rt == 5'b10000) begin
                reg_file_rd = 31;
            end

            alu_a = rs_val;
            alu_b = itype_immediate;
        end

        case(state) 
            STATE_FETCH: begin
                
                reg_file_write = 0;
                read = 1;
                write = 0;
                address_unaligned = pc;
                byteenable = 4'b1111;
            end
            STATE_EXECUTE : begin

                if(opcode == OPCODE_SW) begin
                    write = 0; 
                    read = 0;
                    reg_file_write = 0;
                end
                else if(opcode == OPCODE_SB || opcode == OPCODE_SH) begin
                    write = 0;
                    read = 0;
                    reg_file_write = 0;
                end
                else if(opcode == OPCODE_BEQ || opcode == OPCODE_BGTZ || opcode == OPCODE_BLEZ || opcode == OPCODE_BNE) begin
                    alu_a = itype_immediate;
                    alu_b = pc;
                end

                else if(opcode == OPCODE_REGIMM) begin
                    alu_a = itype_immediate;
                    alu_b = pc;
                    if(reg_file_rt == 5'b10001 || reg_file_rt == 5'b10000) begin
                        reg_file_write = 1;
                        reg_file_data_in = pc+4;
                    end

                end

                else if(opcode == OPCODE_LW || opcode == OPCODE_LBU || opcode == OPCODE_LB || 
                        opcode == OPCODE_LHU || opcode == OPCODE_LH || 
                        opcode == OPCODE_LWL || opcode == OPCODE_LWR) begin
                    write = 0;
                    read = 1;
                    address_unaligned = alu_out;
                    reg_file_write = 0;
                    byteenable = bytes_byteenable;
                end
                else if(opcode == OPCODE_LUI) begin
                    write = 0;
                    read = 0;
                    reg_file_data_in = itype_immediate;
                    reg_file_write = 1;
                end
                else if(opcode == OPCODE_RTYPE) begin
                    if(rtype_fncode == FUNCT_MFH) begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = hi;
                    end
                    else if (rtype_fncode == FUNCT_MFL) begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = lo;
                    end
                    else if(rtype_fncode == FUNCT_JALR) begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = pc + 4;
                    end
                    else begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = alu_out;
                    end
                end
                else if(opcode == OPCODE_JAL) begin
                    reg_file_data_in = pc + 4;
                    reg_file_write = 1;
                    reg_file_rd = 31;
                    write = 0;
                    read = 0;
                end
                else begin
                    write = 0;  
                    read = 0;
                    reg_file_write = 1;
                    reg_file_data_in = alu_out;
                end

            end
            STATE_MEMORY : begin
                reg_file_write = 1;
                if(opcode == OPCODE_SW || 
                   opcode == OPCODE_SB || 
                   opcode == OPCODE_SH) begin
                    write = 1;
                    read = 0;
                    address_unaligned = alu_out;
                    reg_file_write = 0;
                    writedata_eb = loadstore_word;
                    byteenable = bytes_byteenable;
                end
                else begin
                    write = 0;
                    read = 1;
                    reg_file_data_in = loadstore_word;
                    address_unaligned = alu_out;
                    reg_file_write = 1;
                    byteenable = bytes_byteenable;
                end
            end
        endcase

    end

    always_ff @(posedge clk) begin
        waitrequest_prev <= waitrequest;
       
        if(reset) begin
            pc <= 32'hBFC0_0000;
            state <= STATE_FETCH;
            pc_branch <= 0;
            branch_delayed <= BRANCH_NONE;
            lo <= 0;
            hi <= 0;
        end
        else if(active) begin
            case(state)  
                STATE_FETCH : begin


                    if(!waitrequest) begin
                        pc <= pc + 4;
                        state <= STATE_EXECUTE;
                    end

                end
                STATE_EXECUTE : begin
                    ir <= waitrequest_prev ? ir : readdata_eb;
                   
                    case(instr_type) 
                        RTYPE : begin
                            if( rtype_fncode == FUNCT_MULT  ||
                                rtype_fncode == FUNCT_DIV   ||
                                rtype_fncode == FUNCT_MULTU ||
                                rtype_fncode == FUNCT_DIVU
                            ) begin
                                lo <= alu_out;
                                hi <= alu_out2;
                            end
                            else if((rtype_fncode == FUNCT_JR || rtype_fncode == FUNCT_JALR) && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= rs_val;
                                branch_delayed <= BRANCH_DELAYED;
                            end
                            state <= STATE_FETCH;
                        end 
                        ITYPE : begin

                            if( (opcode == OPCODE_BEQ && rs_val == rt_val) && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;
                            end

                            else if(opcode == OPCODE_BNE && rs_val != rt_val && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;
                            end

                            else if(opcode == OPCODE_REGIMM) begin
                                if( (reg_file_rt == 5'b00001 || reg_file_rt == 5'b10001) && ($signed(rs_val) >= 0 && branch_delayed == BRANCH_NONE) ) begin
                                    pc_branch <= alu_out;
                                    branch_delayed <= BRANCH_DELAYED;
                                    
                                end
                    
                                else if( (reg_file_rt == 5'b0 || reg_file_rt == 5'b10000) && ($signed(rs_val) < 0 && branch_delayed == BRANCH_NONE) ) begin
                                    pc_branch <= alu_out;
                                    branch_delayed <= BRANCH_DELAYED;
                                end 
                                
                                state <= STATE_FETCH;
                            end
                            else if(opcode == OPCODE_BGTZ && $signed(rs_val) > 0 && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;

                            end

                            else if(opcode == OPCODE_BLEZ && $signed(rs_val) <= 0 && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;
                            end


                            else if( opcode == OPCODE_LW || opcode == OPCODE_LBU || 
                                opcode == OPCODE_LB || opcode == OPCODE_LH || 
                                opcode == OPCODE_LHU || opcode == OPCODE_LWL || 
                                opcode == OPCODE_LWR ) begin
                                
                                if(!waitrequest) begin
                                    state <= STATE_MEMORY;
                                end 
                            end
                            else if(opcode == OPCODE_SW || opcode == OPCODE_SB || opcode == OPCODE_SH) begin
                                if(!waitrequest) begin 
                                    state <= STATE_MEMORY;
                                end
                            end 
                            else begin
                                state <= STATE_FETCH;
                            end

                        end 
                        JTYPE : begin
                            if(branch_delayed == BRANCH_NONE) begin
                                pc_branch <= jjal_addr;
                                branch_delayed <= BRANCH_DELAYED;
                            end
                        end 
                        default : ;
                    endcase

                    if(branch_delayed == BRANCH_DELAYED) begin
                        pc <= pc_branch;
                        branch_delayed <= BRANCH_NONE;
                    end
                    
                end
                STATE_MEMORY : begin
                    state <= STATE_FETCH;
                end

                default : ;
            endcase
        end
    end

    alu_ctrl alu_ctrl(.opcode(opcode),
                      .rtype_fncode(rtype_fncode),
                      .fncode(alu_fncode)
    );

    reg_file reg_file(.clk(clk), 
                      .reset(reset), 
                      .addr_a(reg_file_rs),
                      .addr_b(reg_file_rt),
                      .write_addr(reg_file_rd),
                      .write(reg_file_write),
                      .data_in(reg_file_data_in),
                      .a(rs_val),
                      .b(rt_val),
                      .register_v0(register_v0)
    );

    alu alu(.a(alu_a),
            .b(alu_b),
            .fncode(alu_fncode), 
            .r(alu_out),
            .o(alu_out2));

    toggle_endianness to_big(.a(readdata), .r(readdata_eb));
    toggle_endianness to_little(.a(writedata_eb), .r(writedata));

    sign_extension sign_extension(
        .itype_immediate(effective_ir[15:0]),
        .opcode(opcode),
        .signed_itype_immediate(itype_immediate)
    );

    bytes_control bytes_control(
        .readdata_eb(readdata_eb),
        .opcode(opcode),
        .lsb_bits(address_unaligned[1:0]),
        .bytes_out(loadstore_word),
        .rt_val_itype(rt_val),
        .byteenable(bytes_byteenable)
    );

endmodule
module mips_cpu_bus(

    input logic clk,
    input logic reset,
    output logic active,
    output logic[31:0] register_v0,


    output logic[31:0] address,
    output logic write,
    output logic read,
    input logic waitrequest,
    output logic[31:0] writedata,
    output logic[3:0] byteenable,
    input logic[31:0] readdata
);

    logic[31:0] address_unaligned;
    assign address = {address_unaligned[31:2], 2'b00};


    logic[31:0] readdata_eb;
    logic[31:0] writedata_eb;


    logic[31: 0] pc, pc_branch;
    logic[31:0] jjal_addr;
    assign jjal_addr = {pc[31:28], jtype_address, 2'b00};
    
    branch_delay_state_t branch_delayed;

    logic[31: 0] ir, effective_ir;
    state_t state;


    logic[31:0] hi, lo;


    logic[31:0] rs_val, rt_val;


    logic reg_file_write;
    logic[31:0] reg_file_data_in;
    logic[4:0] reg_file_rs;
    logic[4:0] reg_file_rt;
    logic[4:0] reg_file_rd;


    logic[31:0] alu_out, alu_out2;
    logic[5:0] alu_fncode;
    logic[31:0] alu_a;
    logic[31:0] alu_b;


    logic[2:0] instr_type;
    logic[5:0] opcode;


    logic[4:0] rtype_rs;
    logic[4:0] rtype_rt;
    logic[4:0] rtype_rd;
    logic[4:0] rtype_shamnt;
    logic[31:0] extended_shamnt;
    logic immediate_shift;
    logic[5:0] rtype_fncode;
    


    logic[4:0] itype_rs;
    logic[4:0] itype_rt;
    logic[31:0] itype_immediate;
    logic[31:0] loadstore_word;
    logic[3:0] bytes_byteenable;


    logic[25:0] jtype_address;

    logic waitrequest_prev;

    assign opcode = effective_ir[31:26];


    assign rtype_rs        = effective_ir[25:21];
    assign rtype_rt        = effective_ir[20:16];
    assign rtype_rd        = effective_ir[15:11];
    assign rtype_shamnt    = effective_ir[10:6];
    assign extended_shamnt = {27'b0, rtype_shamnt};
    assign rtype_fncode    = effective_ir[5:0];


    assign itype_rs     = effective_ir[25:21];
    assign itype_rt     = effective_ir[20:16];


    assign jtype_address = effective_ir[25:0];


    always_comb begin
        

        active = pc != 0 || state != STATE_FETCH;


        effective_ir = (state == STATE_EXECUTE && !waitrequest_prev) 
                       ? readdata_eb : ir;

        if(opcode == OPCODE_RTYPE) begin 
            immediate_shift = rtype_fncode == FUNCT_SLL || 
                              rtype_fncode == FUNCT_SRL || 
                              rtype_fncode == FUNCT_SRA;

            instr_type = RTYPE;
            reg_file_rs = rtype_rs;
            reg_file_rt = rtype_rt;
            reg_file_rd = rtype_rd;
            alu_a = immediate_shift ? extended_shamnt : rs_val;
            alu_b = rt_val;
            case(rtype_fncode)
                FUNCT_MFH : begin
                    reg_file_data_in = hi;
                    reg_file_write = state == STATE_EXECUTE;
                end
                FUNCT_MFL : begin
                    reg_file_data_in = lo;
                    reg_file_write = state == STATE_EXECUTE;
                end
                FUNCT_MULT : begin
                    reg_file_write = 0;
                end
                FUNCT_MULTU : begin
                    reg_file_write = 0;
                end
                FUNCT_DIV : begin
                    reg_file_write = 0;
                end
                FUNCT_DIVU : begin
                    reg_file_write = 0;
                end
                default   : begin
                    reg_file_data_in = alu_out; 
                    reg_file_write = state == STATE_EXECUTE;
                end
            endcase
        end
        else if(opcode == OPCODE_J || opcode == OPCODE_JAL) begin
            instr_type = JTYPE;
        end
        else begin
            instr_type = ITYPE;
            reg_file_rs = itype_rs;
            reg_file_rt = itype_rt;
            reg_file_rd = itype_rt;

            if(reg_file_rt == 5'b10001 ||  reg_file_rt == 5'b10000) begin
                reg_file_rd = 31;
            end

            alu_a = rs_val;
            alu_b = itype_immediate;
        end

        case(state) 
            STATE_FETCH: begin
                
                reg_file_write = 0;
                read = 1;
                write = 0;
                address_unaligned = pc;
                byteenable = 4'b1111;
            end
            STATE_EXECUTE : begin

                if(opcode == OPCODE_SW) begin
                    write = 0; 
                    read = 0;
                    reg_file_write = 0;
                end
                else if(opcode == OPCODE_SB || opcode == OPCODE_SH) begin
                    write = 0;
                    read = 0;
                    reg_file_write = 0;
                end
                else if(opcode == OPCODE_BEQ || opcode == OPCODE_BGTZ || opcode == OPCODE_BLEZ || opcode == OPCODE_BNE) begin
                    alu_a = itype_immediate;
                    alu_b = pc;
                end

                else if(opcode == OPCODE_REGIMM) begin
                    alu_a = itype_immediate;
                    alu_b = pc;
                    if(reg_file_rt == 5'b10001 || reg_file_rt == 5'b10000) begin
                        reg_file_write = 1;
                        reg_file_data_in = pc+4;
                    end

                end

                else if(opcode == OPCODE_LW || opcode == OPCODE_LBU || opcode == OPCODE_LB || 
                        opcode == OPCODE_LHU || opcode == OPCODE_LH || 
                        opcode == OPCODE_LWL || opcode == OPCODE_LWR) begin
                    write = 0;
                    read = 1;
                    address_unaligned = alu_out;
                    reg_file_write = 0;
                    byteenable = bytes_byteenable;
                end
                else if(opcode == OPCODE_LUI) begin
                    write = 0;
                    read = 0;
                    reg_file_data_in = itype_immediate;
                    reg_file_write = 1;
                end
                else if(opcode == OPCODE_RTYPE) begin
                    if(rtype_fncode == FUNCT_MFH) begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = hi;
                    end
                    else if (rtype_fncode == FUNCT_MFL) begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = lo;
                    end
                    else if(rtype_fncode == FUNCT_JALR) begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = pc + 4;
                    end
                    else begin
                        write = 0;  
                        read = 0;
                        reg_file_write = 1;
                        reg_file_data_in = alu_out;
                    end
                end
                else if(opcode == OPCODE_JAL) begin
                    reg_file_data_in = pc + 4;
                    reg_file_write = 1;
                    reg_file_rd = 31;
                    write = 0;
                    read = 0;
                end
                else begin
                    write = 0;  
                    read = 0;
                    reg_file_write = 1;
                    reg_file_data_in = alu_out;
                end

            end
            STATE_MEMORY : begin
                reg_file_write = 1;
                if(opcode == OPCODE_SW || 
                   opcode == OPCODE_SB || 
                   opcode == OPCODE_SH) begin
                    write = 1;
                    read = 0;
                    address_unaligned = alu_out;
                    reg_file_write = 0;
                    writedata_eb = loadstore_word;
                    byteenable = bytes_byteenable;
                end
                else begin
                    write = 0;
                    read = 1;
                    reg_file_data_in = loadstore_word;
                    address_unaligned = alu_out;
                    reg_file_write = 1;
                    byteenable = bytes_byteenable;
                end
            end
        endcase

    end

    always_ff @(posedge clk) begin
        waitrequest_prev <= waitrequest;
       
        if(reset) begin
            pc <= 32'hBFC0_0000;
            state <= STATE_FETCH;
            pc_branch <= 0;
            branch_delayed <= BRANCH_NONE;
            lo <= 0;
            hi <= 0;
        end
        else if(active) begin
            case(state)  
                STATE_FETCH : begin


                    if(!waitrequest) begin
                        pc <= pc + 4;
                        state <= STATE_EXECUTE;
                    end

                end
                STATE_EXECUTE : begin
                    ir <= waitrequest_prev ? ir : readdata_eb;
                   
                    case(instr_type) 
                        RTYPE : begin
                            if( rtype_fncode == FUNCT_MULT  ||
                                rtype_fncode == FUNCT_DIV   ||
                                rtype_fncode == FUNCT_MULTU ||
                                rtype_fncode == FUNCT_DIVU
                            ) begin
                                lo <= alu_out;
                                hi <= alu_out2;
                            end
                            else if((rtype_fncode == FUNCT_JR || rtype_fncode == FUNCT_JALR) && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= rs_val;
                                branch_delayed <= BRANCH_DELAYED;
                            end
                            state <= STATE_FETCH;
                        end 
                        ITYPE : begin

                            if( (opcode == OPCODE_BEQ && rs_val == rt_val) && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;
                            end

                            else if(opcode == OPCODE_BNE && rs_val != rt_val && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;
                            end

                            else if(opcode == OPCODE_REGIMM) begin
                                if( (reg_file_rt == 5'b00001 || reg_file_rt == 5'b10001) && ($signed(rs_val) >= 0 && branch_delayed == BRANCH_NONE) ) begin
                                    pc_branch <= alu_out;
                                    branch_delayed <= BRANCH_DELAYED;
                                    
                                end
                    
                                else if( (reg_file_rt == 5'b0 || reg_file_rt == 5'b10000) && ($signed(rs_val) < 0 && branch_delayed == BRANCH_NONE) ) begin
                                    pc_branch <= alu_out;
                                    branch_delayed <= BRANCH_DELAYED;
                                end 
                                
                                state <= STATE_FETCH;
                            end
                            else if(opcode == OPCODE_BGTZ && $signed(rs_val) > 0 && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;

                            end

                            else if(opcode == OPCODE_BLEZ && $signed(rs_val) <= 0 && branch_delayed == BRANCH_NONE) begin
                                pc_branch <= alu_out;
                                branch_delayed <= BRANCH_DELAYED;
                                state <= STATE_FETCH;
                            end


                            else if( opcode == OPCODE_LW || opcode == OPCODE_LBU || 
                                opcode == OPCODE_LB || opcode == OPCODE_LH || 
                                opcode == OPCODE_LHU || opcode == OPCODE_LWL || 
                                opcode == OPCODE_LWR ) begin
                                
                                if(!waitrequest) begin
                                    state <= STATE_MEMORY;
                                end 
                            end
                            else if(opcode == OPCODE_SW || opcode == OPCODE_SB || opcode == OPCODE_SH) begin
                                if(!waitrequest) begin 
                                    state <= STATE_MEMORY;
                                end
                            end 
                            else begin
                                state <= STATE_FETCH;
                            end

                        end 
                        JTYPE : begin
                            if(branch_delayed == BRANCH_NONE) begin
                                pc_branch <= jjal_addr;
                                branch_delayed <= BRANCH_DELAYED;
                            end
                        end 
                        default : ;
                    endcase

                    if(branch_delayed == BRANCH_DELAYED) begin
                        pc <= pc_branch;
                        branch_delayed <= BRANCH_NONE;
                    end
                    
                end
                STATE_MEMORY : begin
                    state <= STATE_FETCH;
                end

                default : ;
            endcase
        end
    end

    alu_ctrl alu_ctrl(.opcode(opcode),
                      .rtype_fncode(rtype_fncode),
                      .fncode(alu_fncode)
    );

    reg_file reg_file(.clk(clk), 
                      .reset(reset), 
                      .addr_a(reg_file_rs),
                      .addr_b(reg_file_rt),
                      .write_addr(reg_file_rd),
                      .write(reg_file_write),
                      .data_in(reg_file_data_in),
                      .a(rs_val),
                      .b(rt_val),
                      .register_v0(register_v0)
    );

    alu alu(.a(alu_a),
            .b(alu_b),
            .fncode(alu_fncode), 
            .r(alu_out),
            .o(alu_out2));

    toggle_endianness to_big(.a(readdata), .r(readdata_eb));
    toggle_endianness to_little(.a(writedata_eb), .r(writedata));

    sign_extension sign_extension(
        .itype_immediate(effective_ir[15:0]),
        .opcode(opcode),
        .signed_itype_immediate(itype_immediate)
    );

    bytes_control bytes_control(
        .readdata_eb(readdata_eb),
        .opcode(opcode),
        .lsb_bits(address_unaligned[1:0]),
        .bytes_out(loadstore_word),
        .rt_val_itype(rt_val),
        .byteenable(bytes_byteenable)
    );

endmodule