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 accessHPM = ren && csrIsHPM 145 private val accessHPM_EX_II = accessHPM && ( 146 !privState.isModeM && !mcounteren(counterAddr) || 147 privState.isModeHU && !scounteren(counterAddr) 148 ) 149 private val accessHPM_EX_VI = accessHPM && mcounteren(counterAddr) && ( 150 privState.isModeVS && !hcounteren(counterAddr) || 151 privState.isModeVU && (!hcounteren(counterAddr) || !scounteren(counterAddr)) 152 ) 153 154 /** 155 * Sm/Ssstateen0 begin 156 */ 157 // SE0 bit 63 158 private val csrIsHstateen0 = (addr === CSRs.hstateen0.U) 159 private val csrIsSstateen0 = (addr === CSRs.sstateen0.U) 160 private val csrIsStateen0 = csrIsHstateen0 || csrIsSstateen0 161 private val accessStateen0_EX_II = csrIsStateen0 && !privState.isModeM && !mstateen0.SE0.asBool 162 private val accessStateen0_EX_VI = csrIsSstateen0 && mstateen0.SE0.asBool && privState.isVirtual && !hstateen0.SE0.asBool || 163 csrIsHstateen0 && mstateen0.SE0.asBool && privState.isVirtual 164 165 // ENVCFG bit 62 166 private val csrIsHenvcfg = (addr === CSRs.henvcfg.U) 167 private val csrIsSenvcfg = (addr === CSRs.senvcfg.U) 168 private val csrIsEnvcfg = csrIsHenvcfg || csrIsSenvcfg 169 private val accessEnvcfg_EX_II = csrIsEnvcfg && !privState.isModeM && !mstateen0.ENVCFG.asBool 170 private val accessEnvcfg_EX_VI = csrIsSenvcfg && mstateen0.ENVCFG.asBool && privState.isVirtual && !hstateen0.ENVCFG.asBool || 171 csrIsHenvcfg && mstateen0.ENVCFG.asBool && privState.isVirtual 172 173 // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented 174 // csr addr S: [0x150, 0x157] VS: [0x250, 0x257] 175 private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9) 176 private val csrIsVSi = addr.head(9) === CSRs.vsiselect.U.head(9) 177 private val csrIsIND = csrIsSi || csrIsVSi 178 private val accessIND_EX_II = csrIsIND && !privState.isModeM && !mstateen0.CSRIND.asBool 179 private val accessIND_EX_VI = csrIsSi && mstateen0.CSRIND.asBool && privState.isVirtual && !hstateen0.CSRIND.asBool || 180 csrIsVSi && mstateen0.CSRIND.asBool && privState.isVirtual 181 182 // AIA bit 59 183 private val ssAiaHaddr = Seq(CSRs.hvien.U, CSRs.hvictl.U, CSRs.hviprio1.U, CSRs.hviprio2.U) 184 private val ssAiaVSaddr = addr === CSRs.vstopi.U 185 private val ssAiaSaddr = addr === CSRs.stopi.U 186 private val csrIsAIA = ssAiaHaddr.map(_ === addr).reduce(_ || _) || ssAiaVSaddr || ssAiaSaddr 187 private val accessAIA_EX_II = csrIsAIA && !privState.isModeM && !mstateen0.AIA.asBool 188 private val accessAIA_EX_VI = ssAiaSaddr && privState.isVirtual && !hstateen0.AIA.asBool 189 190 // IMSIC bit 58 (Ssaia extension) 191 private val csrIsStopei = addr === CSRs.stopei.U 192 private val csrIsVStopei = addr === CSRs.vstopei.U 193 private val csrIsTpoie = csrIsStopei || csrIsVStopei 194 private val accessTopie_EX_II = csrIsTpoie && !privState.isModeM && !mstateen0.IMSIC.asBool 195 private val accessTopie_EX_VI = csrIsStopei && mstateen0.IMSIC.asBool && privState.isVirtual && !hstateen0.IMSIC.asBool || 196 csrIsVStopei && mstateen0.IMSIC.asBool && privState.isVirtual 197 198 // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented 199 private val csrIsHcontext = (addr === CSRs.hcontext.U) 200 private val csrIsScontext = (addr === CSRs.scontext.U) 201 private val csrIsContext = csrIsHcontext || csrIsScontext 202 private val accessContext_EX_II = csrIsContext && !privState.isModeM && !mstateen0.CONTEXT.asBool 203 private val accessContext_EX_VI = csrIsScontext && mstateen0.CONTEXT.asBool && privState.isVirtual && !hstateen0.CONTEXT.asBool || 204 csrIsHcontext && mstateen0.CONTEXT.asBool && privState.isVirtual 205 206 // P1P13 bit 56, Read-only 0 207 208 // Custom bit 0 209 // csr addr HVS: [0x6c0, 0x6ff], [0xac0, 0xaff], [0xec0, 0xeff] 210 private val csrIsHVSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b10".U) && (addr(7, 6) === "b11".U) 211 // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff] 212 private val csrIsSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U) 213 // [0x800, 0x8ff], [0xcc0, 0xcff] 214 private val csrIsUCustom = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U) 215 private val allCustom = csrIsHVSCustom || csrIsSCustom || csrIsUCustom 216 private val accessCustom_EX_II = allCustom && ( 217 !privState.isModeM && !mstateen0.C.asBool || 218 privState.isModeHU && !sstateen0.C.asBool 219 ) 220 private val accessCustom_EX_VI = mstateen0.C.asBool && ( 221 (csrIsSCustom || csrIsUCustom) && privState.isVirtual && !hstateen0.C.asBool || 222 csrIsUCustom && privState.isModeVU && hstateen0.C.asBool && !sstateen0.C.asBool 223 ) 224 225 val xstateControlAccess_EX_II = csrAccess && (accessStateen0_EX_II || accessEnvcfg_EX_II || accessIND_EX_II || accessAIA_EX_II || 226 accessTopie_EX_II || accessContext_EX_II || accessCustom_EX_II) 227 val xstateControlAccess_EX_VI = csrAccess && (accessStateen0_EX_VI || accessEnvcfg_EX_VI || accessIND_EX_VI || accessAIA_EX_VI || 228 accessTopie_EX_VI || accessContext_EX_VI || accessCustom_EX_VI) 229 /** 230 * Sm/Ssstateen end 231 */ 232 233 private val rwStimecmp_EX_II = csrAccess && !privState.isModeM && (!mcounterenTM || !menvcfgSTCE) && (addr === CSRs.vstimecmp.U || addr === CSRs.stimecmp.U) 234 private val rwStimecmp_EX_VI = (csrAccess && privState.isModeVS && (mcounterenTM && !hcounterenTM || menvcfgSTCE && !henvcfgSTCE) || 235 wen && privState.isModeVS && hvictlVTI) && addr === CSRs.stimecmp.U 236 237 private val fsEffectiveOff = sFSIsOff && !privState.isVirtual || sOrVsFSIsOff && privState.isVirtual 238 private val vsEffectiveOff = sVSIsOff && !privState.isVirtual || sOrVsVSIsOff && privState.isVirtual 239 240 private val fpOff_EX_II = csrAccess && csrIsFp && fsEffectiveOff 241 private val vecOff_EX_II = csrAccess && csrIsVec && vsEffectiveOff 242 243 private val fpVec_EX_II = fpOff_EX_II || vecOff_EX_II 244 245 /** 246 * AIA begin 247 */ 248 private val rwStopei_EX_II = csrAccess && privState.isModeHS && mvienSEIE && addr === CSRs.stopei.U 249 250 private val rwMireg_EX_II = csrAccess && privState.isModeM && miselectIsIllegal && addr === CSRs.mireg.U 251 252 private val rwSireg_EX_II = csrAccess && ((privState.isModeHS && mvienSEIE && siselect >= 0x70.U && siselect <= 0xFF.U) || 253 ((privState.isModeM || privState.isModeHS) && siselectIsIllegal) || 254 (privState.isModeVS && (vsiselect < 0x30.U || (vsiselect >= 0x40.U && vsiselect < 0x70.U) || vsiselect > 0xFF.U))) && addr === CSRs.sireg.U 255 private val rwSireg_EX_VI = csrAccess && (privState.isModeVS && (vsiselect >= 0x30.U && vsiselect <= 0x3F.U)) && addr === CSRs.sireg.U 256 257 private val rwVSireg_EX_II = csrAccess && (privState.isModeM || privState.isModeHS) && vsiselectIsIllegal && addr === CSRs.vsireg.U 258 259 private val rwSip_Sie_EX_VI = csrAccess && privState.isModeVS && hvictlVTI && (addr === CSRs.sip.U || addr === CSRs.sie.U) 260 261 /** 262 * AIA end 263 */ 264 265 // Todo: check correct 266 io.out.EX_II := csrAccess && !privilegeLegal && (!privState.isVirtual || privState.isVirtual && csrIsM) || 267 rwIllegal || mnret_EX_II || mret_EX_II || sret_EX_II || rwSatp_EX_II || accessHPM_EX_II || 268 rwStimecmp_EX_II || fpVec_EX_II || dret_EX_II || xstateControlAccess_EX_II || rwStopei_EX_II || 269 rwMireg_EX_II || rwSireg_EX_II || rwVSireg_EX_II 270 io.out.EX_VI := (csrAccess && !privilegeLegal && privState.isVirtual && !csrIsM || 271 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 272 273 io.out.hasLegalWen := wen && !(io.out.EX_II || io.out.EX_VI) 274 io.out.hasLegalMNret := mnret && !mnretIllegal 275 io.out.hasLegalMret := mret && !mretIllegal 276 io.out.hasLegalSret := sret && !sretIllegal 277 io.out.hasLegalDret := dret && !dretIllegal 278 279 io.out.hasLegalWriteFcsr := wen && csrIsFp && !fsEffectiveOff 280 io.out.hasLegalWriteVcsr := wen && csrIsWritableVec && !vsEffectiveOff 281 282 dontTouch(regularPrivilegeLegal) 283} 284 285class CSRPermitIO extends Bundle { 286 val in = Input(new Bundle { 287 val csrAccess = new Bundle { 288 val ren = Bool() 289 val wen = Bool() 290 val addr = UInt(12.W) 291 } 292 val privState = new PrivState 293 val debugMode = Bool() 294 val mnret = Bool() 295 val mret = Bool() 296 val sret = Bool() 297 val dret = Bool() 298 val csrIsCustom = Bool() 299 val status = new Bundle { 300 // Trap SRET 301 val tsr = Bool() 302 // Virtual Trap SRET 303 val vtsr = Bool() 304 // Trap Virtual Memory 305 val tvm = Bool() 306 // Virtual Trap Virtual Memory 307 val vtvm = Bool() 308 // Machine level counter enable, access PMC from the level less than M will trap EX_II 309 val mcounteren = UInt(32.W) 310 // Hypervisor level counter enable. 311 // Accessing PMC from VS/VU level will trap EX_VI, if m[x]=1 && h[x]=0 312 val hcounteren = UInt(32.W) 313 // Supervisor level counter enable. 314 // Accessing PMC from **HU level** will trap EX_II, if s[x]=0 315 // Accessing PMC from **VU level** will trap EX_VI, if m[x]=1 && h[x]=1 && s[x]=0 316 val scounteren = UInt(32.W) 317 // Machine environment configuration register. 318 // Accessing stimecmp or vstimecmp from **Non-M level** will trap EX_II, if menvcfg.STCE=0 319 val menvcfg = UInt(64.W) 320 // Hypervisor environment configuration register. 321 // Accessing vstimecmp from ** V level** will trap EX_VI, if menvcfg.STCE=1 && henvcfg.STCE=0 322 val henvcfg = UInt(64.W) 323 324 val mstatusFSOff = Bool() 325 val vsstatusFSOff = Bool() 326 val mstatusVSOff = Bool() 327 val vsstatusVSOff = Bool() 328 // Sm/Ssstateen: to control state access 329 val mstateen0 = new MstateenBundle0 330 val hstateen0 = new HstateenBundle0 331 val sstateen0 = new SstateenBundle0 332 } 333 val aia = new Bundle { 334 val miselectIsIllegal = Bool() 335 val siselectIsIllegal = Bool() 336 val vsiselectIsIllegal = Bool() 337 val siselect = UInt(64.W) 338 val vsiselect = UInt(64.W) 339 val mvienSEIE = Bool() 340 val hvictlVTI = Bool() 341 } 342 }) 343 344 val out = Output(new Bundle { 345 val hasLegalWen = Bool() 346 val hasLegalMNret = Bool() 347 val hasLegalMret = Bool() 348 val hasLegalSret = Bool() 349 val hasLegalDret = Bool() 350 val hasLegalWriteFcsr = Bool() 351 val hasLegalWriteVcsr = Bool() 352 val EX_II = Bool() 353 val EX_VI = Bool() 354 }) 355} 356