xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/CSREvent.scala (revision a38d1eab87777ed93b417106a7dfd58a062cee18)
1package xiangshan.backend.fu.NewCSR.CSREvents
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.{SignExt, ZeroExt}
7import xiangshan.HasXSParameter
8import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, PrivState}
9import xiangshan.backend.fu.NewCSR.CSRConfig._
10import xiangshan.backend.fu.NewCSR.CSRDefines.{HgatpMode, SatpMode}
11import xiangshan.backend.fu.NewCSR._
12
13trait CSREvents { self: NewCSR =>
14  val trapEntryDEvent = Module(new TrapEntryDEventModule)
15
16  val trapEntryMEvent = Module(new TrapEntryMEventModule)
17
18  val trapEntryMNEvent = Module(new TrapEntryMNEventModule())
19
20  val trapEntryHSEvent = Module(new TrapEntryHSEventModule)
21
22  val trapEntryVSEvent = Module(new TrapEntryVSEventModule)
23
24  val mretEvent  = Module(new MretEventModule)
25
26  val mnretEvent = Module(new MNretEventModule)
27
28  val sretEvent  = Module(new SretEventModule)
29
30  val dretEvent  = Module(new DretEventModule)
31
32  val events: Seq[Module with CSREventBase] = Seq(
33    trapEntryDEvent,
34    trapEntryMEvent,
35    trapEntryHSEvent,
36    trapEntryVSEvent,
37    mretEvent,
38    sretEvent,
39    dretEvent,
40  )
41
42  events.foreach(x => dontTouch(x.out))
43
44  val trapEntryEvents: Seq[Module with CSREventBase] = Seq(
45    trapEntryDEvent,
46    trapEntryMEvent,
47    trapEntryHSEvent,
48    trapEntryVSEvent,
49  )
50}
51
52trait EventUpdatePrivStateOutput {
53  val privState = ValidIO(new PrivState)
54}
55
56trait EventOutputBase {
57  import scala.reflect.runtime.{universe => ru}
58
59  def getBundleByName(name: String): Valid[CSRBundle] = {
60    val mirror: ru.Mirror = ru.runtimeMirror(getClass.getClassLoader)
61    val im = mirror.reflect(this)
62    val classSymbol: ru.ClassSymbol = im.symbol.asClass
63    val fieldSymbol = classSymbol.info.decl(ru.TermName(name)).asTerm
64    val fieldMirror: ru.FieldMirror = mirror.reflect(this).reflectField(fieldSymbol)
65    fieldMirror.get.asInstanceOf[Valid[CSRBundle]]
66  }
67}
68
69trait CSREventBase {
70  val valid = IO(Input(Bool()))
71  val in: Bundle
72  val out: Bundle
73
74  def genTrapVA(
75    transMode: PrivState,
76    satp: SatpBundle,
77    vsatp: SatpBundle,
78    hgatp: HgatpBundle,
79    addr: UInt,
80  ) = {
81    require(addr.getWidth >= 50)
82
83    val isBare =
84      transMode.isModeM ||
85      transMode.isModeHSorHU &&  satp.MODE === SatpMode.Bare ||
86      transMode.isVirtual    && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare
87    val isSv39 =
88      transMode.isModeHSorHU &&  satp.MODE === SatpMode.Sv39 ||
89      transMode.isVirtual    && vsatp.MODE === SatpMode.Sv39
90    val isSv48 =
91      transMode.isModeHSorHU &&  satp.MODE === SatpMode.Sv48 ||
92      transMode.isVirtual    && vsatp.MODE === SatpMode.Sv48
93    val isSv39x4 =
94      transMode.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4
95    val isSv48x4 =
96      transMode.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
97
98    val bareAddr   = ZeroExt(addr(PAddrWidth - 1, 0), XLEN)
99    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
100    val sv39Addr   = SignExt(addr.take(39), XLEN)
101    val sv39x4Addr = ZeroExt(addr.take(39 + 2), XLEN)
102    val sv48Addr   = SignExt(addr.take(48), XLEN)
103    val sv48x4Addr = ZeroExt(addr.take(48 + 2), XLEN)
104
105    val trapAddr = Mux1H(Seq(
106      isBare   -> bareAddr,
107      isSv39   -> sv39Addr,
108      isSv39x4 -> sv39x4Addr,
109      isSv48   -> sv48Addr,
110      isSv48x4 -> sv48x4Addr,
111    ))
112
113    trapAddr
114  }
115}
116
117class TrapEntryEventInput(implicit val p: Parameters) extends Bundle with HasXSParameter {
118  val causeNO = Input(new CauseBundle)
119  val trapPc = Input(UInt(VaddrMaxWidth.W))
120  val trapPcGPA = Input(UInt(GPAddrBits.W))
121  val trapInst = Input(ValidIO(UInt(InstWidth.W)))
122  val fetchMalTval = Input(UInt(XLEN.W))
123  val isCrossPageIPF = Input(Bool())
124  val isHls = Input(Bool())
125  val isFetchMalAddr = Input(Bool())
126  val isFetchBkpt = Input(Bool())
127  val trapIsForVSnonLeafPTE = Input(Bool())
128
129  // always current privilege
130  val iMode = Input(new PrivState())
131  // take MRPV into consideration
132  val dMode = Input(new PrivState())
133  // status
134  val privState = Input(new PrivState)
135  val mstatus = Input(new MstatusBundle)
136  val hstatus = Input(new HstatusBundle)
137  val sstatus = Input(new SstatusBundle)
138  val vsstatus = Input(new SstatusBundle)
139
140  val pcFromXtvec = Input(UInt(XLEN.W))
141
142  val satp = Input(new SatpBundle)
143  val vsatp = Input(new SatpBundle)
144  val hgatp = Input(new HgatpBundle)
145  // from mem
146  val memExceptionVAddr = Input(UInt(XLEN.W))
147  val memExceptionGPAddr = Input(UInt(XLEN.W))
148  val memExceptionIsForVSnonLeafPTE = Input(Bool())
149  val virtualInterruptIsHvictlInject = Input(Bool())
150  val hvictlIID = Input(UInt(HIIDWidth.W))
151}
152
153trait EventSinkBundle { self: CSRModule[_ <: CSRBundle] =>
154  protected def addUpdateBundleInCSREnumType(updateBundle: ValidIO[CSRBundle]): Unit = {
155    (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
156      if (updateBundle.bits.eventFields.contains(source)) {
157        sink.addOtherUpdate(updateBundle.valid, source)
158      }
159    }
160  }
161}
162
163class TargetPCBundle extends Bundle {
164  val pc = UInt(XLEN.W)
165  val raiseIPF = Bool()
166  val raiseIAF = Bool()
167  val raiseIGPF = Bool()
168
169  def raiseFault = raiseIPF || raiseIAF || raiseIGPF
170}
171