data/full_repos/permissive/415843050/cpu-src/idecode.v
data/verilator_xmls/a7eb1f90-b56f-4065-940a-cf00741eee66.xml
module Idecode(
    Instruction,Received_data,PC_plus_4,PC_plus_4_latch,ALU_result,CP0_data_latch,
    clock,reset,
    Jal,Jalr,Bgezal,Bltzal,
    Memory_or_IO,Register_write,Write_back_address,
    Read_data_1,Read_data_2,Immediate_extend,
    Mfc0,Mtc0,
    Break,Syscall,Eret,
    Positive,Negative,
    Overflow,Divide_zero,Reserved_instruction,
    Cause_write,Cause_write_data,Cause_read_data,
    Status_write,Status_write_data,Status_read_data,
    EPC_write,EPC_write_data,EPC_read_data,
    CP0_data,PC_exception,

    Register_write_ex_mem,Write_back_address_ex_mem,
    Register_write_mem_wb,Write_back_address_mem_wb,Memory_or_IO_mem_wb,
    ALU_result_ex_mem,ALU_result_mem_wb,Read_data_mem_wb
    );

    input[31:0]     Instruction;
    input[31:0]     Received_data;
    input[31:0]     PC_plus_4;
    input[31:0]     PC_plus_4_latch;
    input[31:0]     ALU_result;
    input[31:0]     CP0_data_latch;
    
    input       clock;
    input       reset;
    
    input       Jal,Jalr;
    input       Bgezal,Bltzal;
    input       Memory_or_IO;
    input       Register_write;
    input[4:0]  Write_back_address;
    
    output[31:0]    Read_data_1;
    output[31:0]    Read_data_2;
    output[31:0]    Immediate_extend;
    
    input       Mfc0,Mtc0;
    
    input       Break,Syscall,Eret;
    input       Positive,Negative;
    input       Overflow,Divide_zero,Reserved_instruction;
    
    output          Cause_write,Status_write,EPC_write;
    output[31:0]    Cause_write_data,Status_write_data,EPC_write_data;
    input[31:0] Cause_read_data,Status_read_data,EPC_read_data;
    
    output[31:0]    CP0_data;
    output[31:0]    PC_exception;
    
    
    wire[5:0]   opcode;
    wire[4:0]   rs;
    wire[4:0]   rt;
    wire[4:0]   rd;
    wire[31:0]  rt_value;
    wire[31:0]  rd_value;
    wire[15:0]  immediate;
    
    wire        sign;
    
    
    reg[31:0]   register[0:31];
    
    reg[31:0]   write_data;
    reg[4:0]    write_address;
    
    reg[31:0]   cp0_data;
    reg         Cause_write,Status_write,EPC_write;
    reg[31:0]   Cause_write_data,Status_write_data,EPC_write_data;
    
    reg[31:0]   PC_exception;


    input       Register_write_ex_mem,Register_write_mem_wb,Memory_or_IO_mem_wb;
    input[4:0]  Write_back_address_ex_mem,Write_back_address_mem_wb;
    input[31:0] ALU_result_ex_mem,ALU_result_mem_wb,Read_data_mem_wb;
    
    
    

    assign opcode = Instruction[31:26];
    assign rs = Instruction[25:21];
    assign rt = Instruction[20:16];
    assign rd = Instruction[15:11];
    assign immediate = Instruction[15:0];
    

    assign Read_data_1 = register[rs];
    assign Read_data_2 = register[rt];

    assign rt_value = 
                (Register_write_ex_mem && Write_back_address_ex_mem != 0 && 
                        Write_back_address_ex_mem == rt)
                    ? ALU_result_ex_mem
                    : (Register_write_mem_wb && Write_back_address_mem_wb != 0 &&
                            Write_back_address_ex_mem != rt && Write_back_address_mem_wb == rt)
                        ? (Memory_or_IO_mem_wb ? Read_data_mem_wb : ALU_result_mem_wb)
                        : register[rt];
    assign rd_value = 
                (Register_write_ex_mem && Write_back_address_ex_mem != 0 && 
                        Write_back_address_ex_mem == rd)
                    ? ALU_result_ex_mem
                    : (Register_write_mem_wb && Write_back_address_mem_wb != 0 &&
                            Write_back_address_ex_mem != rd && Write_back_address_mem_wb == rd)
                        ? (Memory_or_IO_mem_wb ? Read_data_mem_wb : ALU_result_mem_wb)
                        : register[rd];
    
    assign CP0_data = cp0_data;
    
    always @(*)
    begin
        case ({Mfc0,rd_value})
            {1'b1,32'd12}: cp0_data = Status_read_data;
            {1'b1,32'd13}: cp0_data = Cause_read_data;
            {1'b1,32'd14}: cp0_data = EPC_read_data;
            default: cp0_data = 32'hFFFFFFFF;
        endcase
        

        write_address = (Jal || (Bgezal && !Negative) || (Bltzal && Negative))
            ? 5'd31
            : ((Bgezal || Bltzal) ? 5'd00 : Write_back_address);
                

        write_data = (Jal || Jalr || Bgezal || Bltzal)
            ? PC_plus_4_latch
            : (
                  Memory_or_IO 
                  ? Received_data
                  : (CP0_data_latch != 32'hFFFFFFFF ? CP0_data_latch : ALU_result)
              );
        

        if (Break || Syscall || Overflow || Reserved_instruction)
        begin

            Status_write_data = {Status_read_data[31:1],1'b0};
            

            case ({Break,Syscall,Overflow,Reserved_instruction})
                4'b1000: Cause_write_data = {Cause_read_data[31:7],7'b01001_00};
                4'b0100: Cause_write_data = {Cause_read_data[31:7],7'b01000_00};
                4'b0010: Cause_write_data = {Cause_read_data[31:7],7'b01100_00};
                4'b0001: Cause_write_data = {Cause_read_data[31:7],7'b01010_00};
                default: Cause_write_data = {Cause_read_data[31:7],7'b00000_00};
            endcase
            

            EPC_write_data = PC_plus_4;
            

            PC_exception = 32'h0000F000;
            

            Status_write = 1'b1;
            Cause_write = 1'b1;
            EPC_write = 1'b1;
        end

        else if (Eret)
        begin

            Status_write_data = {Status_read_data[31:1],1'b1};
            
            PC_exception = EPC_read_data;
            

            Status_write = 1'b1;
        end

        else if (Mtc0)
        begin
            case (rd_value)
                32'd12:
                begin
                    Status_write_data = rt_value;
                    Status_write = 1'b1;
                end
                32'd13:
                begin
                    Cause_write_data = rt_value;
                    Cause_write = 1'b1;
                end
                32'd14:
                begin
                    EPC_write_data = rt_value;
                    EPC_write = 1'b1;
                end
                default:
                begin
                    Status_write = 1'b0;
                    Cause_write = 1'b0;
                    EPC_write = 1'b0;
                end
            endcase
        end
        else

        begin
            PC_exception = 32'hFFFFFFFF;
            

            Status_write = 1'b0;
            Cause_write = 1'b0;
            EPC_write = 1'b0;
        end
    end
    

    integer i;
    always @(posedge clock)
    begin
        if (reset)
        begin
            for (i = 0; i < 32; i = i + 1)
                register[i] <= i;
        end
        else if (Register_write && write_address != 5'd00)
        begin
            register[write_address] = write_data;
        end
    end
    

    assign sign = immediate[15];
    assign Immediate_extend[31:16] =
        (opcode == 6'b001100|| opcode == 6'b001101||
            opcode == 6'b001110|| opcode == 6'b001011)
            ? 16'h0000
            : {16{sign}};
    assign Immediate_extend[15:0] = immediate;
    
endmodule
module Idecode(
    Instruction,Received_data,PC_plus_4,PC_plus_4_latch,ALU_result,CP0_data_latch,
    clock,reset,
    Jal,Jalr,Bgezal,Bltzal,
    Memory_or_IO,Register_write,Write_back_address,
    Read_data_1,Read_data_2,Immediate_extend,
    Mfc0,Mtc0,
    Break,Syscall,Eret,
    Positive,Negative,
    Overflow,Divide_zero,Reserved_instruction,
    Cause_write,Cause_write_data,Cause_read_data,
    Status_write,Status_write_data,Status_read_data,
    EPC_write,EPC_write_data,EPC_read_data,
    CP0_data,PC_exception,

    Register_write_ex_mem,Write_back_address_ex_mem,
    Register_write_mem_wb,Write_back_address_mem_wb,Memory_or_IO_mem_wb,
    ALU_result_ex_mem,ALU_result_mem_wb,Read_data_mem_wb
    );


    input[31:0]     Instruction;
    input[31:0]     Received_data;
    input[31:0]     PC_plus_4;
    input[31:0]     PC_plus_4_latch;
    input[31:0]     ALU_result;
    input[31:0]     CP0_data_latch;
    
    input       clock;
    input       reset;
    
    input       Jal,Jalr;
    input       Bgezal,Bltzal;
    input       Memory_or_IO;
    input       Register_write;
    input[4:0]  Write_back_address;
    
    output[31:0]    Read_data_1;
    output[31:0]    Read_data_2;
    output[31:0]    Immediate_extend;
    
    input       Mfc0,Mtc0;
    
    input       Break,Syscall,Eret;
    input       Positive,Negative;
    input       Overflow,Divide_zero,Reserved_instruction;
    
    output          Cause_write,Status_write,EPC_write;
    output[31:0]    Cause_write_data,Status_write_data,EPC_write_data;
    input[31:0] Cause_read_data,Status_read_data,EPC_read_data;
    
    output[31:0]    CP0_data;
    output[31:0]    PC_exception;
    
    
    wire[5:0]   opcode;
    wire[4:0]   rs;
    wire[4:0]   rt;
    wire[4:0]   rd;
    wire[31:0]  rt_value;
    wire[31:0]  rd_value;
    wire[15:0]  immediate;
    
    wire        sign;
    
    
    reg[31:0]   register[0:31];
    
    reg[31:0]   write_data;
    reg[4:0]    write_address;
    
    reg[31:0]   cp0_data;
    reg         Cause_write,Status_write,EPC_write;
    reg[31:0]   Cause_write_data,Status_write_data,EPC_write_data;
    
    reg[31:0]   PC_exception;


    input       Register_write_ex_mem,Register_write_mem_wb,Memory_or_IO_mem_wb;
    input[4:0]  Write_back_address_ex_mem,Write_back_address_mem_wb;
    input[31:0] ALU_result_ex_mem,ALU_result_mem_wb,Read_data_mem_wb;
    
    
    

    assign opcode = Instruction[31:26];
    assign rs = Instruction[25:21];
    assign rt = Instruction[20:16];
    assign rd = Instruction[15:11];
    assign immediate = Instruction[15:0];
    

    assign Read_data_1 = register[rs];
    assign Read_data_2 = register[rt];

    assign rt_value = 
                (Register_write_ex_mem && Write_back_address_ex_mem != 0 && 
                        Write_back_address_ex_mem == rt)
                    ? ALU_result_ex_mem
                    : (Register_write_mem_wb && Write_back_address_mem_wb != 0 &&
                            Write_back_address_ex_mem != rt && Write_back_address_mem_wb == rt)
                        ? (Memory_or_IO_mem_wb ? Read_data_mem_wb : ALU_result_mem_wb)
                        : register[rt];
    assign rd_value = 
                (Register_write_ex_mem && Write_back_address_ex_mem != 0 && 
                        Write_back_address_ex_mem == rd)
                    ? ALU_result_ex_mem
                    : (Register_write_mem_wb && Write_back_address_mem_wb != 0 &&
                            Write_back_address_ex_mem != rd && Write_back_address_mem_wb == rd)
                        ? (Memory_or_IO_mem_wb ? Read_data_mem_wb : ALU_result_mem_wb)
                        : register[rd];
    
    assign CP0_data = cp0_data;
    
    always @(*)
    begin
        case ({Mfc0,rd_value})
            {1'b1,32'd12}: cp0_data = Status_read_data;
            {1'b1,32'd13}: cp0_data = Cause_read_data;
            {1'b1,32'd14}: cp0_data = EPC_read_data;
            default: cp0_data = 32'hFFFFFFFF;
        endcase
        

        write_address = (Jal || (Bgezal && !Negative) || (Bltzal && Negative))
            ? 5'd31
            : ((Bgezal || Bltzal) ? 5'd00 : Write_back_address);
                

        write_data = (Jal || Jalr || Bgezal || Bltzal)
            ? PC_plus_4_latch
            : (
                  Memory_or_IO 
                  ? Received_data
                  : (CP0_data_latch != 32'hFFFFFFFF ? CP0_data_latch : ALU_result)
              );
        

        if (Break || Syscall || Overflow || Reserved_instruction)
        begin

            Status_write_data = {Status_read_data[31:1],1'b0};
            

            case ({Break,Syscall,Overflow,Reserved_instruction})
                4'b1000: Cause_write_data = {Cause_read_data[31:7],7'b01001_00};
                4'b0100: Cause_write_data = {Cause_read_data[31:7],7'b01000_00};
                4'b0010: Cause_write_data = {Cause_read_data[31:7],7'b01100_00};
                4'b0001: Cause_write_data = {Cause_read_data[31:7],7'b01010_00};
                default: Cause_write_data = {Cause_read_data[31:7],7'b00000_00};
            endcase
            

            EPC_write_data = PC_plus_4;
            

            PC_exception = 32'h0000F000;
            

            Status_write = 1'b1;
            Cause_write = 1'b1;
            EPC_write = 1'b1;
        end

        else if (Eret)
        begin

            Status_write_data = {Status_read_data[31:1],1'b1};
            
            PC_exception = EPC_read_data;
            

            Status_write = 1'b1;
        end

        else if (Mtc0)
        begin
            case (rd_value)
                32'd12:
                begin
                    Status_write_data = rt_value;
                    Status_write = 1'b1;
                end
                32'd13:
                begin
                    Cause_write_data = rt_value;
                    Cause_write = 1'b1;
                end
                32'd14:
                begin
                    EPC_write_data = rt_value;
                    EPC_write = 1'b1;
                end
                default:
                begin
                    Status_write = 1'b0;
                    Cause_write = 1'b0;
                    EPC_write = 1'b0;
                end
            endcase
        end
        else

        begin
            PC_exception = 32'hFFFFFFFF;
            

            Status_write = 1'b0;
            Cause_write = 1'b0;
            EPC_write = 1'b0;
        end
    end
    

    integer i;
    always @(posedge clock)
    begin
        if (reset)
        begin
            for (i = 0; i < 32; i = i + 1)
                register[i] <= i;
        end
        else if (Register_write && write_address != 5'd00)
        begin
            register[write_address] = write_data;
        end
    end
    

    assign sign = immediate[15];
    assign Immediate_extend[31:16] =
        (opcode == 6'b001100|| opcode == 6'b001101||
            opcode == 6'b001110|| opcode == 6'b001011)
            ? 16'h0000
            : {16{sign}};
    assign Immediate_extend[15:0] = immediate;
    
endmodule