1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import chisel3.util.experimental.decode.TruthTable 6import xiangshan.backend.fu.NewCSR.CSRBundles.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 csrIsRO = addr(11, 10) === "b11".U 46 47 private val accessTable = TruthTable(Seq( 48 // V PRVM ADDR 49 BitPat("b0__00___00") -> BitPat.Y(), // HU access U 50 BitPat("b1__00___00") -> BitPat.Y(), // VU access U 51 BitPat("b0__01___00") -> BitPat.Y(), // HS access U 52 BitPat("b0__01___01") -> BitPat.Y(), // HS access S 53 BitPat("b1__01___00") -> BitPat.Y(), // VS access U 54 BitPat("b1__01___01") -> BitPat.Y(), // VS access S 55 BitPat("b0__11___00") -> BitPat.Y(), // M access HU 56 BitPat("b0__11___01") -> BitPat.Y(), // M access HS 57 BitPat("b0__11___11") -> BitPat.Y(), // M access M 58 ), BitPat.N()) 59 60 private val isDebugReg = addr(11, 4) === "h7b".U 61 private val debugRegCanAccess = Mux(isDebugReg, debugMode, true.B) 62 63 private val isTriggerReg = addr(11, 4) === "h7a".U 64 private val triggerRegCanAccess = Mux(isTriggerReg, debugMode || privState.isModeM, true.B) 65 66 private val privilegeLegal = chisel3.util.experimental.decode.decoder( 67 privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8), 68 accessTable 69 ).asBool 70 71 private val rwIllegal = csrIsRO && wen 72 73 private val csrAccessIllegal = (!privilegeLegal || rwIllegal) || 74 (isDebugReg && !debugMode) || // for debug reg 75 (isTriggerReg && !(debugMode || privState.isModeM)) // for trigger reg 76 77 private val mretIllegal = !privState.isModeM 78 79 private val sretIllegal = sret && ( 80 privState.isModeHS && tsr || privState.isModeVS && vtsr || privState.isModeHUorVU 81 ) 82 83 private val wfi_EX_II = wfi && (!privState.isModeM && tw) 84 private val wfi_EX_VI = wfi && (privState.isModeVS && vtw && !tw || privState.isModeVU && !tw) 85 86 private val rwSatp_EX_II = csrAccess && privState.isModeHS && tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U) 87 private val rwSatp_EX_VI = csrAccess && privState.isModeVS && vtvm && (addr === CSRs.satp.U) 88 89 private val rwCustom_EX_II = csrAccess && privState.isModeVS && csrIsCustom 90 91 io.out.illegal := csrAccess && csrAccessIllegal || mret && mretIllegal || sret && sretIllegal 92 93 // Todo: check correct 94 io.out.EX_II := io.out.illegal && !privState.isVirtual || wfi_EX_II || rwSatp_EX_II || rwCustom_EX_II 95 io.out.EX_VI := io.out.illegal && privState.isVirtual || wfi_EX_VI || rwSatp_EX_VI 96 97 io.out.hasLegalWen := io.in.csrAccess.wen && !csrAccessIllegal && debugRegCanAccess && triggerRegCanAccess 98 io.out.hasLegalMret := mret && !mretIllegal 99 io.out.hasLegalSret := sret && !sretIllegal 100 io.out.hasLegalWfi := wfi && !wfi_EX_II && !wfi_EX_VI 101} 102 103class CSRPermitIO extends Bundle { 104 val in = Input(new Bundle { 105 val csrAccess = new Bundle { 106 val ren = Bool() 107 val wen = Bool() 108 val addr = UInt(12.W) 109 } 110 val privState = new PrivState 111 val debugMode = Bool() 112 val mret = Bool() 113 val sret = Bool() 114 val wfi = Bool() 115 val csrIsCustom = Bool() 116 val status = new Bundle { 117 // Trap SRET 118 val tsr = Bool() 119 // Virtual Trap SRET 120 val vtsr = Bool() 121 // Timeout Wait 122 val tw = Bool() 123 // Virtual Timeout Wait 124 val vtw = Bool() 125 // Trap Virtual Memory 126 val tvm = Bool() 127 // Virtual Trap Virtual Memory 128 val vtvm = Bool() 129 } 130 }) 131 132 val out = Output(new Bundle { 133 val hasLegalWen = Bool() 134 val hasLegalMret = Bool() 135 val hasLegalSret = Bool() 136 val hasLegalWfi = Bool() 137 // Todo: split illegal into EX_II and EX_VI 138 val illegal = Bool() 139 val EX_II = Bool() 140 val EX_VI = Bool() 141 }) 142} 143