xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRPermitModule.scala (revision be37cd3a1b8e5140268529832cdccea92b814b35)
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 (mret, sret, dret) = (
24    io.in.mret,
25    io.in.sret,
26    io.in.dret,
27  )
28
29  private val (tsr, vtsr) = (
30    io.in.status.tsr,
31    io.in.status.vtsr,
32  )
33
34  private val (tw, vtw) = (
35    io.in.status.tw,
36    io.in.status.vtw
37  )
38
39  private val (tvm, vtvm) = (
40    io.in.status.tvm,
41    io.in.status.vtvm,
42  )
43
44  private val csrIsCustom = io.in.csrIsCustom
45
46  private val (mcounteren, hcounteren, scounteren) = (
47    io.in.status.mcounteren,
48    io.in.status.hcounteren,
49    io.in.status.scounteren,
50  )
51
52  private val (mcounterenTM, hcounterenTM) = (
53    mcounteren(1),
54    hcounteren(1),
55  )
56
57  private val (menvcfg, henvcfg) = (
58    io.in.status.menvcfg,
59    io.in.status.henvcfg,
60  )
61
62  private val (menvcfgSTCE, henvcfgSTCE) = (
63    menvcfg(63),
64    henvcfg(63),
65  )
66
67  private val (sFSIsOff, sVSIsOff, sOrVsFSIsOff, sOrVsVSIsOff) = (
68    io.in.status.mstatusFSOff,
69    io.in.status.mstatusVSOff,
70    io.in.status.mstatusFSOff || io.in.status.vsstatusFSOff,
71    io.in.status.mstatusVSOff || io.in.status.vsstatusVSOff,
72  )
73
74  private val csrIsRO = addr(11, 10) === "b11".U
75  private val csrIsUnpriv = addr(9, 8) === "b00".U
76  private val csrIsM = addr(9, 8) === "b11".U
77  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
78  private val csrIsFp = Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _)
79  private val csrIsVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr, CSRs.vl, CSRs.vtype, CSRs.vlenb).map(_.U === addr).reduce(_ || _)
80  private val csrIsWritableVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _)
81  private val counterAddr = addr(4, 0) // 32 counters
82
83  private val accessTable = TruthTable(Seq(
84    //       V PRVM ADDR
85    BitPat("b0__00___00") -> BitPat.Y(), // HU access U
86    BitPat("b1__00___00") -> BitPat.Y(), // VU access U
87    BitPat("b0__01___00") -> BitPat.Y(), // HS access U
88    BitPat("b0__01___01") -> BitPat.Y(), // HS access S
89    BitPat("b0__01___10") -> BitPat.Y(), // HS access H
90    BitPat("b1__01___00") -> BitPat.Y(), // VS access U
91    BitPat("b1__01___01") -> BitPat.Y(), // VS access S
92    BitPat("b0__11___00") -> BitPat.Y(), // M  access HU
93    BitPat("b0__11___01") -> BitPat.Y(), // M  access HS
94    BitPat("b0__11___10") -> BitPat.Y(), // M  access H
95    BitPat("b0__11___11") -> BitPat.Y(), // M  access M
96  ), BitPat.N())
97
98  private val regularPrivilegeLegal = chisel3.util.experimental.decode.decoder(
99    privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8),
100    accessTable
101  ).asBool
102
103  private val isDebugReg   = addr(11, 4) === "h7b".U
104  private val privilegeLegal = Mux(isDebugReg, debugMode, regularPrivilegeLegal || debugMode)
105
106  private val rwIllegal = csrIsRO && wen
107
108  private val mret_EX_II = mret && !privState.isModeM
109  private val mret_EX_VI = false.B
110  private val mretIllegal = mret_EX_II || mret_EX_VI
111
112  private val sret_EX_II = sret && (privState.isModeHU || privState.isModeHS && tsr)
113  private val sret_EX_VI = sret && (privState.isModeVU || privState.isModeVS && vtsr)
114  private val sretIllegal = sret_EX_II || sret_EX_VI
115
116  private val dret_EX_II = dret && !debugMode
117  private val dretIllegal = dret_EX_II
118
119  private val rwSatp_EX_II = csrAccess && privState.isModeHS &&  tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U)
120  private val rwSatp_EX_VI = csrAccess && privState.isModeVS && vtvm && (addr === CSRs.satp.U)
121
122  private val rwCustom_EX_II = csrAccess && privState.isModeVS && csrIsCustom
123
124  private val accessHPM = ren && csrIsHPM
125  private val accessHPM_EX_II = accessHPM && (
126    !privState.isModeM && !mcounteren(counterAddr) ||
127    privState.isModeHU && !scounteren(counterAddr)
128  )
129  private val accessHPM_EX_VI = accessHPM && mcounteren(counterAddr) && (
130    privState.isModeVS && !hcounteren(counterAddr) ||
131    privState.isModeVU && (!hcounteren(counterAddr) || !scounteren(counterAddr))
132  )
133
134  private val rwStimecmp_EX_II = csrAccess && ((privState.isModeHS && !mcounterenTM || !privState.isModeM && !menvcfgSTCE) && addr === CSRs.vstimecmp.U ||
135    ((privState.isModeHS || privState.isModeVS) && !mcounterenTM || !privState.isModeM && !menvcfgSTCE) && addr === CSRs.stimecmp.U)
136  private val rwStimecmp_EX_VI = csrAccess && privState.isModeVS && (mcounterenTM && !hcounterenTM || menvcfgSTCE && !henvcfgSTCE) && addr === CSRs.stimecmp.U
137
138  private val fsEffectiveOff = sFSIsOff && !privState.isVirtual || sOrVsFSIsOff && privState.isVirtual
139  private val vsEffectiveOff = sVSIsOff && !privState.isVirtual || sOrVsVSIsOff && privState.isVirtual
140
141  private val fpOff_EX_II  = csrAccess && csrIsFp  && fsEffectiveOff
142  private val vecOff_EX_II = csrAccess && csrIsVec && vsEffectiveOff
143
144  private val fpVec_EX_II = fpOff_EX_II || vecOff_EX_II
145
146  private val csrAccessIllegal = (!privilegeLegal || rwIllegal)
147
148  // Todo: check correct
149  io.out.EX_II :=  csrAccess && !privilegeLegal && (!privState.isVirtual || privState.isVirtual && csrIsM) ||
150    rwIllegal || mret_EX_II || sret_EX_II || rwSatp_EX_II || accessHPM_EX_II ||
151    rwStimecmp_EX_II || rwCustom_EX_II || fpVec_EX_II || dret_EX_II
152  io.out.EX_VI := (csrAccess && !privilegeLegal && privState.isVirtual && !csrIsM ||
153    mret_EX_VI || sret_EX_VI || rwSatp_EX_VI || accessHPM_EX_VI || rwStimecmp_EX_VI) && !rwIllegal
154
155  io.out.hasLegalWen  := wen  && !csrAccessIllegal
156  io.out.hasLegalMret := mret && !mretIllegal
157  io.out.hasLegalSret := sret && !sretIllegal
158  io.out.hasLegalDret := dret && !dretIllegal
159
160  io.out.hasLegalWriteFcsr := wen && csrIsFp && !fsEffectiveOff
161  io.out.hasLegalWriteVcsr := wen && csrIsWritableVec && !vsEffectiveOff
162
163  dontTouch(regularPrivilegeLegal)
164}
165
166class CSRPermitIO extends Bundle {
167  val in = Input(new Bundle {
168    val csrAccess = new Bundle {
169      val ren = Bool()
170      val wen = Bool()
171      val addr = UInt(12.W)
172    }
173    val privState = new PrivState
174    val debugMode = Bool()
175    val mret = Bool()
176    val sret = Bool()
177    val dret = Bool()
178    val csrIsCustom = Bool()
179    val status = new Bundle {
180      // Trap SRET
181      val tsr = Bool()
182      // Virtual Trap SRET
183      val vtsr = Bool()
184      // Timeout Wait
185      val tw = Bool()
186      // Virtual Timeout Wait
187      val vtw = Bool()
188      // Trap Virtual Memory
189      val tvm = Bool()
190      // Virtual Trap Virtual Memory
191      val vtvm = Bool()
192      // Machine level counter enable, access PMC from the level less than M will trap EX_II
193      val mcounteren = UInt(32.W)
194      // Hypervisor level counter enable.
195      // Accessing PMC from VS/VU level will trap EX_VI, if m[x]=1 && h[x]=0
196      val hcounteren = UInt(32.W)
197      // Supervisor level counter enable.
198      // Accessing PMC from **HU level** will trap EX_II, if s[x]=0
199      // Accessing PMC from **VU level** will trap EX_VI, if m[x]=1 && h[x]=1 && s[x]=0
200      val scounteren = UInt(32.W)
201      // Machine environment configuration register.
202      // Accessing stimecmp or vstimecmp from **Non-M level** will trap EX_II, if menvcfg.STCE=0
203      val menvcfg = UInt(64.W)
204      // Hypervisor environment configuration register.
205      // Accessing vstimecmp from ** V level** will trap EX_VI, if menvcfg.STCE=1 && henvcfg.STCE=0
206      val henvcfg = UInt(64.W)
207
208      val mstatusFSOff = Bool()
209      val vsstatusFSOff = Bool()
210      val mstatusVSOff = Bool()
211      val vsstatusVSOff = Bool()
212    }
213  })
214
215  val out = Output(new Bundle {
216    val hasLegalWen  = Bool()
217    val hasLegalMret = Bool()
218    val hasLegalSret = Bool()
219    val hasLegalDret = Bool()
220    val hasLegalWriteFcsr = Bool()
221    val hasLegalWriteVcsr = Bool()
222    val EX_II = Bool()
223    val EX_VI = Bool()
224  })
225}
226