data/full_repos/permissive/481307378/source_files/unalign_mem_access/dp_cu_for_unalign_mem_access/ctrl.v
data/verilator_xmls/dc177730-e9f8-4415-b7fd-f762bfe3a246.xml
module ctrl(

    input wire RES,
    input wire CLK,
    

    output reg pc_enable,


    input wire [6 : 0] opcode,
    input wire [2 : 0] funct3,
    

    output reg MODE,
    


    output reg instr_req,
    input wire instr_gnt,
    input wire instr_r_valid,
    

    output reg write_enable,
    

    output reg ALUSrcMux1,
    output reg ALUSrcMux2,
    output reg ALUSrcMux1_S,
    output reg ALUSrcMux2_S,
    

    output reg reg_pc_select,
    

    output reg alu_dm_select,
    

    output reg data_write_enable,
    output reg data_req,
    input wire data_gnt,
    input wire data_r_valid,
    

    input wire irq,
    input wire irq_status,
    output reg irq_ack,
    output reg irq_status_update,
    output reg irq_context,
    output reg irq_addr_sel,
    output reg bckup_reg,
    output reg mret_sel,
    output reg irq_pc_mode,
    

    input wire [1 : 0] n,
    output reg [3 : 0] data_be,
    output reg merge_reg_write_enable,
    output reg dm_addr_select,
    output reg alu_dm_unalign_select
);

    localparam [3:0]
        Ready = 4'b0000,
        instruction_fetch = 4'b0001,
        process_instruction = 4'b0010,
        wait_for_regset_write = 4'b0011,
        wait_for_data_read = 4'b0100,
        wait_for_data_write = 4'b0101,
        process_interrupt = 4'b0110,
        send_interrupt_acknowledge = 4'b0111,
        wait_for_regset_write_JI = 4'b1000,
        mem_second_read = 4'b1001,
        wait_for_second_mem_read = 4'b1010,
        mem_second_write = 4'b1011;
    
    reg [3:0] stateMoore_reg, stateMoore_next;

    always @(posedge CLK, posedge RES)
    begin
        if(RES == 1'b1)
        begin
            stateMoore_reg <= Ready;
        end
        else
        begin
            stateMoore_reg <= stateMoore_next;
        end
    end
    
    always @(stateMoore_reg, instr_gnt, instr_r_valid, opcode, data_gnt, data_r_valid, irq, irq_status, funct3, n)
    begin

        stateMoore_next = stateMoore_reg;
        

        pc_enable = 1'b0;
        MODE = 1'b0;
        
        instr_req = 1'b0;
        ALUSrcMux1 = 1'b0;
        ALUSrcMux1_S = 1'b0;
        ALUSrcMux2 = 1'b0;
        ALUSrcMux2_S = 1'b0;
        reg_pc_select = 1'b0;
        alu_dm_select = 1'b0;
        write_enable = 1'b0;
        

        data_write_enable = 1'b0;
        data_req = 1'b0;
        

        irq_status_update = 1'b0;
        irq_context = 1'b0;
        irq_ack = 1'b0;
        irq_addr_sel = 1'b0;
        bckup_reg = 1'b0;
        mret_sel = 1'b0;
        irq_pc_mode = 1'b0;
        

        data_be = 4'b0000;
        merge_reg_write_enable = 1'b1;
        dm_addr_select = 1'b1;
        alu_dm_unalign_select = 1'b1;
        
        casez(stateMoore_reg)
            Ready:
            begin
                instr_req = 1'b1;
                if(instr_gnt == 1'b1)
                begin
                    stateMoore_next = instruction_fetch;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            instruction_fetch:
            begin

                if(instr_r_valid == 1'b1)
                begin
                    stateMoore_next = process_instruction;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
                    
            process_instruction:
            begin
                    casez(opcode)
                    
                        7'b0110111:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            ALUSrcMux1_S = 1'b1;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b0010111:
                        begin
                            ALUSrcMux1 = 1'b1;
                            ALUSrcMux2 = 1'b1;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b0010011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b0110011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b0;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b1101111:
                        begin
                            ALUSrcMux1 = 1'b1;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux2_S = 1'b1;
                            write_enable = 1'b1;
                            reg_pc_select = 1'b0;
                              
                            MODE = 1'b1;
                            pc_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write_JI;
                        end
                        
                        7'b1100111:
                        begin
                            ALUSrcMux1 = 1'b1;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux2_S = 1'b1;
                            write_enable = 1'b1;
                            reg_pc_select = 1'b1; 
                            
                            MODE = 1'b1;
                            pc_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write_JI;
                        end
                        
                        7'b1100011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux2_S = 1'b0;
                            write_enable = 1'b0;
                            reg_pc_select = 1'b0;
                            
                            pc_enable = 1'b1;
                            MODE = 1'b1;
                            stateMoore_next = Ready;
                        end
                        
                        7'b0000011:
                        begin

                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            ALUSrcMux2_S = 1'b0;
                            write_enable = 1'b0;
                            reg_pc_select = 1'b0;
                            alu_dm_select = 1'b1;
                            MODE = 1'b0;
                            data_write_enable = 1'b0;
                            data_req = 1'b1;
                            

                            if(funct3 == 3'b010)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b1111;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b1110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if((funct3 == 3'b001) || (funct3 == 3'b101))
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0011;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if((funct3 == 3'b000) || (funct3 == 3'b100))
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0001;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0010;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b0100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            
                            if(data_gnt == 1'b1)
                            begin
                                stateMoore_next = wait_for_data_read;
                            end
                        end
                        
                        7'b0100011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            ALUSrcMux2_S = 1'b0;
                            write_enable = 1'b0;
                            reg_pc_select = 1'b0;
                            alu_dm_select = 1'b0;
                            MODE = 1'b0;
                            data_write_enable = 1'b1;
                            data_req = 1'b1;
                            instr_req = 1'b0;
                            

                            if(funct3 == 3'b010)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b1111;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b1110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if(funct3 == 3'b001)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0011;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if(funct3 == 3'b000)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0001;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0010;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b0100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            if(data_gnt == 1'b1)
                            begin
                                stateMoore_next = wait_for_data_write;
                            end
                        end
                        
                        7'b1110011:
                        begin
                            if (funct3 == 3'b000)
                            begin
                                pc_enable = 1'b1;
                                stateMoore_next = Ready;
                                ALUSrcMux1 = 1'b0;
                                ALUSrcMux2 = 1'b0;
                                ALUSrcMux1_S = 1'b0;
                                ALUSrcMux2_S = 1'b0;
                                reg_pc_select = 1'b0;
                                alu_dm_select = 1'b0;
                                write_enable = 1'b0;

                                irq_status_update = 1'b1;
                                irq_context = 1'b0;
                                irq_pc_mode = 1'b1;
                                irq_addr_sel = 1'b0;
                                bckup_reg = 1'b0;
                                mret_sel = 1'b1;
                            end
                            
                            if (funct3 == 3'b010)
                            begin
                                ALUSrcMux1 = 1'b0;
                                ALUSrcMux1_S = 1'b1;
                                ALUSrcMux2 = 1'b1;
                                ALUSrcMux2_S = 1'b0;
                                
                                write_enable = 1'b0;
                                reg_pc_select = 1'b0;
                                alu_dm_select = 1'b1;
                                MODE = 1'b0;
                                data_write_enable = 1'b0;
                                data_req = 1'b1;
                                if(data_gnt == 1'b1)
                                begin
                                    stateMoore_next = wait_for_data_read;
                                end
                            end
                        end
                        
                        default:
                        begin
                            stateMoore_next = Ready;
                            pc_enable = 1'b0;
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux1_S = 1'b0;
                            ALUSrcMux2_S = 1'b0;
                            reg_pc_select = 1'b0;
                            alu_dm_select = 1'b0;
                            write_enable = 1'b0;

                            irq_status_update = 1'b0;
                            irq_context = 1'b0;
                            irq_ack = 1'b0;
                            irq_addr_sel = 1'b0;
                            bckup_reg = 1'b0;
                            mret_sel = 1'b0;
                            irq_pc_mode = 1'b0;
                        end
                    endcase
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_regset_write:
            begin
                stateMoore_next = Ready;
                pc_enable = 1'b1;
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_regset_write_JI:
            begin
                stateMoore_next = Ready;
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_data_read:
            begin
                data_req = 1'b0;
                merge_reg_write_enable = 1'b1;
                if(data_r_valid == 1'b1)
                begin
                    write_enable = 1'b1;
                    alu_dm_select = 1'b1;
                    stateMoore_next = wait_for_regset_write;
                    

                    if( ( opcode == 7'b0000011 ) && 
                        ( ((funct3 == 3'b010) && ((n == 2'b01) || (n == 2'b10) || (n == 2'b11))) ||
                          ((funct3 == 3'b001) || (funct3 == 3'b101) && (n == 2'b11)) )
                        )
                    begin
                        write_enable = 1'b0;
                        alu_dm_select = 1'b0;
                        stateMoore_next = mem_second_read;
                    end
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            mem_second_read:
            begin
                dm_addr_select = 1'b1;
                
                ALUSrcMux1 = 1'b0;
                ALUSrcMux2 = 1'b1;
                ALUSrcMux2_S = 1'b0;
                data_req = 1'b1;

                if(funct3 == 3'b010)
                begin
                    casez (n)
                        2'b01:
                        begin
                            data_be = 4'b0001;
                        end
                        2'b10:
                        begin
                            data_be = 4'b0011;
                        end
                        2'b11:
                        begin
                            data_be = 4'b0111;
                        end
                        default:
                        begin
                            data_be = 4'b0000;
                        end
                    endcase
                end

                if((funct3 == 3'b001) || (funct3 == 3'b101))
                begin
                    casez (n)
                        2'b11:
                        begin
                            data_be = 4'b0001;
                        end
                        default:
                        begin
                            data_be = 4'b0000;
                        end
                    endcase
                end
                if(data_gnt == 1'b1)
                begin
                    stateMoore_next = wait_for_second_mem_read;
                end
                
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_second_mem_read:
            begin
                data_req = 1'b0;
                if(data_r_valid == 1'b1)
                begin
                    alu_dm_unalign_select = 1'b1;
                    write_enable = 1'b1;
                    stateMoore_next = wait_for_regset_write;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_data_write:
            begin
                data_req = 1'b0;
                pc_enable = 1'b1;
                stateMoore_next = Ready;
                

                if( ( opcode == 7'b0100011 ) && 
                    ( ((funct3 == 3'b010) && ((n == 2'b01) || (n == 2'b10) || (n == 2'b11))) ||
                      ((funct3 == 3'b001) || (funct3 == 3'b101) && (n == 2'b11)) )
                    )
                begin
                    pc_enable = 1'b0;
                    
                    dm_addr_select = 1'b1;
                    ALUSrcMux1 = 1'b0;
                    ALUSrcMux2 = 1'b1;
                    ALUSrcMux2_S = 1'b0;
                    data_write_enable = 1'b1;
                    data_req = 1'b1;

                    if(funct3 == 3'b010)
                    begin
                        casez (n)
                            2'b01:
                            begin
                                data_be = 4'b0001;
                            end
                            2'b10:
                            begin
                                data_be = 4'b0011;
                            end
                            2'b11:
                            begin
                                data_be = 4'b0111;
                            end
                            default:
                            begin
                                data_be = 4'b0000;
                            end
                        endcase
                    end

                    if(funct3 == 3'b001)
                    begin
                        casez (n)
                            2'b11:
                            begin
                                data_be = 4'b0001;
                            end
                            default:
                            begin
                                data_be = 4'b0000;
                            end
                        endcase
                    end
                    if(data_gnt == 1'b1)
                        stateMoore_next = mem_second_write;
                    else
                        stateMoore_next = wait_for_data_write;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            mem_second_write:
            begin
                data_req = 1'b0;
                pc_enable = 1'b1;
                stateMoore_next = Ready;
            end
            
            process_interrupt:
            begin
                pc_enable = 1'b1;
                irq_pc_mode = 1'b1;
                bckup_reg = 1'b1;
                irq_addr_sel = 1'b1;
                
                irq_status_update = 1'b1;
                irq_context = 1'b1;
                stateMoore_next = send_interrupt_acknowledge;                
            end
            
            send_interrupt_acknowledge:
            begin
                irq_ack = 1'b1;
                stateMoore_next = Ready;
            end
            
            default:
            begin
                stateMoore_next = Ready;
                pc_enable = 1'b0;
                ALUSrcMux1 = 1'b0;
                ALUSrcMux2 = 1'b0;
                ALUSrcMux1_S = 1'b0;
                ALUSrcMux2_S = 1'b0;
                reg_pc_select = 1'b0;
                alu_dm_select = 1'b0;
                write_enable = 1'b0;

                irq_status_update = 1'b0;
                irq_context = 1'b0;
                irq_ack = 1'b0;
                irq_addr_sel = 1'b0;
                bckup_reg = 1'b0;
                mret_sel = 1'b0;
                irq_pc_mode = 1'b0;
            end
        endcase
    end
    
endmodule
module ctrl(

    input wire RES,
    input wire CLK,
    

    output reg pc_enable,


    input wire [6 : 0] opcode,
    input wire [2 : 0] funct3,
    

    output reg MODE,
    


    output reg instr_req,
    input wire instr_gnt,
    input wire instr_r_valid,
    

    output reg write_enable,
    

    output reg ALUSrcMux1,
    output reg ALUSrcMux2,
    output reg ALUSrcMux1_S,
    output reg ALUSrcMux2_S,
    

    output reg reg_pc_select,
    

    output reg alu_dm_select,
    

    output reg data_write_enable,
    output reg data_req,
    input wire data_gnt,
    input wire data_r_valid,
    

    input wire irq,
    input wire irq_status,
    output reg irq_ack,
    output reg irq_status_update,
    output reg irq_context,
    output reg irq_addr_sel,
    output reg bckup_reg,
    output reg mret_sel,
    output reg irq_pc_mode,
    

    input wire [1 : 0] n,
    output reg [3 : 0] data_be,
    output reg merge_reg_write_enable,
    output reg dm_addr_select,
    output reg alu_dm_unalign_select
);


    localparam [3:0]
        Ready = 4'b0000,
        instruction_fetch = 4'b0001,
        process_instruction = 4'b0010,
        wait_for_regset_write = 4'b0011,
        wait_for_data_read = 4'b0100,
        wait_for_data_write = 4'b0101,
        process_interrupt = 4'b0110,
        send_interrupt_acknowledge = 4'b0111,
        wait_for_regset_write_JI = 4'b1000,
        mem_second_read = 4'b1001,
        wait_for_second_mem_read = 4'b1010,
        mem_second_write = 4'b1011;
    
    reg [3:0] stateMoore_reg, stateMoore_next;

    always @(posedge CLK, posedge RES)
    begin
        if(RES == 1'b1)
        begin
            stateMoore_reg <= Ready;
        end
        else
        begin
            stateMoore_reg <= stateMoore_next;
        end
    end
    
    always @(stateMoore_reg, instr_gnt, instr_r_valid, opcode, data_gnt, data_r_valid, irq, irq_status, funct3, n)
    begin

        stateMoore_next = stateMoore_reg;
        

        pc_enable = 1'b0;
        MODE = 1'b0;
        
        instr_req = 1'b0;
        ALUSrcMux1 = 1'b0;
        ALUSrcMux1_S = 1'b0;
        ALUSrcMux2 = 1'b0;
        ALUSrcMux2_S = 1'b0;
        reg_pc_select = 1'b0;
        alu_dm_select = 1'b0;
        write_enable = 1'b0;
        

        data_write_enable = 1'b0;
        data_req = 1'b0;
        

        irq_status_update = 1'b0;
        irq_context = 1'b0;
        irq_ack = 1'b0;
        irq_addr_sel = 1'b0;
        bckup_reg = 1'b0;
        mret_sel = 1'b0;
        irq_pc_mode = 1'b0;
        

        data_be = 4'b0000;
        merge_reg_write_enable = 1'b1;
        dm_addr_select = 1'b1;
        alu_dm_unalign_select = 1'b1;
        
        casez(stateMoore_reg)
            Ready:
            begin
                instr_req = 1'b1;
                if(instr_gnt == 1'b1)
                begin
                    stateMoore_next = instruction_fetch;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            instruction_fetch:
            begin

                if(instr_r_valid == 1'b1)
                begin
                    stateMoore_next = process_instruction;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
                    
            process_instruction:
            begin
                    casez(opcode)
                    
                        7'b0110111:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            ALUSrcMux1_S = 1'b1;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b0010111:
                        begin
                            ALUSrcMux1 = 1'b1;
                            ALUSrcMux2 = 1'b1;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b0010011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b0110011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b0;
                            write_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write;
                        end
                        
                        7'b1101111:
                        begin
                            ALUSrcMux1 = 1'b1;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux2_S = 1'b1;
                            write_enable = 1'b1;
                            reg_pc_select = 1'b0;
                              
                            MODE = 1'b1;
                            pc_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write_JI;
                        end
                        
                        7'b1100111:
                        begin
                            ALUSrcMux1 = 1'b1;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux2_S = 1'b1;
                            write_enable = 1'b1;
                            reg_pc_select = 1'b1; 
                            
                            MODE = 1'b1;
                            pc_enable = 1'b1;
                            stateMoore_next = wait_for_regset_write_JI;
                        end
                        
                        7'b1100011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux2_S = 1'b0;
                            write_enable = 1'b0;
                            reg_pc_select = 1'b0;
                            
                            pc_enable = 1'b1;
                            MODE = 1'b1;
                            stateMoore_next = Ready;
                        end
                        
                        7'b0000011:
                        begin

                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            ALUSrcMux2_S = 1'b0;
                            write_enable = 1'b0;
                            reg_pc_select = 1'b0;
                            alu_dm_select = 1'b1;
                            MODE = 1'b0;
                            data_write_enable = 1'b0;
                            data_req = 1'b1;
                            

                            if(funct3 == 3'b010)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b1111;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b1110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if((funct3 == 3'b001) || (funct3 == 3'b101))
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0011;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if((funct3 == 3'b000) || (funct3 == 3'b100))
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0001;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0010;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b0100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            
                            if(data_gnt == 1'b1)
                            begin
                                stateMoore_next = wait_for_data_read;
                            end
                        end
                        
                        7'b0100011:
                        begin
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b1;
                            ALUSrcMux2_S = 1'b0;
                            write_enable = 1'b0;
                            reg_pc_select = 1'b0;
                            alu_dm_select = 1'b0;
                            MODE = 1'b0;
                            data_write_enable = 1'b1;
                            data_req = 1'b1;
                            instr_req = 1'b0;
                            

                            if(funct3 == 3'b010)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b1111;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b1110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if(funct3 == 3'b001)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0011;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0110;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b1100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            

                            if(funct3 == 3'b000)
                            begin
                                casez (n)
                                    2'b00:
                                    begin
                                        data_be = 4'b0001;
                                    end
                                    2'b01:
                                    begin
                                        data_be = 4'b0010;
                                    end
                                    2'b10:
                                    begin
                                        data_be = 4'b0100;
                                    end
                                    2'b11:
                                    begin
                                        data_be = 4'b1000;
                                    end
                                    default:
                                    begin
                                        data_be = 4'b0000;
                                    end
                                endcase
                            end
                            if(data_gnt == 1'b1)
                            begin
                                stateMoore_next = wait_for_data_write;
                            end
                        end
                        
                        7'b1110011:
                        begin
                            if (funct3 == 3'b000)
                            begin
                                pc_enable = 1'b1;
                                stateMoore_next = Ready;
                                ALUSrcMux1 = 1'b0;
                                ALUSrcMux2 = 1'b0;
                                ALUSrcMux1_S = 1'b0;
                                ALUSrcMux2_S = 1'b0;
                                reg_pc_select = 1'b0;
                                alu_dm_select = 1'b0;
                                write_enable = 1'b0;

                                irq_status_update = 1'b1;
                                irq_context = 1'b0;
                                irq_pc_mode = 1'b1;
                                irq_addr_sel = 1'b0;
                                bckup_reg = 1'b0;
                                mret_sel = 1'b1;
                            end
                            
                            if (funct3 == 3'b010)
                            begin
                                ALUSrcMux1 = 1'b0;
                                ALUSrcMux1_S = 1'b1;
                                ALUSrcMux2 = 1'b1;
                                ALUSrcMux2_S = 1'b0;
                                
                                write_enable = 1'b0;
                                reg_pc_select = 1'b0;
                                alu_dm_select = 1'b1;
                                MODE = 1'b0;
                                data_write_enable = 1'b0;
                                data_req = 1'b1;
                                if(data_gnt == 1'b1)
                                begin
                                    stateMoore_next = wait_for_data_read;
                                end
                            end
                        end
                        
                        default:
                        begin
                            stateMoore_next = Ready;
                            pc_enable = 1'b0;
                            ALUSrcMux1 = 1'b0;
                            ALUSrcMux2 = 1'b0;
                            ALUSrcMux1_S = 1'b0;
                            ALUSrcMux2_S = 1'b0;
                            reg_pc_select = 1'b0;
                            alu_dm_select = 1'b0;
                            write_enable = 1'b0;

                            irq_status_update = 1'b0;
                            irq_context = 1'b0;
                            irq_ack = 1'b0;
                            irq_addr_sel = 1'b0;
                            bckup_reg = 1'b0;
                            mret_sel = 1'b0;
                            irq_pc_mode = 1'b0;
                        end
                    endcase
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_regset_write:
            begin
                stateMoore_next = Ready;
                pc_enable = 1'b1;
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_regset_write_JI:
            begin
                stateMoore_next = Ready;
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_data_read:
            begin
                data_req = 1'b0;
                merge_reg_write_enable = 1'b1;
                if(data_r_valid == 1'b1)
                begin
                    write_enable = 1'b1;
                    alu_dm_select = 1'b1;
                    stateMoore_next = wait_for_regset_write;
                    

                    if( ( opcode == 7'b0000011 ) && 
                        ( ((funct3 == 3'b010) && ((n == 2'b01) || (n == 2'b10) || (n == 2'b11))) ||
                          ((funct3 == 3'b001) || (funct3 == 3'b101) && (n == 2'b11)) )
                        )
                    begin
                        write_enable = 1'b0;
                        alu_dm_select = 1'b0;
                        stateMoore_next = mem_second_read;
                    end
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            mem_second_read:
            begin
                dm_addr_select = 1'b1;
                
                ALUSrcMux1 = 1'b0;
                ALUSrcMux2 = 1'b1;
                ALUSrcMux2_S = 1'b0;
                data_req = 1'b1;

                if(funct3 == 3'b010)
                begin
                    casez (n)
                        2'b01:
                        begin
                            data_be = 4'b0001;
                        end
                        2'b10:
                        begin
                            data_be = 4'b0011;
                        end
                        2'b11:
                        begin
                            data_be = 4'b0111;
                        end
                        default:
                        begin
                            data_be = 4'b0000;
                        end
                    endcase
                end

                if((funct3 == 3'b001) || (funct3 == 3'b101))
                begin
                    casez (n)
                        2'b11:
                        begin
                            data_be = 4'b0001;
                        end
                        default:
                        begin
                            data_be = 4'b0000;
                        end
                    endcase
                end
                if(data_gnt == 1'b1)
                begin
                    stateMoore_next = wait_for_second_mem_read;
                end
                
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_second_mem_read:
            begin
                data_req = 1'b0;
                if(data_r_valid == 1'b1)
                begin
                    alu_dm_unalign_select = 1'b1;
                    write_enable = 1'b1;
                    stateMoore_next = wait_for_regset_write;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            wait_for_data_write:
            begin
                data_req = 1'b0;
                pc_enable = 1'b1;
                stateMoore_next = Ready;
                

                if( ( opcode == 7'b0100011 ) && 
                    ( ((funct3 == 3'b010) && ((n == 2'b01) || (n == 2'b10) || (n == 2'b11))) ||
                      ((funct3 == 3'b001) || (funct3 == 3'b101) && (n == 2'b11)) )
                    )
                begin
                    pc_enable = 1'b0;
                    
                    dm_addr_select = 1'b1;
                    ALUSrcMux1 = 1'b0;
                    ALUSrcMux2 = 1'b1;
                    ALUSrcMux2_S = 1'b0;
                    data_write_enable = 1'b1;
                    data_req = 1'b1;

                    if(funct3 == 3'b010)
                    begin
                        casez (n)
                            2'b01:
                            begin
                                data_be = 4'b0001;
                            end
                            2'b10:
                            begin
                                data_be = 4'b0011;
                            end
                            2'b11:
                            begin
                                data_be = 4'b0111;
                            end
                            default:
                            begin
                                data_be = 4'b0000;
                            end
                        endcase
                    end

                    if(funct3 == 3'b001)
                    begin
                        casez (n)
                            2'b11:
                            begin
                                data_be = 4'b0001;
                            end
                            default:
                            begin
                                data_be = 4'b0000;
                            end
                        endcase
                    end
                    if(data_gnt == 1'b1)
                        stateMoore_next = mem_second_write;
                    else
                        stateMoore_next = wait_for_data_write;
                end
                

                if((irq == 1'b1) && (irq_status == 0))
                begin
                    stateMoore_next = process_interrupt;
                end
            end
            
            mem_second_write:
            begin
                data_req = 1'b0;
                pc_enable = 1'b1;
                stateMoore_next = Ready;
            end
            
            process_interrupt:
            begin
                pc_enable = 1'b1;
                irq_pc_mode = 1'b1;
                bckup_reg = 1'b1;
                irq_addr_sel = 1'b1;
                
                irq_status_update = 1'b1;
                irq_context = 1'b1;
                stateMoore_next = send_interrupt_acknowledge;                
            end
            
            send_interrupt_acknowledge:
            begin
                irq_ack = 1'b1;
                stateMoore_next = Ready;
            end
            
            default:
            begin
                stateMoore_next = Ready;
                pc_enable = 1'b0;
                ALUSrcMux1 = 1'b0;
                ALUSrcMux2 = 1'b0;
                ALUSrcMux1_S = 1'b0;
                ALUSrcMux2_S = 1'b0;
                reg_pc_select = 1'b0;
                alu_dm_select = 1'b0;
                write_enable = 1'b0;

                irq_status_update = 1'b0;
                irq_context = 1'b0;
                irq_ack = 1'b0;
                irq_addr_sel = 1'b0;
                bckup_reg = 1'b0;
                mret_sel = 1'b0;
                irq_pc_mode = 1'b0;
            end
        endcase
    end
    
endmodule