`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/06/13 14:23:19
// Design Name: 
// Module Name: Controller
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module Controller (
    input      [31:15] Instr,
    output reg          RegWr,
    output reg          ALUBsrc,
    output reg          MemToReg,
    output reg          MemWrEn,
    output reg          srcReg,
    output reg  [2:0]   AluCtrl,
    output reg  [1:0]   ExtOp
);
    localparam ADD_W  = 17'b00000010001000000;
    localparam SLT_W  = 17'b00000010010000000;
    localparam SLTU_W = 17'b00000010011000000;
    localparam LU12I_W = 7'b0001010;
    localparam LD_W    = 7'b0010100;
    localparam ST_W    = 7'b0010101;
    localparam ALU_ADD  = 3'b000;
    localparam ALU_SLT  = 3'b101;
    localparam ALU_SLTU = 3'b110;
    localparam EXT_SIGN_12 = 2'b00;
    localparam EXT_ZERO_20 = 2'b10;
    always @(*) begin
        RegWr    = 1'b0;
        ALUBsrc  = 1'b0;
        MemToReg = 1'b0;
        MemWrEn  = 1'b0;
        srcReg   = 1'b0;
        AluCtrl  = 3'bxxx;
        ExtOp    = 2'bxx;
        if (Instr == ADD_W) begin
            RegWr    = 1'b1;
            ALUBsrc  = 1'b0;
            MemToReg = 1'b0;
            MemWrEn  = 1'b0;
            srcReg   = 1'b0;
            AluCtrl  = ALU_ADD;
            ExtOp    = 2'bxx;
        end
        else if (Instr == SLT_W) begin
            RegWr    = 1'b1;
            ALUBsrc  = 1'b0;
            MemToReg = 1'b0;
            MemWrEn  = 1'b0;
            srcReg   = 1'b0;
            AluCtrl  = ALU_SLT;
            ExtOp    = 2'bxx;
        end
        else if (Instr == SLTU_W) begin
            RegWr    = 1'b1;
            ALUBsrc  = 1'b0;
            MemToReg = 1'b0;
            MemWrEn  = 1'b0;
            srcReg   = 1'b0;
            AluCtrl  = ALU_SLTU;
            ExtOp    = 2'bxx;
        end
        else if (Instr[31:25] == LU12I_W) begin
            RegWr    = 1'b1;
            ALUBsrc  = 1'b1;
            MemToReg = 1'b0;
            MemWrEn  = 1'b0;
            srcReg   = 1'b0;
            AluCtrl  = ALU_ADD;
            ExtOp    = EXT_ZERO_20;
        end
        else if (Instr[31:25] == LD_W) begin
            RegWr    = 1'b1;
            ALUBsrc  = 1'b1;
            MemToReg = 1'b1;
            MemWrEn  = 1'b0;
            srcReg   = 1'b0;
            AluCtrl  = ALU_ADD;
            ExtOp    = EXT_SIGN_12;
        end
        else if (Instr[31:25] == ST_W) begin
            RegWr    = 1'b0;
            ALUBsrc  = 1'b1;
            MemToReg = 1'bx;
            MemWrEn  = 1'b1;
            srcReg   = 1'b1;
            AluCtrl  = ALU_ADD;
            ExtOp    = EXT_SIGN_12;
        end
    end
endmodule
