package projet
import chisel3._

/*\
 * Principalement le timer pour pouvoir faire tourner space invaders !
\*/
class CLint extends Module {
    val io = IO(new Bundle {
        val bus = new BusInterface
        val tip = Output(Bool())
    })

    // Adresses des deux registres 64 bits du composant
    val MTIMERCMP_ADDR = 0x4000
    val MTIMER_ADDR = 0xbff8

    // Sur le rv32i le timer est constitué de 2 registres pour faire 64 bits
    val mtime = RegInit(0.U(64.W))

    // Free running, comme on dit chez nous !
    mtime := mtime + 1.U

    // La comparaison nécessite également 2 registres, pour une
    // comparaison sur 64 bits si nécessaire
    val mtimecmp = RegInit(0.U(64.W))
    // Sortie mtimer interrupt pending dont on se moque pour l'instant
    io.tip := (mtime > mtimecmp)
    // Valeur par défaut sur le bus de lecture
    // avec toujours un cycle de latence
    val clintRegValue = RegInit(0.U(64.W))

    io.bus.rdata := clintRegValue

    when(io.bus.en === true.B) {
        when(io.bus.be.asUInt.orR) { // Écriture
            when(io.bus.addr === MTIMERCMP_ADDR.U) {
                mtimecmp := io.bus.wdata
            }
        }.otherwise { // Lecture
            when(io.bus.addr === MTIMER_ADDR.U) {
                clintRegValue := mtime
            }.elsewhen(io.bus.addr === MTIMERCMP_ADDR.U) {
                clintRegValue := mtimecmp
            }
        }
    }
}
