package projet

import chisel3._
import chisel3.util.switch
import chisel3.util.is
import chisel3.util.Cat
import chisel3.util.Fill

class ImmediateDecoder extends Module {
    import projet.OpType

    val io = IO(new Bundle {
        val op_type = Input(OpType())
        val instruction = Input(UInt(32.W))
        val immediate = Output(UInt(64.W))
    })
    io.immediate := 0.U

    // Decode and construct immediates
    val imm_u =
        Cat(Fill(32, io.instruction(31)), io.instruction(31, 12), 0.U(12.W));
    val imm_i = Cat(Fill(52, io.instruction(31)), io.instruction(31, 20));
    val imm_ir = io.instruction(25, 20);
    val imm_j = Cat(
        Fill(43, io.instruction(31)),
        io.instruction(31),
        io.instruction(19, 12),
        io.instruction(20),
        io.instruction(30, 21),
        0.U
    );
    val imm_b = Cat(
        Fill(51, io.instruction(31)),
        io.instruction(31),
        io.instruction(7),
        io.instruction(30, 25),
        io.instruction(11, 8),
        0.U
    )
    val imm_s = Cat(
        Fill(52, io.instruction(31)),
        io.instruction(31, 25),
        io.instruction(11, 7)
    )

    switch(io.op_type) {
        is(OpType.U) {
            io.immediate := imm_u
        }
        is(OpType.I) {
            io.immediate := imm_i
        }
        is(OpType.IR) {
            io.immediate := imm_ir
        }
        is(OpType.J) {
            io.immediate := imm_j
        }
        is(OpType.B) {
            io.immediate := imm_b
        }
        is(OpType.S) {
            io.immediate := imm_s
        }
    }
}
