data/full_repos/permissive/475937410/Ass3/ALU.v
data/verilator_xmls/c9ed5cb0-08cd-4800-8ef9-7924e50e8dc6.xml
module alu(instruction,regA, regB, result, flags);


input signed [31:0] instruction,regA, regB;
output signed [31:0] result;
output [2:0] flags;


reg[5:0] opcode, func;
reg[4:0] rs, rt, rd;
reg signed[31:0] reg_A, reg_B, reg_C, rs_reg, rt_reg;
reg[31:0] unsigned_reg_A, unsigned_reg_B;
reg extension;
reg zero;
reg negative;
reg overflow;



always @(instruction,regA, regB)
begin

    opcode = instruction[31:26];
    func = instruction[5:0];
    rs = instruction[25:21];
    rt = instruction[20:16];
    rd = instruction[15:11];


    case(rs)
        5'b00000:
        begin
            rs_reg = regA;
        end
        5'b00001:
        begin
            rs_reg = regB;
        end
    endcase

    case(rt)
        5'b00000:
        begin
            rt_reg = regA;
        end
        5'b00001:
        begin
            rt_reg = regB;
        end
    endcase

    case(opcode)


        6'b000000:
        begin

            case(func)


                6'b100000:
                begin
                    {extension, reg_C} = {rs_reg[31],rs_reg} + {rt_reg[31],rt_reg};
                    overflow = extension ^ reg_C[31];
                end


                6'b100001:
                begin
                    unsigned_reg_A = rs_reg;
                    unsigned_reg_B = rt_reg;
                    reg_C = unsigned_reg_A + unsigned_reg_B;
                end


                6'b100100:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A & reg_B;
                end


                6'b100111:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A ~| reg_B;
                end


                6'b100101:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A | reg_B;
                end


                6'b000000:
                begin
                    reg_A = rt_reg;
                    reg_B = {{27{1'b0}}, instruction[10:6]};
                    reg_C = reg_A << reg_B;
                end


                6'b000100:
                begin
                    reg_A = rt_reg;
                    reg_B = rs_reg;
                    reg_C = reg_A << reg_B;
                end


                6'b101010:
                begin
                    {extension, reg_C} = {rs_reg[31],rs_reg} - {rt_reg[31],rt_reg};
                    overflow = extension ^ reg_C[31];
                end


                6'b101011:
                begin
                    unsigned_reg_A = rs_reg;
                    unsigned_reg_B = rt_reg;
                    reg_C = unsigned_reg_A - unsigned_reg_B;
                end


                6'b000011:
                begin
                    reg_A = rt_reg;
                    reg_B = {{27{1'b0}}, instruction[10:6]};
                    reg_C = reg_A >>> reg_B;
                end


                6'b000111:
                begin
                    reg_A = rt_reg;
                    reg_B = rs_reg;
                    reg_C = reg_A >>> reg_B;
                end


                6'b000010:
                begin
                    reg_A = rt_reg;
                    reg_B = {{27{1'b0}}, instruction[10:6]};
                    reg_C = reg_A >> reg_B;
                end


                6'b000110:
                begin
                    reg_A = rt_reg;
                    reg_B = rs_reg;
                    reg_C = reg_A >> reg_B;
                end


                6'b100010:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    {extension, reg_C} = {rs_reg[31],rs_reg} - {rt_reg[31],rt_reg};
                    overflow = extension ^ reg_C[31];
                end


                6'b100011:
                begin
                    unsigned_reg_A = rs_reg;
                    unsigned_reg_B = rt_reg;
                    reg_C = unsigned_reg_A - unsigned_reg_B;
                end


                6'b100110:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A ^ reg_B;
                end
                

            endcase
        end




        6'b001000:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} + {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b001001:
        begin
            unsigned_reg_A = rs_reg;
            unsigned_reg_B = {{16{instruction[15]}}, instruction[15:0]};
            reg_C = unsigned_reg_A + unsigned_reg_B;
        end


        6'b001100:
        begin
            reg_A = rs_reg;
            reg_B = {{16{1'b0}}, instruction[15:0]};
            reg_C = reg_A & reg_B;
        end


        6'b000100:
        begin
            reg_A = rs_reg;
            reg_B = rt_reg;
            {extension, reg_C} = {reg_A[31],reg_A} - {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b000101:
        begin
            reg_A = rs_reg;
            reg_B = rt_reg;
            {extension, reg_C} = {reg_A[31],reg_A} - {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b100011:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} + {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b101011:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} + {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b001101:
        begin
            reg_A = rs_reg;
            reg_B = {{16{1'b0}}, instruction[15:0]};
            reg_C = reg_A | reg_B;
        end


        6'b001010:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} - {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b001011:
        begin
            unsigned_reg_A = rs_reg;
            unsigned_reg_B = {{16{instruction[15]}}, instruction[15:0]};
            reg_C = unsigned_reg_A - unsigned_reg_B;
        end


        6'b001110:
        begin
            reg_A = rs_reg;
            reg_B = {{16{1'b0}}, instruction[15:0]};
            reg_C = reg_A ^ reg_B;
        end

    endcase


    case (reg_C)
        32'b0: 
        begin
            zero = 1'b1;
        end
        default: 
        begin
            zero = 1'b0;
        end
    endcase


    case (reg_C[31])
        1'b1: 
        begin
            negative = 1'b1;
        end
        default: 
        begin
            negative = 1'b0;
        end
    endcase

end

assign result = reg_C[31:0];
assign flags[2] = zero;
assign flags[1] = negative;
assign flags[0] = overflow;


endmodule
module alu(instruction,regA, regB, result, flags);



input signed [31:0] instruction,regA, regB;
output signed [31:0] result;
output [2:0] flags;


reg[5:0] opcode, func;
reg[4:0] rs, rt, rd;
reg signed[31:0] reg_A, reg_B, reg_C, rs_reg, rt_reg;
reg[31:0] unsigned_reg_A, unsigned_reg_B;
reg extension;
reg zero;
reg negative;
reg overflow;



always @(instruction,regA, regB)
begin

    opcode = instruction[31:26];
    func = instruction[5:0];
    rs = instruction[25:21];
    rt = instruction[20:16];
    rd = instruction[15:11];


    case(rs)
        5'b00000:
        begin
            rs_reg = regA;
        end
        5'b00001:
        begin
            rs_reg = regB;
        end
    endcase

    case(rt)
        5'b00000:
        begin
            rt_reg = regA;
        end
        5'b00001:
        begin
            rt_reg = regB;
        end
    endcase

    case(opcode)


        6'b000000:
        begin

            case(func)


                6'b100000:
                begin
                    {extension, reg_C} = {rs_reg[31],rs_reg} + {rt_reg[31],rt_reg};
                    overflow = extension ^ reg_C[31];
                end


                6'b100001:
                begin
                    unsigned_reg_A = rs_reg;
                    unsigned_reg_B = rt_reg;
                    reg_C = unsigned_reg_A + unsigned_reg_B;
                end


                6'b100100:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A & reg_B;
                end


                6'b100111:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A ~| reg_B;
                end


                6'b100101:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A | reg_B;
                end


                6'b000000:
                begin
                    reg_A = rt_reg;
                    reg_B = {{27{1'b0}}, instruction[10:6]};
                    reg_C = reg_A << reg_B;
                end


                6'b000100:
                begin
                    reg_A = rt_reg;
                    reg_B = rs_reg;
                    reg_C = reg_A << reg_B;
                end


                6'b101010:
                begin
                    {extension, reg_C} = {rs_reg[31],rs_reg} - {rt_reg[31],rt_reg};
                    overflow = extension ^ reg_C[31];
                end


                6'b101011:
                begin
                    unsigned_reg_A = rs_reg;
                    unsigned_reg_B = rt_reg;
                    reg_C = unsigned_reg_A - unsigned_reg_B;
                end


                6'b000011:
                begin
                    reg_A = rt_reg;
                    reg_B = {{27{1'b0}}, instruction[10:6]};
                    reg_C = reg_A >>> reg_B;
                end


                6'b000111:
                begin
                    reg_A = rt_reg;
                    reg_B = rs_reg;
                    reg_C = reg_A >>> reg_B;
                end


                6'b000010:
                begin
                    reg_A = rt_reg;
                    reg_B = {{27{1'b0}}, instruction[10:6]};
                    reg_C = reg_A >> reg_B;
                end


                6'b000110:
                begin
                    reg_A = rt_reg;
                    reg_B = rs_reg;
                    reg_C = reg_A >> reg_B;
                end


                6'b100010:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    {extension, reg_C} = {rs_reg[31],rs_reg} - {rt_reg[31],rt_reg};
                    overflow = extension ^ reg_C[31];
                end


                6'b100011:
                begin
                    unsigned_reg_A = rs_reg;
                    unsigned_reg_B = rt_reg;
                    reg_C = unsigned_reg_A - unsigned_reg_B;
                end


                6'b100110:
                begin
                    reg_A = rs_reg;
                    reg_B = rt_reg;
                    reg_C = reg_A ^ reg_B;
                end
                

            endcase
        end




        6'b001000:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} + {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b001001:
        begin
            unsigned_reg_A = rs_reg;
            unsigned_reg_B = {{16{instruction[15]}}, instruction[15:0]};
            reg_C = unsigned_reg_A + unsigned_reg_B;
        end


        6'b001100:
        begin
            reg_A = rs_reg;
            reg_B = {{16{1'b0}}, instruction[15:0]};
            reg_C = reg_A & reg_B;
        end


        6'b000100:
        begin
            reg_A = rs_reg;
            reg_B = rt_reg;
            {extension, reg_C} = {reg_A[31],reg_A} - {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b000101:
        begin
            reg_A = rs_reg;
            reg_B = rt_reg;
            {extension, reg_C} = {reg_A[31],reg_A} - {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b100011:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} + {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b101011:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} + {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b001101:
        begin
            reg_A = rs_reg;
            reg_B = {{16{1'b0}}, instruction[15:0]};
            reg_C = reg_A | reg_B;
        end


        6'b001010:
        begin
            reg_A = rs_reg;
            reg_B = {{16{instruction[15]}}, instruction[15:0]};
            {extension, reg_C} = {reg_A[31],reg_A} - {reg_B[31],reg_B};
            overflow = extension ^ reg_C[31];
        end


        6'b001011:
        begin
            unsigned_reg_A = rs_reg;
            unsigned_reg_B = {{16{instruction[15]}}, instruction[15:0]};
            reg_C = unsigned_reg_A - unsigned_reg_B;
        end


        6'b001110:
        begin
            reg_A = rs_reg;
            reg_B = {{16{1'b0}}, instruction[15:0]};
            reg_C = reg_A ^ reg_B;
        end

    endcase


    case (reg_C)
        32'b0: 
        begin
            zero = 1'b1;
        end
        default: 
        begin
            zero = 1'b0;
        end
    endcase


    case (reg_C[31])
        1'b1: 
        begin
            negative = 1'b1;
        end
        default: 
        begin
            negative = 1'b0;
        end
    endcase

end

assign result = reg_C[31:0];
assign flags[2] = zero;
assign flags[1] = negative;
assign flags[0] = overflow;


endmodule