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