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