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