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