1package xiangshan.backend.fu.NewCSR.CSREvents 2 3import chisel3._ 4import chisel3.util._ 5import utility.{SignExt, ZeroExt} 6import xiangshan.ExceptionNO 7import xiangshan.ExceptionNO._ 8import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState} 9import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN} 10import xiangshan.backend.fu.NewCSR.CSRDefines.{PrivMode, SatpMode, VirtMode} 11import xiangshan.backend.fu.NewCSR._ 12 13 14class MNretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 15 val mnstatus = ValidIO((new MnstatusBundle).addInEvent(_.MNPP, _.MNPV, _.NMIE)) 16 val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPRV)) 17 val targetPc = ValidIO(UInt(VaddrMaxWidth.W)) 18 19 override def getBundleByName(name: String): ValidIO[CSRBundle] = { 20 name match { 21 case "mnstatus" => this.mnstatus 22 case "mstatus" => this.mstatus 23 } 24 } 25} 26 27class MNretEventInput extends Bundle { 28 val mnstatus = Input(new MnstatusBundle) 29 val mstatus = Input(new MstatusBundle) 30 val mnepc = Input(new Epc()) 31} 32 33class MNretEventModule extends Module with CSREventBase { 34 val in = IO(new MNretEventInput) 35 val out = IO(new MNretEventOutput) 36 37 out := DontCare 38 39 out.privState.valid := valid 40 out.mnstatus .valid := valid 41 out.targetPc .valid := valid 42 43 out.privState.bits.PRVM := in.mnstatus.MNPP 44 out.privState.bits.V := Mux(in.mnstatus.MNPP === PrivMode.M, VirtMode.Off.asUInt, in.mnstatus.MNPV.asUInt) 45 out.mnstatus.bits.MNPP := PrivMode.U 46 out.mnstatus.bits.MNPV := VirtMode.Off.asUInt 47 out.mnstatus.bits.NMIE := 1.U 48 out.mstatus.bits.MPRV := Mux(in.mnstatus.MNPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt) 49 out.targetPc.bits := in.mnepc.asUInt 50} 51 52trait MNretEventSinkBundle { self: CSRModule[_] => 53 val retFromMN = IO(Flipped(new MNretEventOutput)) 54 55 private val updateBundle: ValidIO[CSRBundle] = retFromMN.getBundleByName(self.modName.toLowerCase()) 56 57 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 58 if (updateBundle.bits.eventFields.contains(source)) { 59 when(updateBundle.valid) { 60 sink := source 61 } 62 } 63 } 64 65}