diff --git a/src/main/scala/Xim/CPU_Core.scala b/src/main/scala/Xim/CPU_Core.scala index d18e997..e0ac960 100644 --- a/src/main/scala/Xim/CPU_Core.scala +++ b/src/main/scala/Xim/CPU_Core.scala @@ -84,6 +84,7 @@ class CPU_Core(val rv_width: Int = 64, inSOC: Boolean = false) extends Module { PrivModule.io.sstatus_spp := CSRModule.io.sstatus_spp CSRModule.io.priv_level := PrivModule.io.priv_level PrivModule.io.deleg_trap := CSRModule.io.deleg_trap + EX_Stage.io.priv_level := PrivModule.io.priv_level EX_Stage.io.mepc := CSRModule.io.mepc EX_Stage.io.sepc := CSRModule.io.sepc diff --git a/src/main/scala/Xim/CPU_EX.scala b/src/main/scala/Xim/CPU_EX.scala index 0908bc9..ad77b48 100644 --- a/src/main/scala/Xim/CPU_EX.scala +++ b/src/main/scala/Xim/CPU_EX.scala @@ -67,6 +67,7 @@ class CPU_EX(val rv_width: Int = 64) extends Module { val csr_mtvec = Input(UInt(rv_width.W)) val csr_timer_int = Input(UInt(1.W)) val mstatus_tsr = Input(UInt(1.W)) + val priv_level = Input(UInt(2.W)) }) val es_valid = RegInit(0.U(1.W)) @@ -976,7 +977,13 @@ class CPU_EX(val rv_width: Int = 64) extends Module { } .else*/when (es_valid === 1.U && fs_ex_r === 1.U) { es_excode := fs_excode_r } .elsewhen (es_valid === 1.U && es_ecall === 1.U) { - es_excode := excode_const.MEcall + when (io.priv_level === priv_consts.Machine) { + es_excode := excode_const.MEcall + } .elsewhen (io.priv_level === priv_consts.Supervisor) { + es_excode := excode_const.SEcall + } .otherwise { + es_excode := excode_const.UEcall + } } .elsewhen (es_valid === 1.U && inst_reserved === 1.U) { es_excode := excode_const.IllegalInstruction } .elsewhen (es_valid === 1.U && es_read_ex === 1.U) { @@ -984,7 +991,13 @@ class CPU_EX(val rv_width: Int = 64) extends Module { } .elsewhen (es_valid === 1.U && es_write_ex === 1.U) { es_excode := excode_const.StoreAddrMisaligned } .elsewhen (es_valid === 1.U && timer_int_r === 1.U) { - es_excode := excode_const.MachineTimerInt + when (io.priv_level === priv_consts.Machine) { + es_excode := excode_const.MachineTimerInt + } .elsewhen (io.priv_level === priv_consts.Supervisor) { + es_excode := excode_const.SupervisorTimerInt + } .otherwise { + es_excode := excode_const.UserTimerInt + } } .otherwise { es_excode := 0.U } diff --git a/src/main/scala/Xim/csr.scala b/src/main/scala/Xim/csr.scala index 6289358..f899550 100644 --- a/src/main/scala/Xim/csr.scala +++ b/src/main/scala/Xim/csr.scala @@ -332,10 +332,15 @@ class CSR(val rv_width: Int = 64) extends Module { val csr_stval = RegInit(reset_stval) val isInterrupt = Wire(Bool()) - isInterrupt := io.es_excode(rv_width - 1) === 1.U val deleg = Wire(Bool()) + val SupervisorTIDeleg = Wire(UInt(1.W)) + val UserTIDeleg = Wire(UInt(1.W)) + + isInterrupt := io.es_excode(rv_width - 1) === 1.U deleg := ((isInterrupt && csr_mideleg.value(io.es_excode(3,0))) || (!isInterrupt && csr_medeleg.value(io.es_excode(3,0))) && io.priv_level =/= priv_consts.Machine) io.deleg_trap := deleg + SupervisorTIDeleg := csr_mideleg.value(5) + UserTIDeleg := csr_mideleg.value(4) when (io.es_new_instr === 1.U && io.es_ex === 1.U) { es_ex_once := 1.U @@ -367,6 +372,33 @@ class CSR(val rv_width: Int = 64) extends Module { csr_mhartid.zero := 0.U + // timer interrupt + when (mtime_full === mtimecmp_full) { + when (io.priv_level === priv_consts.Machine) { + csr_mip.MTIP := 1.U + } .elsewhen (io.priv_level === priv_consts.Supervisor) { + when (SupervisorTIDeleg === 1.U) { + csr_sip.STIP := 1.U + } .otherwise { + csr_mip.MTIP := 1.U + } + } .otherwise { + when (UserTIDeleg === 1.U) { + csr_sip.STIP := 1.U + } .otherwise { + csr_mip.MTIP := 1.U + } + } + } + + when (csr_mip.MTIP === 1.U && csr_mstatus.MIE === 1.U && csr_mie.MTIE === 1.U) { + time_int := 1.U + } .elsewhen (csr_sip.STIP === 1.U && csr_sstatus.SIE === 1.U && csr_sie.STIE === 1.U) { + time_int := 1.U + } .otherwise { + time_int := 0.U + } + // MSTATUS when (es_ex_once === 1.U && !deleg) { csr_mstatus.MPIE := csr_mstatus.MIE @@ -423,17 +455,9 @@ class CSR(val rv_width: Int = 64) extends Module { csr_mip.MEIP := io.es_csr_write_data(11) } - when (csr_mip.MTIP === 1.U && csr_mstatus.MIE === 1.U && csr_mie.MTIE === 1.U) { - time_int := 1.U - } .otherwise { - time_int := 0.U - } - when (io.es_csr_wr === 1.U && (io.es_csr_write_num === csr_consts.MTIME || io.es_csr_write_num === csr_consts.MTIMECMP )) { csr_mip.MTIP := 0.U - } .elsewhen (mtime_full === mtimecmp_full) { - csr_mip.MTIP := 1.U } //io.mip := csr_mip.asUInt() @@ -550,6 +574,48 @@ class CSR(val rv_width: Int = 64) extends Module { // DIRECT Mode only } + // SIP + when (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.SIP) { + csr_sip.SEIP := io.es_csr_write_data(9) + } + + when (io.es_csr_wr === 1.U && (io.es_csr_write_num === csr_consts.MTIME || + io.es_csr_write_num === csr_consts.MTIMECMP )) { + csr_sip.STIP := 0.U + } + + // SIE + when (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.SIE) { + csr_sie.SEIE := io.es_csr_write_data(9) + csr_sie.STIE := io.es_csr_write_data(5) + csr_sie.SSIE := io.es_csr_write_data(1) + } + + // SSCRATCH + when (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.SSCRATCH) { + csr_sscratch.value := io.es_csr_write_data + } + + // SCAUSE + // excode is generated in pipeline + when (es_ex_once === 1.U && deleg) { + csr_scause.excode := io.es_excode(rv_width - 2, 0) + csr_scause.interrupt := io.es_excode(rv_width - 1) + } .elsewhen (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.SCAUSE) { + csr_scause.interrupt := io.es_csr_write_data(rv_width - 1) + csr_scause.excode := io.es_csr_write_data(rv_width - 2, 0) + } + + // STVAL + csr_stval.value := RegInit(0.U) + when (es_ex_once === 1.U && io.es_excode === excode_const.IllegalInstruction && deleg) { + csr_stval.value := io.fault_instr + } .elsewhen (es_ex_once === 1.U && (io.es_excode === excode_const.StoreAddrMisaligned || io.es_excode === excode_const.LoadAddrMisaligned || io.es_excode === excode_const.InstructionMisaligned) && deleg) { + csr_stval.value := io.fault_addr + } .elsewhen (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.STVAL) { + csr_stval.value := io.es_csr_write_data + } + // READ Data path when (io.es_csr_read_num === csr_consts.MSTATUS) { @@ -582,6 +648,22 @@ class CSR(val rv_width: Int = 64) extends Module { io.es_csr_read_data := csr_mtimecmp.asUInt() } .elsewhen (io.es_csr_read_num === csr_consts.MTIME) { io.es_csr_read_data := csr_mtime.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.SSTATUS) { + io.es_csr_read_data := csr_sstatus.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.STVEC) { + io.es_csr_read_data := csr_stvec.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.SEPC) { + io.es_csr_read_data := csr_sepc.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.SIP) { + io.es_csr_read_data := csr_sip.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.SIE) { + io.es_csr_read_data := csr_sie.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.SSCRATCH) { + io.es_csr_read_data := csr_sscratch.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.SCAUSE) { + io.es_csr_read_data := csr_scause.asUInt() + } .elsewhen (io.es_csr_read_num === csr_consts.STVAL) { + io.es_csr_read_data := csr_stval.asUInt() } .otherwise { // WARNING: TEST ONLY io.es_csr_read_data := csr_mtime.asUInt()