xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRPermitModule.scala (revision bf652b44938d589a2cbab79a8b890c4e3d22b640)
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  private val (ren, wen, addr, privState, debugMode) = (
14    io.in.csrAccess.ren,
15    io.in.csrAccess.wen,
16    io.in.csrAccess.addr,
17    io.in.privState,
18    io.in.debugMode
19  )
20
21  private val csrAccess = WireInit(ren || wen)
22
23  private val (mnret, mret, sret, dret) = (
24    io.in.mnret,
25    io.in.mret,
26    io.in.sret,
27    io.in.dret,
28  )
29
30  private val (tsr, vtsr) = (
31    io.in.status.tsr,
32    io.in.status.vtsr,
33  )
34
35  private val (tvm, vtvm) = (
36    io.in.status.tvm,
37    io.in.status.vtvm,
38  )
39
40  private val csrIsCustom = io.in.csrIsCustom
41
42  private val (mcounteren, hcounteren, scounteren) = (
43    io.in.status.mcounteren,
44    io.in.status.hcounteren,
45    io.in.status.scounteren,
46  )
47
48  private val (mstateen0, hstateen0, sstateen0) = (
49    io.in.status.mstateen0,
50    io.in.status.hstateen0,
51    io.in.status.sstateen0,
52  )
53
54  private val (mcounterenTM, hcounterenTM) = (
55    mcounteren(1),
56    hcounteren(1),
57  )
58
59  private val (menvcfg, henvcfg) = (
60    io.in.status.menvcfg,
61    io.in.status.henvcfg,
62  )
63
64  private val (menvcfgSTCE, henvcfgSTCE) = (
65    menvcfg(63),
66    henvcfg(63),
67  )
68
69  private val (sFSIsOff, sVSIsOff, sOrVsFSIsOff, sOrVsVSIsOff) = (
70    io.in.status.mstatusFSOff,
71    io.in.status.mstatusVSOff,
72    io.in.status.mstatusFSOff || io.in.status.vsstatusFSOff,
73    io.in.status.mstatusVSOff || io.in.status.vsstatusVSOff,
74  )
75
76  private val (miselectIsIllegal, siselectIsIllegal, vsiselectIsIllegal) = (
77    io.in.aia.miselectIsIllegal,
78    io.in.aia.siselectIsIllegal,
79    io.in.aia.vsiselectIsIllegal,
80  )
81
82  private val (siselect, vsiselect) = (
83    io.in.aia.siselect,
84    io.in.aia.vsiselect,
85  )
86
87  private val (mvienSEIE, hvictlVTI) = (
88    io.in.aia.mvienSEIE,
89    io.in.aia.hvictlVTI,
90  )
91
92  private val csrIsRO = addr(11, 10) === "b11".U
93  private val csrIsUnpriv = addr(9, 8) === "b00".U
94  private val csrIsM = addr(9, 8) === "b11".U
95  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
96  private val csrIsFp = Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _)
97  private val csrIsVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr, CSRs.vtype).map(_.U === addr).reduce(_ || _)
98  private val csrIsWritableVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _)
99  private val counterAddr = addr(4, 0) // 32 counters
100
101  private val accessTable = TruthTable(Seq(
102    //       V PRVM ADDR
103    BitPat("b0__00___00") -> BitPat.Y(), // HU access U
104    BitPat("b1__00___00") -> BitPat.Y(), // VU access U
105    BitPat("b0__01___00") -> BitPat.Y(), // HS access U
106    BitPat("b0__01___01") -> BitPat.Y(), // HS access S
107    BitPat("b0__01___10") -> BitPat.Y(), // HS access H
108    BitPat("b1__01___00") -> BitPat.Y(), // VS access U
109    BitPat("b1__01___01") -> BitPat.Y(), // VS access S
110    BitPat("b0__11___00") -> BitPat.Y(), // M  access HU
111    BitPat("b0__11___01") -> BitPat.Y(), // M  access HS
112    BitPat("b0__11___10") -> BitPat.Y(), // M  access H
113    BitPat("b0__11___11") -> BitPat.Y(), // M  access M
114  ), BitPat.N())
115
116  private val regularPrivilegeLegal = chisel3.util.experimental.decode.decoder(
117    privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8),
118    accessTable
119  ).asBool
120
121  private val isDebugReg   = addr(11, 4) === "h7b".U
122  private val privilegeLegal = Mux(isDebugReg, debugMode, regularPrivilegeLegal || debugMode)
123
124  private val rwIllegal = csrIsRO && wen
125
126  private val mnret_EX_II = mnret && !privState.isModeM
127  private val mnret_EX_VI = false.B
128  private val mnretIllegal = mnret_EX_VI || mnret_EX_II
129
130  private val mret_EX_II = mret && !privState.isModeM
131  private val mret_EX_VI = false.B
132  private val mretIllegal = mret_EX_II || mret_EX_VI
133
134  private val sret_EX_II = sret && (privState.isModeHU || privState.isModeHS && tsr)
135  private val sret_EX_VI = sret && (privState.isModeVU || privState.isModeVS && vtsr)
136  private val sretIllegal = sret_EX_II || sret_EX_VI
137
138  private val dret_EX_II = dret && !debugMode
139  private val dretIllegal = dret_EX_II
140
141  private val rwSatp_EX_II = csrAccess && privState.isModeHS &&  tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U)
142  private val rwSatp_EX_VI = csrAccess && privState.isModeVS && vtvm && (addr === CSRs.satp.U)
143
144  private val rwCustom_EX_II = csrAccess && privState.isModeVS && csrIsCustom
145
146  private val accessHPM = ren && csrIsHPM
147  private val accessHPM_EX_II = accessHPM && (
148    !privState.isModeM && !mcounteren(counterAddr) ||
149    privState.isModeHU && !scounteren(counterAddr)
150  )
151  private val accessHPM_EX_VI = accessHPM && mcounteren(counterAddr) && (
152    privState.isModeVS && !hcounteren(counterAddr) ||
153    privState.isModeVU && (!hcounteren(counterAddr) || !scounteren(counterAddr))
154  )
155
156  /**
157   * Sm/Ssstateen0 begin
158   */
159  // SE0 bit 63
160  private val csrIsHstateen0 = (addr === CSRs.hstateen0.U)
161  private val csrIsSstateen0 = (addr === CSRs.sstateen0.U)
162  private val csrIsStateen0 = csrIsHstateen0 || csrIsSstateen0
163  private val accessStateen0_EX_II = csrIsStateen0 && !privState.isModeM && !mstateen0.SE0.asBool
164  private val accessStateen0_EX_VI = csrIsSstateen0 && mstateen0.SE0.asBool && privState.isVirtual && !hstateen0.SE0.asBool ||
165    csrIsHstateen0 && mstateen0.SE0.asBool && privState.isVirtual
166
167  // ENVCFG bit 62
168  private val csrIsHenvcfg = (addr === CSRs.henvcfg.U)
169  private val csrIsSenvcfg = (addr === CSRs.senvcfg.U)
170  private val csrIsEnvcfg = csrIsHenvcfg || csrIsSenvcfg
171  private val accessEnvcfg_EX_II = csrIsEnvcfg && !privState.isModeM && !mstateen0.ENVCFG.asBool
172  private val accessEnvcfg_EX_VI = csrIsSenvcfg && mstateen0.ENVCFG.asBool && privState.isVirtual && !hstateen0.ENVCFG.asBool ||
173    csrIsHenvcfg && mstateen0.ENVCFG.asBool && privState.isVirtual
174
175  // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented
176  // csr addr S: [0x150, 0x157]     VS: [0x250, 0x257]
177  private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9)
178  private val csrIsVSi = addr.head(9) === CSRs.vsiselect.U.head(9)
179  private val csrIsIND = csrIsSi || csrIsVSi
180  private val accessIND_EX_II = csrIsIND && !privState.isModeM && !mstateen0.CSRIND.asBool
181  private val accessIND_EX_VI = csrIsSi && mstateen0.CSRIND.asBool && privState.isVirtual && !hstateen0.CSRIND.asBool ||
182    csrIsVSi && mstateen0.CSRIND.asBool && privState.isVirtual
183
184  // AIA bit 59
185  private val ssAiaHaddr = Seq(CSRs.hvien.U, CSRs.hvictl.U, CSRs.hviprio1.U, CSRs.hviprio2.U)
186  private val ssAiaVSaddr = addr === CSRs.vstopi.U
187  private val csrIsAIA = ssAiaHaddr.map(_ === addr).reduce(_ || _) || ssAiaVSaddr
188  private val accessAIA_EX_II = csrIsAIA && !privState.isModeM && !mstateen0.AIA.asBool
189  private val accessAIA_EX_VI = csrIsAIA && mstateen0.AIA.asBool && privState.isVirtual
190
191  // IMSIC bit 58 (Ssaia extension)
192  private val csrIsStopei = addr === CSRs.stopei.U
193  private val csrIsVStopei = addr === CSRs.vstopei.U
194  private val csrIsTpoie = csrIsStopei || csrIsVStopei
195  private val accessTopie_EX_II = csrIsTpoie && !privState.isModeM && !mstateen0.IMSIC.asBool
196  private val accessTopie_EX_VI = csrIsStopei && mstateen0.IMSIC.asBool && privState.isVirtual && !hstateen0.IMSIC.asBool ||
197    csrIsVStopei && mstateen0.IMSIC.asBool && privState.isVirtual
198
199  // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented
200  private val csrIsHcontext = (addr === CSRs.hcontext.U)
201  private val csrIsScontext = (addr === CSRs.scontext.U)
202  private val csrIsContext = csrIsHcontext || csrIsScontext
203  private val accessContext_EX_II = csrIsContext && !privState.isModeM && !mstateen0.CONTEXT.asBool
204  private val accessContext_EX_VI = csrIsScontext && mstateen0.CONTEXT.asBool && privState.isVirtual && !hstateen0.CONTEXT.asBool ||
205    csrIsHcontext && mstateen0.CONTEXT.asBool && privState.isVirtual
206
207  // P1P13 bit 56, Read-only 0
208
209  // Custom bit 0
210  // csr addr HVS: [0x6c0, 0x6ff], [0xac0, 0xaff], [0xec0, 0xeff]
211  private val csrIsHVSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b10".U) && (addr(7, 6) === "b11".U)
212  // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff]
213  private val csrIsSCustom   = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U)
214  // [0x800, 0x8ff], [0xcc0, 0xcff]
215  private val csrIsUCustom   = (addr(11, 8) =/= "b1000".U) || (addr(11, 6) =/= "b100011".U)
216  private val allCustom      = csrIsHVSCustom || csrIsSCustom || csrIsUCustom
217  private val accessCustom_EX_II = allCustom && (
218    !privState.isModeM && !mstateen0.C.asBool ||
219      privState.isModeHU && !sstateen0.C.asBool
220  )
221  private val accessCustom_EX_VI = mstateen0.C.asBool && (
222    (csrIsSCustom || csrIsUCustom) && privState.isVirtual && !hstateen0.C.asBool ||
223      csrIsUCustom && privState.isModeVU && hstateen0.C.asBool && !sstateen0.C.asBool
224  )
225
226  val xstateControlAccess_EX_II = csrAccess && (accessStateen0_EX_II || accessEnvcfg_EX_II || accessIND_EX_II || accessAIA_EX_II ||
227    accessTopie_EX_II || accessContext_EX_II || accessCustom_EX_II)
228  val xstateControlAccess_EX_VI = csrAccess && (accessStateen0_EX_VI || accessEnvcfg_EX_VI || accessIND_EX_VI || accessAIA_EX_VI ||
229    accessTopie_EX_VI || accessContext_EX_VI || accessCustom_EX_VI)
230  /**
231   * Sm/Ssstateen end
232   */
233
234  private val rwStimecmp_EX_II = csrAccess && ((privState.isModeHS && !mcounterenTM || !privState.isModeM && !menvcfgSTCE) && addr === CSRs.vstimecmp.U ||
235    ((privState.isModeHS || privState.isModeVS) && !mcounterenTM || !privState.isModeM && !menvcfgSTCE) && addr === CSRs.stimecmp.U)
236  private val rwStimecmp_EX_VI = (csrAccess && privState.isModeVS && (mcounterenTM && !hcounterenTM || menvcfgSTCE && !henvcfgSTCE) ||
237    wen && privState.isModeVS && hvictlVTI) && addr === CSRs.stimecmp.U
238
239  private val fsEffectiveOff = sFSIsOff && !privState.isVirtual || sOrVsFSIsOff && privState.isVirtual
240  private val vsEffectiveOff = sVSIsOff && !privState.isVirtual || sOrVsVSIsOff && privState.isVirtual
241
242  private val fpOff_EX_II  = csrAccess && csrIsFp  && fsEffectiveOff
243  private val vecOff_EX_II = csrAccess && csrIsVec && vsEffectiveOff
244
245  private val fpVec_EX_II = fpOff_EX_II || vecOff_EX_II
246
247  /**
248   * AIA begin
249   */
250  private val rwStopei_EX_II = csrAccess && privState.isModeHS && mvienSEIE && addr === CSRs.stopei.U
251
252  private val rwMireg_EX_II = csrAccess && privState.isModeM && miselectIsIllegal && addr === CSRs.mireg.U
253
254  private val rwSireg_EX_II = csrAccess && ((privState.isModeHS && mvienSEIE && siselect >= 0x70.U && siselect <= 0xFF.U) ||
255    ((privState.isModeM || privState.isModeHS) && siselectIsIllegal) ||
256    (privState.isModeVS && (vsiselect < 0x30.U || (vsiselect >= 0x40.U && vsiselect < 0x70.U) || vsiselect > 0xFF.U))) && addr === CSRs.sireg.U
257  private val rwSireg_EX_VI = csrAccess && (privState.isModeVS && (vsiselect >= 0x30.U && vsiselect <= 0x3F.U)) && addr === CSRs.sireg.U
258
259  private val rwVSireg_EX_II = csrAccess && (privState.isModeM || privState.isModeHS) && vsiselectIsIllegal && addr === CSRs.vsireg.U
260
261  private val rwSip_Sie_EX_VI = csrAccess && privState.isModeVS && hvictlVTI && (addr === CSRs.sip.U || addr === CSRs.sie.U)
262
263  /**
264   * AIA end
265   */
266
267  // Todo: check correct
268  io.out.EX_II :=  csrAccess && !privilegeLegal && (!privState.isVirtual || privState.isVirtual && csrIsM) ||
269    rwIllegal || mnret_EX_II || mret_EX_II || sret_EX_II || rwSatp_EX_II || accessHPM_EX_II ||
270    rwStimecmp_EX_II || rwCustom_EX_II || fpVec_EX_II || dret_EX_II || xstateControlAccess_EX_II || rwStopei_EX_II ||
271    rwMireg_EX_II || rwSireg_EX_II || rwVSireg_EX_II
272  io.out.EX_VI := (csrAccess && !privilegeLegal && privState.isVirtual && !csrIsM ||
273    mnret_EX_VI || mret_EX_VI || sret_EX_VI || rwSatp_EX_VI || accessHPM_EX_VI || rwStimecmp_EX_VI || rwSireg_EX_VI || rwSip_Sie_EX_VI) && !rwIllegal || xstateControlAccess_EX_VI
274
275  io.out.hasLegalWen   := wen   && !(io.out.EX_II || io.out.EX_VI)
276  io.out.hasLegalMNret := mnret && !mnretIllegal
277  io.out.hasLegalMret  := mret  && !mretIllegal
278  io.out.hasLegalSret  := sret  && !sretIllegal
279  io.out.hasLegalDret  := dret  && !dretIllegal
280
281  io.out.hasLegalWriteFcsr := wen && csrIsFp && !fsEffectiveOff
282  io.out.hasLegalWriteVcsr := wen && csrIsWritableVec && !vsEffectiveOff
283
284  dontTouch(regularPrivilegeLegal)
285}
286
287class CSRPermitIO extends Bundle {
288  val in = Input(new Bundle {
289    val csrAccess = new Bundle {
290      val ren = Bool()
291      val wen = Bool()
292      val addr = UInt(12.W)
293    }
294    val privState = new PrivState
295    val debugMode = Bool()
296    val mnret = Bool()
297    val mret = Bool()
298    val sret = Bool()
299    val dret = Bool()
300    val csrIsCustom = Bool()
301    val status = new Bundle {
302      // Trap SRET
303      val tsr = Bool()
304      // Virtual Trap SRET
305      val vtsr = Bool()
306      // Trap Virtual Memory
307      val tvm = Bool()
308      // Virtual Trap Virtual Memory
309      val vtvm = Bool()
310      // Machine level counter enable, access PMC from the level less than M will trap EX_II
311      val mcounteren = UInt(32.W)
312      // Hypervisor level counter enable.
313      // Accessing PMC from VS/VU level will trap EX_VI, if m[x]=1 && h[x]=0
314      val hcounteren = UInt(32.W)
315      // Supervisor level counter enable.
316      // Accessing PMC from **HU level** will trap EX_II, if s[x]=0
317      // Accessing PMC from **VU level** will trap EX_VI, if m[x]=1 && h[x]=1 && s[x]=0
318      val scounteren = UInt(32.W)
319      // Machine environment configuration register.
320      // Accessing stimecmp or vstimecmp from **Non-M level** will trap EX_II, if menvcfg.STCE=0
321      val menvcfg = UInt(64.W)
322      // Hypervisor environment configuration register.
323      // Accessing vstimecmp from ** V level** will trap EX_VI, if menvcfg.STCE=1 && henvcfg.STCE=0
324      val henvcfg = UInt(64.W)
325
326      val mstatusFSOff = Bool()
327      val vsstatusFSOff = Bool()
328      val mstatusVSOff = Bool()
329      val vsstatusVSOff = Bool()
330      // Sm/Ssstateen: to control state access
331      val mstateen0 = new MstateenBundle0
332      val hstateen0 = new HstateenBundle0
333      val sstateen0 = new SstateenBundle0
334    }
335    val aia = new Bundle {
336      val miselectIsIllegal = Bool()
337      val siselectIsIllegal = Bool()
338      val vsiselectIsIllegal = Bool()
339      val siselect = UInt(64.W)
340      val vsiselect = UInt(64.W)
341      val mvienSEIE = Bool()
342      val hvictlVTI = Bool()
343    }
344  })
345
346  val out = Output(new Bundle {
347    val hasLegalWen   = Bool()
348    val hasLegalMNret = Bool()
349    val hasLegalMret  = Bool()
350    val hasLegalSret  = Bool()
351    val hasLegalDret  = Bool()
352    val hasLegalWriteFcsr = Bool()
353    val hasLegalWriteVcsr = Bool()
354    val EX_II = Bool()
355    val EX_VI = Bool()
356  })
357}
358