module Controller(
    input  [31:15] Opcode_in,
    output reg     RegWr,
    output reg     MemToReg,
    output reg     MemWrEn,
    output reg     ALUBSrc,
    output reg     srcReg,
    output reg [1:0]  ExtOp,
    output reg [2:0]  AluCtrl
);
    parameter OP_RTYPE = 3'b000, OP_LU12I = 3'b001, OP_LOAD  = 3'b010, OP_STORE = 3'b011;
    
    parameter FUNC_ADD = 7'b0000010, FUNC_SLT = 7'b0000100, FUNC_SLTU= 7'b0000101;
    
    wire [2:0] main_op = Opcode_in[31:29];
    wire [6:0] func_op = Opcode_in[21:15];

    always @(*) begin
        RegWr=0; MemToReg=0; MemWrEn=0; ALUBSrc=0; srcReg=0; ExtOp=2'bxx; AluCtrl=3'bxxx;
        
        case(main_op)
            OP_RTYPE: begin
                RegWr=1; ALUBSrc=0;
                case(func_op)
                    FUNC_ADD:  AluCtrl = 3'b000;
                    FUNC_SLT:  AluCtrl = 3'b101;
                    FUNC_SLTU: AluCtrl = 3'b110;
                    default: ;
                endcase
            end
            OP_LU12I: begin
                RegWr=1; ALUBSrc=1; ExtOp=2'b10; AluCtrl=3'b111;
            end
            OP_LOAD:  begin
                RegWr=1; MemToReg=1; ALUBSrc=1; ExtOp=2'b00; AluCtrl=3'b000;
            end
            OP_STORE: begin
                MemWrEn=1; ALUBSrc=1; srcReg=1; ExtOp=2'b00; AluCtrl=3'b000;
            end
            default: ;
        endcase
    end
endmodule