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