package projet.op

import chisel3._
import chisel3.util.switch
import projet.CUInterface
import projet.AluOpCode
import chisel3.util.is
import projet.OpType

object OpImmW {
    // Implements functions for all instruction of the opImm, w  kind
    def opImmW(io: CUInterface) = {
        val funct3 = io.instruction(14, 12);
        // Meaning of Funct3 in the context of an OpImm instruction
        object Funct3 extends ChiselEnum {
            // Type I
            val ADDIW = "b000".U
            val SLLIW = "b001".U

            val ShiftWordRight = "b101".U // Right shifts
        }

        io.optype := OpType.I;
        io.reg_file_we := true.B // Write to regfile
        io.mux_regb_imm := false.B; // OpImm are operations with imm, so send imm to ALU
        io.mux_alu_imm := true.B;
        io.mux_rega_pc := true.B;
        io.alu_word_mode := true.B
        switch(funct3) {
            // Type I
            is(Funct3.ADDIW) {
                io.alu_opcode := AluOpCode.Add
                io.optype := OpType.I
            }

            is(Funct3.SLLIW) {
                io.alu_opcode := AluOpCode.ShiftLeft
                io.optype := OpType.I
            }

            is(Funct3.ShiftWordRight) {
                io.optype := OpType.IR

                // Second-to-last bit indicates arithmetic or logical shift
                when(io.instruction(30)) {
                    io.alu_opcode := AluOpCode.ShiftArithmeticRight
                }.otherwise {
                    io.alu_opcode := AluOpCode.ShiftRight
                }
            }
        }
    }
}
