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._ 12import xiangshan.backend.fu.util.CSRConst 13 14 15class SretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 16 // Todo: write sstatus instead of mstatus 17 val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV)) 18 val hstatus = ValidIO((new HstatusBundle).addInEvent(_.SPV)) 19 val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP)) 20 val targetPc = ValidIO(new Epc().addInEvent(_.ALL)) 21 22 override def getBundleByName(name: String): ValidIO[CSRBundle] = { 23 name match { 24 case "mstatus" => this.mstatus 25 case "hstatus" => this.hstatus 26 case "vsstatus" => this.vsstatus 27 } 28 } 29} 30 31class SretEventInput extends Bundle { 32 val privState = Input(new PrivState) 33 val sstatus = Input(new SstatusBundle) 34 val hstatus = Input(new HstatusBundle) 35 val vsstatus = Input(new SstatusBundle) 36 val sepc = Input(new Epc()) 37 val vsepc = Input(new Epc()) 38} 39 40class SretEventModule extends Module with CSREventBase { 41 val in = IO(new SretEventInput) 42 val out = IO(new SretEventOutput) 43 44 val sretInHSorM = in.privState.isModeM || in.privState.isModeHS 45 val sretInVS = in.privState.isModeVS 46 47 out := DontCare 48 49 out.privState.valid := valid 50 out.targetPc .valid := valid 51 52 out.privState.bits.PRVM := Mux1H(Seq( 53 // SPP is not PrivMode enum type, so asUInt 54 sretInHSorM -> in.sstatus.SPP.asUInt, 55 sretInVS -> in.vsstatus.SPP.asUInt, 56 )) 57 out.privState.bits.V := Mux1H(Seq( 58 sretInHSorM -> in.hstatus.SPV, 59 sretInVS -> in.privState.V, // keep 60 )) 61 62 // hstatus 63 out.hstatus.valid := valid && sretInHSorM 64 out.hstatus.bits.SPV := VirtMode.Off 65 66 // sstatus 67 out.mstatus.valid := valid && sretInHSorM 68 out.mstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 69 out.mstatus.bits.SIE := in.sstatus.SPIE 70 out.mstatus.bits.SPIE := 1.U 71 out.mstatus.bits.MPRV := 0.U // sret will always leave M mode 72 73 // vsstatus 74 out.vsstatus.valid := valid && sretInVS 75 out.vsstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 76 out.vsstatus.bits.SIE := in.vsstatus.SPIE 77 out.vsstatus.bits.SPIE := 1.U 78 79 out.targetPc.bits := Mux1H(Seq( 80 sretInHSorM -> in.sepc, 81 sretInVS -> in.vsepc, 82 )) 83 84 // for better verilog 85 dontTouch(sretInHSorM) 86 dontTouch(sretInVS) 87} 88 89trait SretEventSinkBundle { self: CSRModule[_] => 90 val retFromS = IO(Flipped(new SretEventOutput)) 91 92 private val updateBundle: ValidIO[CSRBundle] = retFromS.getBundleByName(self.modName.toLowerCase()) 93 94 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 95 if (updateBundle.bits.eventFields.contains(source)) { 96 when(updateBundle.valid) { 97 sink := source 98 } 99 } 100 } 101} 102