xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRPermitModule.scala (revision 881e32f5b63c435bafbaf5dc1d792ffcc9ea103e)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import chisel3.util.experimental.decode.TruthTable
6import freechips.rocketchip.rocket.CSRs
7import xiangshan.backend.fu.NewCSR.CSRBundles.{Counteren, PrivState}
8import xiangshan.backend.fu.NewCSR.CSRDefines._
9
10class CSRPermitModule extends Module {
11  val io = IO(new CSRPermitIO)
12
13  val xRetPermitMod = Module(new XRetPermitModule)
14  val mLevelPermitMod = Module(new MLevelPermitModule)
15  val sLevelPermitMod = Module(new SLevelPermitModule)
16  val privilegePermitMod = Module(new PrivilegePermitModule)
17  val virtualLevelPermitMod = Module(new VirtualLevelPermitModule)
18  val indirectCSRPermitMod = Module(new IndirectCSRPermitModule)
19
20  xRetPermitMod.io.in.privState := io.in.privState
21  xRetPermitMod.io.in.debugMode := io.in.debugMode
22  xRetPermitMod.io.in.xRet      := io.in.xRet
23  xRetPermitMod.io.in.status    := io.in.status
24
25  mLevelPermitMod.io.in.csrAccess  := io.in.csrAccess
26  mLevelPermitMod.io.in.privState  := io.in.privState
27  mLevelPermitMod.io.in.status     := io.in.status
28  mLevelPermitMod.io.in.xcounteren := io.in.xcounteren
29  mLevelPermitMod.io.in.xenvcfg    := io.in.xenvcfg
30  mLevelPermitMod.io.in.xstateen   := io.in.xstateen
31  mLevelPermitMod.io.in.aia        := io.in.aia
32
33  sLevelPermitMod.io.in.csrAccess  := io.in.csrAccess
34  sLevelPermitMod.io.in.privState  := io.in.privState
35  sLevelPermitMod.io.in.xcounteren := io.in.xcounteren
36  sLevelPermitMod.io.in.xstateen   := io.in.xstateen
37
38  privilegePermitMod.io.in.csrAccess := io.in.csrAccess
39  privilegePermitMod.io.in.privState := io.in.privState
40  privilegePermitMod.io.in.debugMode := io.in.debugMode
41
42  virtualLevelPermitMod.io.in.csrAccess   := io.in.csrAccess
43  virtualLevelPermitMod.io.in.privState   := io.in.privState
44  virtualLevelPermitMod.io.in.status      := io.in.status
45  virtualLevelPermitMod.io.in.xcounteren  := io.in.xcounteren
46  virtualLevelPermitMod.io.in.xenvcfg     := io.in.xenvcfg
47  virtualLevelPermitMod.io.in.xstateen    := io.in.xstateen
48  virtualLevelPermitMod.io.in.aia         := io.in.aia
49
50  indirectCSRPermitMod.io.in.csrAccess := io.in.csrAccess
51  indirectCSRPermitMod.io.in.privState := io.in.privState
52  indirectCSRPermitMod.io.in.aia       := io.in.aia
53
54  private val (ren, wen) = (
55    io.in.csrAccess.ren,
56    io.in.csrAccess.wen,
57  )
58
59  private val csrAccess = WireInit(ren || wen)
60
61  val mPermit_EX_II = mLevelPermitMod.io.out.mLevelPermit_EX_II
62
63  val sPermit_EX_II = sLevelPermitMod.io.out.sLevelPermit_EX_II
64
65  val pPermit_EX_II = privilegePermitMod.io.out.privilege_EX_II
66  val pPermit_EX_VI = privilegePermitMod.io.out.privilege_EX_VI
67
68  val vPermit_EX_II = virtualLevelPermitMod.io.out.virtualLevelPermit_EX_II
69  val vPermit_EX_VI = virtualLevelPermitMod.io.out.virtualLevelPermit_EX_VI
70
71  val indirectPermit_EX_II = indirectCSRPermitMod.io.out.indirectCSR_EX_II
72  val indirectPermit_EX_VI = indirectCSRPermitMod.io.out.indirectCSR_EX_VI
73
74  val directPermit_illegal = mPermit_EX_II || sPermit_EX_II || pPermit_EX_II || pPermit_EX_VI || vPermit_EX_II || vPermit_EX_VI
75
76  val csrAccess_EX_II = csrAccess && (
77    (mPermit_EX_II || sPermit_EX_II || pPermit_EX_II || vPermit_EX_II) ||
78    (!directPermit_illegal && indirectPermit_EX_II)
79  )
80  val csrAccess_EX_VI = csrAccess && (
81    (pPermit_EX_VI || vPermit_EX_VI) ||
82    (!directPermit_illegal && indirectPermit_EX_VI)
83  )
84
85  val Xret_EX_II = xRetPermitMod.io.out.Xret_EX_II
86  val Xret_EX_VI = xRetPermitMod.io.out.Xret_EX_VI
87
88  io.out.EX_II := csrAccess_EX_II || Xret_EX_II
89  io.out.EX_VI := !io.out.EX_II && (csrAccess_EX_VI || Xret_EX_VI)
90
91  io.out.hasLegalWen   := wen   && !(io.out.EX_II || io.out.EX_VI)
92  io.out.hasLegalMNret := xRetPermitMod.io.out.hasLegalMNret
93  io.out.hasLegalMret  := xRetPermitMod.io.out.hasLegalMret
94  io.out.hasLegalSret  := xRetPermitMod.io.out.hasLegalSret
95  io.out.hasLegalDret  := xRetPermitMod.io.out.hasLegalDret
96
97  io.out.hasLegalWriteFcsr := mLevelPermitMod.io.out.hasLegalWriteFcsr
98  io.out.hasLegalWriteVcsr := mLevelPermitMod.io.out.hasLegalWriteVcsr
99}
100
101class XRetPermitModule extends Module {
102  val io = IO(new Bundle() {
103    val in = Input(new Bundle {
104      val privState = new PrivState
105      val debugMode = Bool()
106      val xRet = new xRetIO
107      val status = new statusIO
108    })
109    val out = Output(new Bundle {
110      val Xret_EX_II = Bool()
111      val Xret_EX_VI = Bool()
112      val hasLegalMNret = Bool()
113      val hasLegalMret  = Bool()
114      val hasLegalSret  = Bool()
115      val hasLegalDret  = Bool()
116    })
117  })
118
119  private val (privState, debugMode) = (
120    io.in.privState,
121    io.in.debugMode,
122  )
123
124  private val (mnret, mret, sret, dret) = (
125    io.in.xRet.mnret,
126    io.in.xRet.mret,
127    io.in.xRet.sret,
128    io.in.xRet.dret,
129  )
130
131  private val (tsr, vtsr) = (
132    io.in.status.tsr,
133    io.in.status.vtsr,
134  )
135
136  private val mnret_EX_II = mnret && !privState.isModeM
137  private val mnretIllegal =  mnret_EX_II
138
139  private val mret_EX_II = mret && !privState.isModeM
140  private val mretIllegal = mret_EX_II
141
142  private val sret_EX_II = sret && (privState.isModeHU || privState.isModeHS && tsr)
143  private val sret_EX_VI = sret && (privState.isModeVU || privState.isModeVS && vtsr)
144  private val sretIllegal = sret_EX_II || sret_EX_VI
145
146  private val dret_EX_II = dret && !debugMode
147  private val dretIllegal = dret_EX_II
148
149  io.out.Xret_EX_II := mnret_EX_II || mret_EX_II || sret_EX_II || dret_EX_II
150  io.out.Xret_EX_VI := sret_EX_VI
151  io.out.hasLegalMNret := mnret && !mnretIllegal
152  io.out.hasLegalMret  := mret  && !mretIllegal
153  io.out.hasLegalSret  := sret  && !sretIllegal
154  io.out.hasLegalDret  := dret  && !dretIllegal
155}
156
157class MLevelPermitModule extends Module {
158  val io = IO(new Bundle() {
159    val in = Input(new Bundle {
160      val csrAccess = new csrAccessIO
161      val privState = new PrivState
162      val status = new statusIO
163      val xcounteren = new xcounterenIO
164      val xenvcfg = new xenvcfgIO
165      val xstateen = new xstateenIO
166      val aia = new aiaIO
167    })
168    val out = Output(new Bundle {
169      val mLevelPermit_EX_II = Bool()
170      val hasLegalWriteFcsr = Bool()
171      val hasLegalWriteVcsr = Bool()
172    })
173  })
174
175  private val (wen, addr, privState) = (
176    io.in.csrAccess.wen,
177    io.in.csrAccess.addr,
178    io.in.privState,
179  )
180
181  private val tvm = io.in.status.tvm
182
183  private val mcounteren = io.in.xcounteren.mcounteren
184
185  private val mstateen0 = io.in.xstateen.mstateen0
186
187  private val mcounterenTM = mcounteren(1)
188
189  private val menvcfg = io.in.xenvcfg.menvcfg
190
191  private val menvcfgSTCE = menvcfg(63)
192
193  private val (sFSIsOff, sVSIsOff, sOrVsFSIsOff, sOrVsVSIsOff) = (
194    io.in.status.mstatusFSOff,
195    io.in.status.mstatusVSOff,
196    io.in.status.mstatusFSOff || io.in.status.vsstatusFSOff,
197    io.in.status.mstatusVSOff || io.in.status.vsstatusVSOff,
198  )
199
200  private val mvienSEIE = io.in.aia.mvienSEIE
201
202  private val csrIsRO = addr(11, 10) === "b11".U
203  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
204  private val csrIsFp = Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _)
205  private val csrIsVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr, CSRs.vtype).map(_.U === addr).reduce(_ || _)
206  private val csrIsWritableVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _)
207  private val counterAddr = addr(4, 0) // 32 counters
208
209  private val rwIllegal = csrIsRO && wen
210
211  private val fsEffectiveOff = sFSIsOff && !privState.isVirtual || sOrVsFSIsOff && privState.isVirtual
212  private val vsEffectiveOff = sVSIsOff && !privState.isVirtual || sOrVsVSIsOff && privState.isVirtual
213
214  private val fpOff_EX_II  = csrIsFp  && fsEffectiveOff
215  private val vecOff_EX_II = csrIsVec && vsEffectiveOff
216
217  private val fpVec_EX_II = fpOff_EX_II || vecOff_EX_II
218
219  private val rwStimecmp_EX_II = !privState.isModeM && (!mcounterenTM || !menvcfgSTCE) && (addr === CSRs.vstimecmp.U || addr === CSRs.stimecmp.U)
220
221  private val accessHPM_EX_II = csrIsHPM && !privState.isModeM && !mcounteren(counterAddr)
222
223  private val rwSatp_EX_II = privState.isModeHS && tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U)
224
225  private val rwStopei_EX_II = privState.isModeHS && mvienSEIE && (addr === CSRs.stopei.U)
226
227  /**
228   * Sm/Ssstateen0 begin
229   */
230  // SE0 bit 63
231  private val csrIsHstateen0 = addr === CSRs.hstateen0.U
232  private val csrIsSstateen0 = addr === CSRs.sstateen0.U
233  private val csrIsStateen0 = csrIsHstateen0 || csrIsSstateen0
234  private val accessStateen0_EX_II = csrIsStateen0 && !privState.isModeM && !mstateen0.SE0.asBool
235
236  // ENVCFG bit 62
237  private val csrIsHenvcfg = addr === CSRs.henvcfg.U
238  private val csrIsSenvcfg = addr === CSRs.senvcfg.U
239  private val csrIsEnvcfg = csrIsHenvcfg || csrIsSenvcfg
240  private val accessEnvcfg_EX_II = csrIsEnvcfg && !privState.isModeM && !mstateen0.ENVCFG.asBool
241
242  // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented
243  // csr addr S: [0x150, 0x157]     VS: [0x250, 0x257]
244  private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9)
245  private val csrIsVSi = addr.head(9) === CSRs.vsiselect.U.head(9)
246  private val csrIsIND = csrIsSi || csrIsVSi
247  private val accessIND_EX_II = csrIsIND && !privState.isModeM && !mstateen0.CSRIND.asBool
248
249  // AIA bit 59
250  private val ssAiaHaddr = Seq(CSRs.hvien.U, CSRs.hvictl.U, CSRs.hviprio1.U, CSRs.hviprio2.U)
251  private val ssAiaVSaddr = addr === CSRs.vstopi.U
252  private val ssAiaSaddr = addr === CSRs.stopi.U
253  private val csrIsAIA = ssAiaHaddr.map(_ === addr).reduce(_ || _) || ssAiaVSaddr || ssAiaSaddr
254  private val accessAIA_EX_II = csrIsAIA && !privState.isModeM && !mstateen0.AIA.asBool
255
256  // IMSIC bit 58 (Ssaia extension)
257  private val csrIsStopei = addr === CSRs.stopei.U
258  private val csrIsVStopei = addr === CSRs.vstopei.U
259  private val csrIsTpoie = csrIsStopei || csrIsVStopei
260  private val accessTopie_EX_II = csrIsTpoie && !privState.isModeM && !mstateen0.IMSIC.asBool
261
262  // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented
263  private val csrIsHcontext = addr === CSRs.hcontext.U
264  private val csrIsScontext = addr === CSRs.scontext.U
265  private val csrIsContext = csrIsHcontext || csrIsScontext
266  private val accessContext_EX_II = csrIsContext && !privState.isModeM && !mstateen0.CONTEXT.asBool
267
268  // P1P13 bit 56, Read-only 0
269
270  // Custom bit 0
271  // csr addr HVS: [0x6c0, 0x6ff], [0xac0, 0xaff], [0xec0, 0xeff]
272  private val csrIsHVSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b10".U) && (addr(7, 6) === "b11".U)
273  // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff]
274  private val csrIsSCustom   = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U)
275  // [0x800, 0x8ff], [0xcc0, 0xcff]
276  private val csrIsUCustom   = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U)
277  private val allCustom      = csrIsHVSCustom || csrIsSCustom || csrIsUCustom
278  private val accessCustom_EX_II = allCustom && !privState.isModeM && !mstateen0.C.asBool
279
280  val xstateControlAccess_EX_II = accessStateen0_EX_II || accessEnvcfg_EX_II || accessIND_EX_II || accessAIA_EX_II ||
281    accessTopie_EX_II || accessContext_EX_II || accessCustom_EX_II
282  /**
283   * Sm/Ssstateen end
284   */
285
286  io.out.mLevelPermit_EX_II := rwIllegal || fpVec_EX_II || rwStimecmp_EX_II ||
287    accessHPM_EX_II || rwSatp_EX_II || rwStopei_EX_II || xstateControlAccess_EX_II
288  io.out.hasLegalWriteFcsr := wen && csrIsFp && !fsEffectiveOff
289  io.out.hasLegalWriteVcsr := wen && csrIsWritableVec && !vsEffectiveOff
290}
291
292class SLevelPermitModule extends Module {
293  val io = IO(new Bundle() {
294    val in = Input(new Bundle {
295      val csrAccess = new csrAccessIO
296      val privState = new PrivState
297      val xcounteren = new xcounterenIO
298      val xstateen = new xstateenIO
299    })
300    val out = Output(new Bundle {
301      val sLevelPermit_EX_II = Bool()
302    })
303  })
304
305  private val (addr, privState) = (
306    io.in.csrAccess.addr,
307    io.in.privState,
308  )
309
310  private val scounteren = io.in.xcounteren.scounteren
311
312  private val sstateen0 = io.in.xstateen.sstateen0
313
314  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
315  private val counterAddr = addr(4, 0) // 32 counters
316
317  private val accessHPM_EX_II = csrIsHPM && privState.isModeHU && !scounteren(counterAddr)
318
319  private val csrIsUCustom   = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U)
320  private val accessCustom_EX_II = csrIsUCustom && privState.isModeHU && !sstateen0.C.asBool
321
322  io.out.sLevelPermit_EX_II := accessHPM_EX_II || accessCustom_EX_II
323}
324
325class PrivilegePermitModule extends Module {
326  val io = IO(new Bundle() {
327    val in = Input(new Bundle {
328      val csrAccess = new csrAccessIO
329      val privState = new PrivState
330      val debugMode = Bool()
331    })
332    val out = Output(new Bundle {
333      val privilege_EX_II = Bool()
334      val privilege_EX_VI = Bool()
335    })
336  })
337
338  private val (addr, privState, debugMode) = (
339    io.in.csrAccess.addr,
340    io.in.privState,
341    io.in.debugMode
342  )
343
344  private val accessTable = TruthTable(Seq(
345    //       V PRVM ADDR
346    BitPat("b0__00___00") -> BitPat.Y(), // HU access U
347    BitPat("b1__00___00") -> BitPat.Y(), // VU access U
348    BitPat("b0__01___00") -> BitPat.Y(), // HS access U
349    BitPat("b0__01___01") -> BitPat.Y(), // HS access S
350    BitPat("b0__01___10") -> BitPat.Y(), // HS access H
351    BitPat("b1__01___00") -> BitPat.Y(), // VS access U
352    BitPat("b1__01___01") -> BitPat.Y(), // VS access S
353    BitPat("b0__11___00") -> BitPat.Y(), // M  access HU
354    BitPat("b0__11___01") -> BitPat.Y(), // M  access HS
355    BitPat("b0__11___10") -> BitPat.Y(), // M  access H
356    BitPat("b0__11___11") -> BitPat.Y(), // M  access M
357  ), BitPat.N())
358
359  private val regularPrivilegeLegal = chisel3.util.experimental.decode.decoder(
360    privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8),
361    accessTable
362  ).asBool
363
364  private val csrIsM = addr(9, 8) === "b11".U
365  private val isDebugReg   = addr(11, 4) === "h7b".U
366  private val privilegeLegal = Mux(isDebugReg, debugMode, regularPrivilegeLegal || debugMode)
367
368  io.out.privilege_EX_II := !privilegeLegal && (!privState.isVirtual || csrIsM)
369  io.out.privilege_EX_VI := !privilegeLegal && privState.isVirtual && !csrIsM
370}
371
372class VirtualLevelPermitModule extends Module {
373  val io = IO(new Bundle() {
374    val in = Input(new Bundle {
375      val csrAccess = new csrAccessIO
376      val privState = new PrivState
377      val status = new statusIO
378      val xcounteren = new xcounterenIO
379      val xenvcfg = new xenvcfgIO
380      val xstateen = new xstateenIO
381      val aia = new aiaIO
382    })
383    val out = Output(new Bundle {
384      val virtualLevelPermit_EX_II = Bool()
385      val virtualLevelPermit_EX_VI = Bool()
386    })
387  })
388
389  private val (wen, addr, privState) = (
390    io.in.csrAccess.wen,
391    io.in.csrAccess.addr,
392    io.in.privState,
393  )
394
395  private val (vtvm, vgein) = (
396    io.in.status.vtvm,
397    io.in.status.vgein,
398  )
399
400  private val (hcounteren, scounteren) = (
401    io.in.xcounteren.hcounteren,
402    io.in.xcounteren.scounteren,
403  )
404
405  private val hcounterenTM = hcounteren(1)
406
407  private val henvcfg = io.in.xenvcfg.henvcfg
408
409  private val henvcfgSTCE = henvcfg(63)
410
411  private val (hstateen0, sstateen0) = (
412    io.in.xstateen.hstateen0,
413    io.in.xstateen.sstateen0,
414  )
415
416  private val hvictlVTI = io.in.aia.hvictlVTI
417
418  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
419  private val counterAddr = addr(4, 0) // 32 counters
420
421  private val rwSatp_EX_VI = privState.isModeVS && vtvm && (addr === CSRs.satp.U)
422
423  private val rwVStopei_EX_II = (privState.isModeM || privState.isModeHS) && (addr === CSRs.vstopei.U) && (vgein === 0.U || vgein > CSRConfig.GEILEN.U)
424  private val rwStopei_EX_VI = privState.isModeVS && (addr === CSRs.stopei.U) && (vgein === 0.U || vgein > CSRConfig.GEILEN.U)
425
426  private val rwSip_Sie_EX_VI = privState.isModeVS && hvictlVTI && (addr === CSRs.sip.U || addr === CSRs.sie.U)
427
428  private val rwStimecmp_EX_VI = privState.isModeVS && (addr === CSRs.stimecmp.U) &&
429    (!hcounterenTM || !henvcfgSTCE || wen && hvictlVTI)
430
431  private val accessHPM_EX_VI = csrIsHPM && (
432      privState.isModeVS && !hcounteren(counterAddr) ||
433      privState.isModeVU && (!hcounteren(counterAddr) || !scounteren(counterAddr))
434    )
435
436  /**
437   * Sm/Ssstateen0 begin
438   */
439  // SE0 bit 63
440  private val csrIsSstateen0 = addr === CSRs.sstateen0.U
441  private val accessStateen0_EX_VI = csrIsSstateen0 && privState.isVirtual && !hstateen0.SE0.asBool
442
443  // ENVCFG bit 62
444  private val csrIsSenvcfg = addr === CSRs.senvcfg.U
445  private val accessEnvcfg_EX_VI = csrIsSenvcfg && privState.isVirtual && !hstateen0.ENVCFG.asBool
446
447  // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented
448  // csr addr S: [0x150, 0x157]
449  private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9)
450  private val accessIND_EX_VI = csrIsSi && privState.isVirtual && !hstateen0.CSRIND.asBool
451
452  // AIA bit 59
453  private val ssAiaSaddr = addr === CSRs.stopi.U
454  private val accessAIA_EX_VI = ssAiaSaddr && privState.isVirtual && !hstateen0.AIA.asBool
455
456  // IMSIC bit 58 (Ssaia extension)
457  private val csrIsStopei = addr === CSRs.stopei.U
458  private val accessTopie_EX_VI = csrIsStopei && privState.isVirtual && !hstateen0.IMSIC.asBool
459
460  // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented
461  private val csrIsScontext = addr === CSRs.scontext.U
462  private val accessContext_EX_VI = csrIsScontext && privState.isVirtual && !hstateen0.CONTEXT.asBool
463
464  // P1P13 bit 56, Read-only 0
465
466  // Custom bit 0
467  // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff]
468  private val csrIsSCustom   = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U)
469  // [0x800, 0x8ff], [0xcc0, 0xcff]
470  private val csrIsUCustom   = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U)
471  private val accessCustom_EX_VI = (csrIsSCustom || csrIsUCustom) && privState.isVirtual && !hstateen0.C.asBool ||
472    csrIsUCustom && privState.isModeVU && hstateen0.C.asBool && !sstateen0.C.asBool
473
474  private val xstateControlAccess_EX_VI = accessStateen0_EX_VI || accessEnvcfg_EX_VI || accessIND_EX_VI || accessAIA_EX_VI ||
475    accessTopie_EX_VI || accessContext_EX_VI || accessCustom_EX_VI
476
477  io.out.virtualLevelPermit_EX_II := rwVStopei_EX_II
478  io.out.virtualLevelPermit_EX_VI := rwSatp_EX_VI || rwStopei_EX_VI || rwSip_Sie_EX_VI || rwStimecmp_EX_VI || accessHPM_EX_VI || xstateControlAccess_EX_VI
479}
480
481class IndirectCSRPermitModule extends Module {
482  val io = IO(new Bundle() {
483    val in = Input(new Bundle {
484      val csrAccess = new csrAccessIO
485      val privState = new PrivState
486      val aia = new aiaIO
487    })
488    val out = Output(new Bundle {
489      val indirectCSR_EX_II = Bool()
490      val indirectCSR_EX_VI = Bool()
491    })
492  })
493
494  private val (addr, privState) = (
495    io.in.csrAccess.addr,
496    io.in.privState,
497  )
498
499  private val (miselectIsIllegal, siselectIsIllegal, vsiselectIsIllegal) = (
500    io.in.aia.miselectIsIllegal,
501    io.in.aia.siselectIsIllegal,
502    io.in.aia.vsiselectIsIllegal,
503  )
504
505  private val (siselect, vsiselect) = (
506    io.in.aia.siselect,
507    io.in.aia.vsiselect,
508  )
509
510  private val mvienSEIE = io.in.aia.mvienSEIE
511
512  private val rwMireg_EX_II = miselectIsIllegal && addr === CSRs.mireg.U
513
514  private val rwSireg_EX_II = (
515      (privState.isModeHS && mvienSEIE && siselect >= 0x70.U && siselect <= 0xFF.U) ||
516      ((privState.isModeM || privState.isModeHS) && siselectIsIllegal) ||
517      (privState.isModeVS && (vsiselect < 0x30.U || (vsiselect >= 0x40.U && vsiselect < 0x70.U) || vsiselect > 0xFF.U))
518    ) && addr === CSRs.sireg.U
519
520  private val rwSireg_EX_VI = privState.isModeVS && (vsiselect >= 0x30.U && vsiselect <= 0x3F.U) && addr === CSRs.sireg.U
521
522  private val rwVSireg_EX_II = vsiselectIsIllegal && addr === CSRs.vsireg.U
523
524  io.out.indirectCSR_EX_II := rwMireg_EX_II || rwSireg_EX_II || rwVSireg_EX_II
525  io.out.indirectCSR_EX_VI := rwSireg_EX_VI
526}
527
528class csrAccessIO extends Bundle {
529  val ren   = Bool()
530  val wen   = Bool()
531  val addr  = UInt(12.W)
532}
533
534class xRetIO extends Bundle {
535  val mnret = Bool()
536  val mret = Bool()
537  val sret = Bool()
538  val dret = Bool()
539}
540
541class statusIO extends Bundle {
542  // Trap SRET
543  val tsr = Bool()
544  // Virtual Trap SRET
545  val vtsr = Bool()
546  // Trap Virtual Memory
547  val tvm = Bool()
548  // Virtual Trap Virtual Memory
549  val vtvm = Bool()
550  val vgein = UInt(6.W)
551  val mstatusFSOff = Bool()
552  val vsstatusFSOff = Bool()
553  val mstatusVSOff = Bool()
554  val vsstatusVSOff = Bool()
555}
556
557class xcounterenIO extends Bundle {
558  // Machine level counter enable, access PMC from the level less than M will trap EX_II
559  val mcounteren = UInt(32.W)
560  // Hypervisor level counter enable.
561  // Accessing PMC from VS/VU level will trap EX_VI, if m[x]=1 && h[x]=0
562  val hcounteren = UInt(32.W)
563  // Supervisor level counter enable.
564  // Accessing PMC from **HU level** will trap EX_II, if s[x]=0
565  // Accessing PMC from **VU level** will trap EX_VI, if m[x]=1 && h[x]=1 && s[x]=0
566  val scounteren = UInt(32.W)
567}
568
569class xenvcfgIO extends Bundle {
570  // Machine environment configuration register.
571  // Accessing stimecmp or vstimecmp from **Non-M level** will trap EX_II, if menvcfg.STCE=0
572  val menvcfg = UInt(64.W)
573  // Hypervisor environment configuration register.
574  // Accessing vstimecmp from ** V level** will trap EX_VI, if menvcfg.STCE=1 && henvcfg.STCE=0
575  val henvcfg = UInt(64.W)
576}
577
578class xstateenIO extends Bundle {
579  // Sm/Ssstateen: to control state access
580  val mstateen0 = new MstateenBundle0
581  val hstateen0 = new HstateenBundle0
582  val sstateen0 = new SstateenBundle0
583}
584
585class aiaIO extends Bundle {
586  val miselectIsIllegal = Bool()
587  val siselectIsIllegal = Bool()
588  val vsiselectIsIllegal = Bool()
589  val siselect = UInt(64.W)
590  val vsiselect = UInt(64.W)
591  val mvienSEIE = Bool()
592  val hvictlVTI = Bool()
593}
594
595class CSRPermitIO extends Bundle {
596  val in = Input(new Bundle {
597    val csrAccess = new csrAccessIO
598    val privState = new PrivState
599    val debugMode = Bool()
600    val xRet = new xRetIO
601    val status = new statusIO
602    val xcounteren = new xcounterenIO
603    val xenvcfg = new xenvcfgIO
604    val xstateen = new xstateenIO
605    val aia = new aiaIO
606  })
607
608  val out = Output(new Bundle {
609    val hasLegalWen   = Bool()
610    val hasLegalMNret = Bool()
611    val hasLegalMret  = Bool()
612    val hasLegalSret  = Bool()
613    val hasLegalDret  = Bool()
614    val hasLegalWriteFcsr = Bool()
615    val hasLegalWriteVcsr = Bool()
616    val EX_II = Bool()
617    val EX_VI = Bool()
618  })
619}
620