1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import chisel3.util.experimental.decode.TruthTable 6import xiangshan.backend.fu.NewCSR.CSRBundles.{Counteren, PrivState} 7import freechips.rocketchip.rocket.CSRs 8 9class CSRPermitModule extends Module { 10 val io = IO(new CSRPermitIO) 11 12 private val (ren, wen, addr, privState, debugMode) = ( 13 io.in.csrAccess.ren, 14 io.in.csrAccess.wen, 15 io.in.csrAccess.addr, 16 io.in.privState, 17 io.in.debugMode 18 ) 19 20 private val csrAccess = WireInit(ren || wen) 21 22 private val (mret, sret, wfi) = ( 23 io.in.mret, 24 io.in.sret, 25 io.in.wfi, 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 csrIsRO = addr(11, 10) === "b11".U 67 private val csrIsUnpriv = addr(9, 8) === "b00".U 68 private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U 69 private val counterAddr = addr(4, 0) // 32 counters 70 71 private val accessTable = TruthTable(Seq( 72 // V PRVM ADDR 73 BitPat("b0__00___00") -> BitPat.Y(), // HU access U 74 BitPat("b1__00___00") -> BitPat.Y(), // VU access U 75 BitPat("b0__01___00") -> BitPat.Y(), // HS access U 76 BitPat("b0__01___01") -> BitPat.Y(), // HS access S 77 BitPat("b1__01___00") -> BitPat.Y(), // VS access U 78 BitPat("b1__01___01") -> BitPat.Y(), // VS access S 79 BitPat("b0__11___00") -> BitPat.Y(), // M access HU 80 BitPat("b0__11___01") -> BitPat.Y(), // M access HS 81 BitPat("b0__11___11") -> BitPat.Y(), // M access M 82 ), BitPat.N()) 83 84 private val isDebugReg = addr(11, 4) === "h7b".U 85 private val isTriggerReg = addr(11, 4) === "h7a".U 86 87 private val regularPrivilegeLegal = chisel3.util.experimental.decode.decoder( 88 privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8), 89 accessTable 90 ).asBool 91 92 private val privilegeLegal = MuxCase( 93 regularPrivilegeLegal, 94 Seq( 95 isDebugReg -> debugMode, 96 isTriggerReg -> (debugMode || privState.isModeM), 97 ) 98 ) 99 100 private val rwIllegal = csrIsRO && wen 101 102 private val csrAccessIllegal = (!privilegeLegal || rwIllegal) 103 104 private val mretIllegal = !privState.isModeM 105 106 private val sretIllegal = sret && ( 107 privState.isModeHS && tsr || privState.isModeVS && vtsr || privState.isModeHUorVU 108 ) 109 110 private val wfi_EX_II = wfi && (!privState.isModeM && tw) 111 private val wfi_EX_VI = wfi && (privState.isModeVS && vtw && !tw || privState.isModeVU && !tw) 112 113 private val rwSatp_EX_II = csrAccess && privState.isModeHS && tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U) 114 private val rwSatp_EX_VI = csrAccess && privState.isModeVS && vtvm && (addr === CSRs.satp.U) 115 116 private val rwCustom_EX_II = csrAccess && privState.isModeVS && csrIsCustom 117 118 private val accessHPM = ren && csrIsHPM 119 private val accessHPM_EX_II = accessHPM && ( 120 !privState.isModeM && !mcounteren(counterAddr) || 121 privState.isModeHU && scounteren(counterAddr) 122 ) 123 private val accessHPM_EX_VI = accessHPM && mcounteren(counterAddr) && ( 124 privState.isModeVS && !hcounteren(counterAddr) || 125 privState.isModeVU && (!hcounteren(counterAddr) || !scounteren(counterAddr)) 126 ) 127 128 private val rwStimecmp_EX_II = csrAccess && ((privState.isModeHS && !mcounterenTM || !privState.isModeM && !menvcfgSTCE) && addr === CSRs.vstimecmp.U || 129 ((privState.isModeHS || privState.isModeVS) && !mcounterenTM || !privState.isModeM && !menvcfgSTCE) && addr === CSRs.stimecmp.U) 130 private val rwStimecmp_EX_VI = csrAccess && privState.isModeVS && (mcounterenTM && !hcounterenTM || menvcfgSTCE && !henvcfgSTCE) && addr === CSRs.stimecmp.U 131 132 io.out.illegal := csrAccess && csrAccessIllegal || mret && mretIllegal || sret && sretIllegal 133 134 // Todo: check correct 135 io.out.EX_II := io.out.illegal && !privState.isVirtual || wfi_EX_II || rwSatp_EX_II || accessHPM_EX_II || rwStimecmp_EX_II || rwCustom_EX_II 136 io.out.EX_VI := io.out.illegal && privState.isVirtual || wfi_EX_VI || rwSatp_EX_VI || accessHPM_EX_VI || rwStimecmp_EX_VI 137 138 io.out.hasLegalWen := io.in.csrAccess.wen && !csrAccessIllegal 139 io.out.hasLegalMret := mret && !mretIllegal 140 io.out.hasLegalSret := sret && !sretIllegal 141 io.out.hasLegalWfi := wfi && !wfi_EX_II && !wfi_EX_VI 142} 143 144class CSRPermitIO extends Bundle { 145 val in = Input(new Bundle { 146 val csrAccess = new Bundle { 147 val ren = Bool() 148 val wen = Bool() 149 val addr = UInt(12.W) 150 } 151 val privState = new PrivState 152 val debugMode = Bool() 153 val mret = Bool() 154 val sret = Bool() 155 val wfi = Bool() 156 val csrIsCustom = Bool() 157 val status = new Bundle { 158 // Trap SRET 159 val tsr = Bool() 160 // Virtual Trap SRET 161 val vtsr = Bool() 162 // Timeout Wait 163 val tw = Bool() 164 // Virtual Timeout Wait 165 val vtw = Bool() 166 // Trap Virtual Memory 167 val tvm = Bool() 168 // Virtual Trap Virtual Memory 169 val vtvm = Bool() 170 // Machine level counter enable, access PMC from the level less than M will trap EX_II 171 val mcounteren = UInt(32.W) 172 // Hypervisor level counter enable. 173 // Accessing PMC from VS/VU level will trap EX_VI, if m[x]=1 && h[x]=0 174 val hcounteren = UInt(32.W) 175 // Supervisor level counter enable. 176 // Accessing PMC from **HU level** will trap EX_II, if s[x]=0 177 // Accessing PMC from **VU level** will trap EX_VI, if m[x]=1 && h[x]=1 && s[x]=0 178 val scounteren = UInt(32.W) 179 // Machine environment configuration register. 180 // Accessing stimecmp or vstimecmp from **Non-M level** will trap EX_II, if menvcfg.STCE=0 181 val menvcfg = UInt(64.W) 182 // Hypervisor environment configuration register. 183 // Accessing vstimecmp from ** V level** will trap EX_VI, if menvcfg.STCE=1 && henvcfg.STCE=0 184 val henvcfg = UInt(64.W) 185 } 186 }) 187 188 val out = Output(new Bundle { 189 val hasLegalWen = Bool() 190 val hasLegalMret = Bool() 191 val hasLegalSret = Bool() 192 val hasLegalWfi = Bool() 193 // Todo: split illegal into EX_II and EX_VI 194 val illegal = Bool() 195 val EX_II = Bool() 196 val EX_VI = Bool() 197 }) 198} 199