1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 17c84054caSLinJiaweipackage xiangshan.backend.fu 18c84054caSLinJiawei 198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters 20c84054caSLinJiaweiimport chisel3._ 21c84054caSLinJiaweiimport chisel3.util._ 226ab6918fSYinan Xuimport difftest._ 23b6982e83SLemoverimport freechips.rocketchip.util._ 243c02ee8fSwakafaimport utility.MaskedRegMap.WritableMask 25c84054caSLinJiaweiimport utils._ 263c02ee8fSwakafaimport utility._ 276ab6918fSYinan Xuimport xiangshan.ExceptionNO._ 28c84054caSLinJiaweiimport xiangshan._ 29db988794Swangkaifanimport xiangshan.backend.fu.util._ 306ab6918fSYinan Xuimport xiangshan.cache._ 31730cfbc0SXuan Huimport xiangshan.backend.Bundles.ExceptionInfo 3262a2cb19SXuan Huimport xiangshan.backend.fu.util.CSR.CSRNamedConstant.ContextStatus 3362a2cb19SXuan Huimport utils.MathUtils.{BigIntGenMask, BigIntNot} 34c84054caSLinJiawei 352225d46eSJiawei Linclass FpuCsrIO extends Bundle { 367f1506e3SLinJiawei val fflags = Output(Valid(UInt(5.W))) 37c84054caSLinJiawei val isIllegal = Output(Bool()) 38c84054caSLinJiawei val dirty_fs = Output(Bool()) 39c84054caSLinJiawei val frm = Input(UInt(3.W)) 40c84054caSLinJiawei} 41c84054caSLinJiawei 42daa01159SZiyue Zhangclass VpuCsrIO(implicit p: Parameters) extends XSBundle { 43daa01159SZiyue Zhang val vstart = Input(UInt(XLEN.W)) 44daa01159SZiyue Zhang val vxsat = Input(UInt(1.W)) 45daa01159SZiyue Zhang val vxrm = Input(UInt(2.W)) 4635d1557aSZiyue Zhang val vcsr = Input(UInt(XLEN.W)) 47daa01159SZiyue Zhang val vl = Input(UInt(XLEN.W)) 4835d1557aSZiyue Zhang val vtype = Input(UInt(XLEN.W)) 49daa01159SZiyue Zhang val vlenb = Input(UInt(XLEN.W)) 50daa01159SZiyue Zhang 51daa01159SZiyue Zhang val vill = Input(UInt(1.W)) 52daa01159SZiyue Zhang val vma = Input(UInt(1.W)) 53daa01159SZiyue Zhang val vta = Input(UInt(1.W)) 54daa01159SZiyue Zhang val vsew = Input(UInt(3.W)) 55daa01159SZiyue Zhang val vlmul = Input(UInt(3.W)) 56daa01159SZiyue Zhang 5735d1557aSZiyue Zhang val set_vstart = Output(Valid(UInt(XLEN.W))) 58daa01159SZiyue Zhang val set_vl = Output(Valid(UInt(XLEN.W))) 5935d1557aSZiyue Zhang val set_vtype = Output(Valid(UInt(XLEN.W))) 606355a2b7Sczw val set_vxsat = Output(Valid(UInt(1.W))) 61daa01159SZiyue Zhang 62daa01159SZiyue Zhang val dirty_vs = Output(Bool()) 63daa01159SZiyue Zhang} 64daa01159SZiyue Zhang 65b2e234ebSLinJiawei 662225d46eSJiawei Linclass PerfCounterIO(implicit p: Parameters) extends XSBundle { 671ca0e4f3SYinan Xu val perfEventsFrontend = Vec(numCSRPCntFrontend, new PerfEvent) 681ca0e4f3SYinan Xu val perfEventsCtrl = Vec(numCSRPCntCtrl, new PerfEvent) 691ca0e4f3SYinan Xu val perfEventsLsu = Vec(numCSRPCntLsu, new PerfEvent) 701ca0e4f3SYinan Xu val perfEventsHc = Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent) 71edd6ddbcSwakafa val retiredInstr = UInt(3.W) 72edd6ddbcSwakafa val frontendInfo = new Bundle { 73edd6ddbcSwakafa val ibufFull = Bool() 74e0d9a9f0SLingrui98 val bpuInfo = new Bundle { 75e0d9a9f0SLingrui98 val bpRight = UInt(XLEN.W) 76e0d9a9f0SLingrui98 val bpWrong = UInt(XLEN.W) 77e0d9a9f0SLingrui98 } 78edd6ddbcSwakafa } 79edd6ddbcSwakafa val ctrlInfo = new Bundle { 809aca92b9SYinan Xu val robFull = Bool() 81edd6ddbcSwakafa val intdqFull = Bool() 82edd6ddbcSwakafa val fpdqFull = Bool() 83edd6ddbcSwakafa val lsdqFull = Bool() 84edd6ddbcSwakafa } 85edd6ddbcSwakafa val memInfo = new Bundle { 86edd6ddbcSwakafa val sqFull = Bool() 87edd6ddbcSwakafa val lqFull = Bool() 88edd6ddbcSwakafa val dcacheMSHRFull = Bool() 89edd6ddbcSwakafa } 9062ab1317SYinan Xu} 9162ab1317SYinan Xu 922225d46eSJiawei Linclass CSRFileIO(implicit p: Parameters) extends XSBundle { 93f57f7f2aSYangyu Chen val hartId = Input(UInt(hartIdLen.W)) 94129a273eSYinan Xu // output (for func === CSROpType.jmp) 95edd6ddbcSwakafa val perf = Input(new PerfCounterIO) 968635f18fSwangkaifan val isPerfCnt = Output(Bool()) 97129a273eSYinan Xu // to FPU 98129a273eSYinan Xu val fpu = Flipped(new FpuCsrIO) 99daa01159SZiyue Zhang // to VPU 100daa01159SZiyue Zhang val vpu = Flipped(new VpuCsrIO) 101bf9968b2SYinan Xu // from rob 1023a474d38SYinan Xu val exception = Flipped(ValidIO(new ExceptionInfo)) 103129a273eSYinan Xu // to ROB 104ac5a5d53SLinJiawei val isXRet = Output(Bool()) 105129a273eSYinan Xu val trapTarget = Output(UInt(VAddrBits.W)) 106129a273eSYinan Xu val interrupt = Output(Bool()) 1075c95ea2eSYinan Xu val wfi_event = Output(Bool()) 108129a273eSYinan Xu // from LSQ 109129a273eSYinan Xu val memExceptionVAddr = Input(UInt(VAddrBits.W)) 110d0de7e4aSpeixiaokun val memExceptionGPAddr = Input(UInt(GPAddrBits.W)) 111129a273eSYinan Xu // from outside cpu,externalInterrupt 112129a273eSYinan Xu val externalInterrupt = new ExternalInterruptIO 113129a273eSYinan Xu // TLB 114129a273eSYinan Xu val tlb = Output(new TlbCsrBundle) 115d4aca96cSlqre // Debug Mode 116d7dd1af1SLi Qianruo // val singleStep = Output(Bool()) 117d4aca96cSlqre val debugMode = Output(Bool()) 118e5adbe81SLemover // to Fence to disable sfence 119e5adbe81SLemover val disableSfence = Output(Bool()) 120d0de7e4aSpeixiaokun // to Fence to disable hfence.gvma 121d0de7e4aSpeixiaokun val disableHfenceg = Output(Bool()) 122d0de7e4aSpeixiaokun // to Fence to disable hfence.vvma 123d0de7e4aSpeixiaokun val disableHfencev = Output(Bool()) 124e377d77eSWilliam Wang // Custom microarchiture ctrl signal 125e377d77eSWilliam Wang val customCtrl = Output(new CustomCSRCtrlIO) 126e377d77eSWilliam Wang // distributed csr write 12770899835SWilliam Wang val distributedUpdate = Vec(2, Flipped(new DistributedCSRUpdateReq)) 12835a47a38SYinan Xu} 12935a47a38SYinan Xu 130a8db15d8Sfdyclass VtypeStruct(implicit p: Parameters) extends XSBundle { 131a8db15d8Sfdy val vill = UInt(1.W) 132a8db15d8Sfdy val reserved = UInt((XLEN - 9).W) 133a8db15d8Sfdy val vma = UInt(1.W) 134a8db15d8Sfdy val vta = UInt(1.W) 135a8db15d8Sfdy val vsew = UInt(3.W) 136a8db15d8Sfdy val vlmul = UInt(3.W) 137a8db15d8Sfdy} 138a8db15d8Sfdy 139d91483a6Sfdyclass CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) 1403b739f49SXuan Hu with HasCSRConst 1413b739f49SXuan Hu with PMPMethod 1423b739f49SXuan Hu with PMAMethod 1433b739f49SXuan Hu with HasXSParameter 144f7af4c74Schengguanghui with SdtrigExt 145f7af4c74Schengguanghui with DebugCSR 14635a47a38SYinan Xu{ 1473b739f49SXuan Hu val csrio = io.csrio.get 148c84054caSLinJiawei 149e18c367fSLinJiawei val flushPipe = Wire(Bool()) 150c84054caSLinJiawei 151e18c367fSLinJiawei val (valid, src1, src2, func) = ( 152e18c367fSLinJiawei io.in.valid, 1536a35d972SXuan Hu io.in.bits.data.src(0), 1546a35d972SXuan Hu io.in.bits.data.imm, 1556a35d972SXuan Hu io.in.bits.ctrl.fuOpType 156e18c367fSLinJiawei ) 157c84054caSLinJiawei 158c84054caSLinJiawei // CSR define 159d0de7e4aSpeixiaokun val virtMode = RegInit(false.B) 160d0de7e4aSpeixiaokun csrio.customCtrl.virtMode := virtMode 161c84054caSLinJiawei 162c84054caSLinJiawei class Priv extends Bundle { 163c84054caSLinJiawei val m = Output(Bool()) 164d0de7e4aSpeixiaokun val h = Output(Bool()) // unused 165c84054caSLinJiawei val s = Output(Bool()) 166c84054caSLinJiawei val u = Output(Bool()) 167c84054caSLinJiawei } 168c84054caSLinJiawei 169c84054caSLinJiawei class MstatusStruct extends Bundle { 170c84054caSLinJiawei val sd = Output(UInt(1.W)) 1718e7b11e5SWilliam Wang 172d0de7e4aSpeixiaokun val pad1 = if (XLEN == 64 && HasHExtension) Output(UInt(23.W)) else if (XLEN == 64) Output(UInt(25.W)) else null 173d0de7e4aSpeixiaokun val mpv = if (XLEN == 64 && HasHExtension) Output(UInt(1.W)) else null 174d0de7e4aSpeixiaokun val gva = if (XLEN == 64 && HasHExtension) Output(UInt(1.W)) else null 1757d9edc86SLemover val mbe = if (XLEN == 64) Output(UInt(1.W)) else null 1767d9edc86SLemover val sbe = if (XLEN == 64) Output(UInt(1.W)) else null 1778e7b11e5SWilliam Wang val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 1788e7b11e5SWilliam Wang val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 1798e7b11e5SWilliam Wang val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 1808e7b11e5SWilliam Wang 181c84054caSLinJiawei val tsr = Output(UInt(1.W)) 182c84054caSLinJiawei val tw = Output(UInt(1.W)) 1838e7b11e5SWilliam Wang val tvm = Output(UInt(1.W)) 184c84054caSLinJiawei val mxr = Output(UInt(1.W)) 185c84054caSLinJiawei val sum = Output(UInt(1.W)) 186c84054caSLinJiawei val mprv = Output(UInt(1.W)) 187c84054caSLinJiawei val xs = Output(UInt(2.W)) 188c84054caSLinJiawei val fs = Output(UInt(2.W)) 189c84054caSLinJiawei val mpp = Output(UInt(2.W)) 190daa01159SZiyue Zhang val vs = Output(UInt(2.W)) 191c84054caSLinJiawei val spp = Output(UInt(1.W)) 192c84054caSLinJiawei val pie = new Priv 193c84054caSLinJiawei val ie = new Priv 194c84054caSLinJiawei assert(this.getWidth == XLEN) 1957d9edc86SLemover 1967d9edc86SLemover def ube = pie.h // a little ugly 1977d9edc86SLemover def ube_(r: UInt): Unit = { 1987d9edc86SLemover pie.h := r(0) 1997d9edc86SLemover } 200c84054caSLinJiawei } 201c84054caSLinJiawei 202d0de7e4aSpeixiaokun class HstatusStruct extends Bundle { 203d0de7e4aSpeixiaokun val pad4 = if (HSXLEN == 64) Output(UInt(30.W)) else null 204d0de7e4aSpeixiaokun val vsxl = if (HSXLEN == 64) Output(UInt(2.W)) else null 205d0de7e4aSpeixiaokun val pad3 = Output(UInt(9.W)) 206d0de7e4aSpeixiaokun val vtsr = Output(UInt(1.W)) 207d0de7e4aSpeixiaokun val vtw = Output(UInt(1.W)) 208d0de7e4aSpeixiaokun val vtvm = Output(UInt(1.W)) 209d0de7e4aSpeixiaokun val pad2 = Output(UInt(2.W)) 210d0de7e4aSpeixiaokun val vgein = Output(UInt(6.W)) 211d0de7e4aSpeixiaokun val pad1 = Output(UInt(2.W)) 212d0de7e4aSpeixiaokun val hu = Output(UInt(1.W)) 213d0de7e4aSpeixiaokun val spvp = Output(UInt(1.W)) 214d0de7e4aSpeixiaokun val spv = Output(UInt(1.W)) 215d0de7e4aSpeixiaokun val gva = Output(UInt(1.W)) 216d0de7e4aSpeixiaokun val vsbe = Output(UInt(1.W)) 217d0de7e4aSpeixiaokun val pad0 = Output(UInt(5.W)) 218d0de7e4aSpeixiaokun assert(this.getWidth == XLEN) 219d0de7e4aSpeixiaokun } 220d0de7e4aSpeixiaokun 221c84054caSLinJiawei class Interrupt extends Bundle { 222d4aca96cSlqre// val d = Output(Bool()) // Debug 223c84054caSLinJiawei val e = new Priv 224c84054caSLinJiawei val t = new Priv 225c84054caSLinJiawei val s = new Priv 226c84054caSLinJiawei } 227c84054caSLinJiawei 228d4aca96cSlqre // Debug CSRs 229f7af4c74Schengguanghui val dcsr = RegInit(UInt(32.W), DcsrStruct.init) 230d4aca96cSlqre val dpc = Reg(UInt(64.W)) 231f7af4c74Schengguanghui val dscratch0 = Reg(UInt(64.W)) 232d4aca96cSlqre val dscratch1 = Reg(UInt(64.W)) 233d4aca96cSlqre val debugMode = RegInit(false.B) 234f7af4c74Schengguanghui val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable 235d4aca96cSlqre csrio.debugMode := debugMode 236d4aca96cSlqre 237d4aca96cSlqre val dpcPrev = RegNext(dpc) 2381097f021SLi Qianruo XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x\n", dpc, dpcPrev) 239d4aca96cSlqre 240d4aca96cSlqre val dcsrData = Wire(new DcsrStruct) 241d4aca96cSlqre dcsrData := dcsr.asTypeOf(new DcsrStruct) 242d7dd1af1SLi Qianruo val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(4) | GenMask(2, 0), XLEN)// Dcsr write mask 243d4aca96cSlqre def dcsrUpdateSideEffect(dcsr: UInt): UInt = { 244d4aca96cSlqre val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct)) 245d4aca96cSlqre val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11 246d4aca96cSlqre dcsrNew 247d4aca96cSlqre } 248d7dd1af1SLi Qianruo // csrio.singleStep := dcsrData.step 249d7dd1af1SLi Qianruo csrio.customCtrl.singlestep := dcsrData.step && !debugMode 250d4aca96cSlqre 25172951335SLi Qianruo // Trigger CSRs 252f7af4c74Schengguanghui private val tselectPhy = RegInit(0.U(log2Up(TriggerNum).W)) 25372951335SLi Qianruo 254f7af4c74Schengguanghui private val tdata1RegVec = RegInit(VecInit(Seq.fill(TriggerNum)(Tdata1Bundle.default))) 255f7af4c74Schengguanghui private val tdata2RegVec = RegInit(VecInit(Seq.fill(TriggerNum)(0.U(64.W)))) 256f7af4c74Schengguanghui private val tdata1WireVec = tdata1RegVec.map(_.asTypeOf(new Tdata1Bundle)) 257f7af4c74Schengguanghui private val tdata2WireVec = tdata2RegVec 258f7af4c74Schengguanghui private val tdata1Selected = tdata1RegVec(tselectPhy).asTypeOf(new Tdata1Bundle) 259f7af4c74Schengguanghui private val tdata2Selected = tdata2RegVec(tselectPhy) 260f7af4c74Schengguanghui private val newTriggerChainVec = UIntToOH(tselectPhy, TriggerNum).asBools | tdata1WireVec.map(_.data.asTypeOf(new MControlData).chain) 261f7af4c74Schengguanghui private val newTriggerChainIsLegal = TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength) 262f7af4c74Schengguanghui val tinfo = RegInit((BigInt(1) << TrigTypeEnum.MCONTROL.litValue.toInt).U(XLEN.W)) // This value should be 4.U 263716f717fSLi Qianruo 26472951335SLi Qianruo 26572951335SLi Qianruo def WriteTselect(wdata: UInt) = { 266*5f28e666Schengguanghui Mux(wdata < TriggerNum.U, wdata(log2Up(TriggerNum) - 1, 0), tselectPhy) 26772951335SLi Qianruo } 26872951335SLi Qianruo 269f7af4c74Schengguanghui def GenTdataDistribute(tdata1: Tdata1Bundle, tdata2: UInt): MatchTriggerIO = { 27072951335SLi Qianruo val res = Wire(new MatchTriggerIO) 271f7af4c74Schengguanghui val mcontrol: MControlData = WireInit(tdata1.data.asTypeOf(new MControlData)) 272f7af4c74Schengguanghui res.matchType := mcontrol.match_.asUInt 273f7af4c74Schengguanghui res.select := mcontrol.select 274f7af4c74Schengguanghui res.timing := mcontrol.timing 275f7af4c74Schengguanghui res.action := mcontrol.action.asUInt 276f7af4c74Schengguanghui res.chain := mcontrol.chain 277f7af4c74Schengguanghui res.execute := mcontrol.execute 278f7af4c74Schengguanghui res.load := mcontrol.load 279f7af4c74Schengguanghui res.store := mcontrol.store 28072951335SLi Qianruo res.tdata2 := tdata2 28172951335SLi Qianruo res 28272951335SLi Qianruo } 28372951335SLi Qianruo 284f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tUpdate.bits.addr := tselectPhy 285f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tUpdate.bits.addr := tselectPhy 286f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tUpdate.bits.tdata := GenTdataDistribute(tdata1Selected, tdata2Selected) 287f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tUpdate.bits.tdata := GenTdataDistribute(tdata1Selected, tdata2Selected) 28872951335SLi Qianruo 289c84054caSLinJiawei // Machine-Level CSRs 290a4e57ea3SLi Qianruo // mtvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 291a4e57ea3SLi Qianruo val mtvecMask = ~(0x2.U(XLEN.W)) 292c84054caSLinJiawei val mtvec = RegInit(UInt(XLEN.W), 0.U) 293c84054caSLinJiawei val mcounteren = RegInit(UInt(XLEN.W), 0.U) 294e4b1ccacSxuzefan // Currently, XiangShan don't support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 295e4b1ccacSxuzefan val mcounterenMask = 0.U(XLEN.W) 296c84054caSLinJiawei val mcause = RegInit(UInt(XLEN.W), 0.U) 297c84054caSLinJiawei val mtval = RegInit(UInt(XLEN.W), 0.U) 298d0de7e4aSpeixiaokun val mtval2 = RegInit(UInt(XLEN.W), 0.U) 299d0de7e4aSpeixiaokun val mtinst = RegInit(UInt(XLEN.W), 0.U) 300d0de7e4aSpeixiaokun val mepc = RegInit(UInt(XLEN.W), 0.U) 301e30fd06aSYinan Xu // Page 36 in riscv-priv: The low bit of mepc (mepc[0]) is always zero. 302e30fd06aSYinan Xu val mepcMask = ~(0x1.U(XLEN.W)) 303c84054caSLinJiawei 304c84054caSLinJiawei val mie = RegInit(0.U(XLEN.W)) 305c84054caSLinJiawei val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 3065dabf2dfSYinan Xu val mipReg = RegInit(0.U(XLEN.W)) 307d7e392d1Sxuzefan val mipMask = ZeroExt(Array( 308d7e392d1Sxuzefan 1, // SSIP 309d7e392d1Sxuzefan 2, // VSSIP 310d7e392d1Sxuzefan 3, // MSIP 311d7e392d1Sxuzefan 5, // STIP 312d7e392d1Sxuzefan 6, // VSTIP 313d7e392d1Sxuzefan 7, // MTIP 314d7e392d1Sxuzefan 9, // SEIP 315d7e392d1Sxuzefan 10, // VSEIP 316d7e392d1Sxuzefan 11, // MEIP 317d7e392d1Sxuzefan 12, // SGEIP 318d7e392d1Sxuzefan ).map(GenMask(_)).reduce(_ | _), XLEN) 319c84054caSLinJiawei val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 320c84054caSLinJiawei 321d0de7e4aSpeixiaokun val mip_mie_WMask_H = if(HasHExtension){((1 << 2) | (1 << 6) | (1 << 10) | (1 << 12)).U(XLEN.W)}else{0.U(XLEN.W)} 322d0de7e4aSpeixiaokun val vssip_Mask = (1 << 2).U(XLEN.W) 323d0de7e4aSpeixiaokun 324d0de7e4aSpeixiaokun val mipWMask = vssip_Mask | ((1 << 9) | (1 << 5) | (1 << 1)).U(XLEN.W) 32544f8e3e4Speixiaokun val mieWMask = mip_mie_WMask_H | "haaa".U(XLEN.W) 326d0de7e4aSpeixiaokun 32767ba96b4SYinan Xu def getMisaMxl(mxl: BigInt): BigInt = mxl << (XLEN - 2) 32867ba96b4SYinan Xu def getMisaExt(ext: Char): Long = 1 << (ext.toInt - 'a'.toInt) 329c84054caSLinJiawei var extList = List('a', 's', 'i', 'u') 330c84054caSLinJiawei if (HasMExtension) { extList = extList :+ 'm' } 331c84054caSLinJiawei if (HasCExtension) { extList = extList :+ 'c' } 332d0de7e4aSpeixiaokun if (HasHExtension) { extList = extList :+ 'h' } 333c84054caSLinJiawei if (HasFPU) { extList = extList ++ List('f', 'd') } 3340ba52110SZiyue Zhang if (HasVPU) { extList = extList :+ 'v' } 335d0de7e4aSpeixiaokun val misaInitVal = getMisaMxl(2) | extList.foldLeft(0L)((sum, i) => sum | getMisaExt(i)) //"h8000000000141185".U 33667ba96b4SYinan Xu val misa = RegInit(UInt(XLEN.W), misaInitVal.U) 337ddb6dcf0SXuan Hu println(s"[CSR] supported isa ext: $extList") 338bc5ff277Swangkaifan 339c84054caSLinJiawei // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 340c84054caSLinJiawei // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 341c84054caSLinJiawei 34206490c40Speixiaokun // Machine Configuration 34306490c40Speixiaokun val menvcfg = RegInit(UInt(XLEN.W), 0.U) 34406490c40Speixiaokun 345c84054caSLinJiawei val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 346e1b773eaSLuo Jia val marchid = RegInit(UInt(XLEN.W), 25.U) // architecture id for XiangShan is 25; see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 347c84054caSLinJiawei val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 34867ba96b4SYinan Xu val mhartid = Reg(UInt(XLEN.W)) // the hardware thread running the code 34967ba96b4SYinan Xu when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 35067ba96b4SYinan Xu mhartid := csrio.hartId 35167ba96b4SYinan Xu } 3527d9edc86SLemover val mconfigptr = RegInit(UInt(XLEN.W), 0.U) // the read-only pointer pointing to the platform config structure, 0 for not supported. 35362a2cb19SXuan Hu val mstatus = RegInit("ha00002200".U(XLEN.W)) 354bc5ff277Swangkaifan 355c84054caSLinJiawei // mstatus Value Table 35662a2cb19SXuan Hu // | sd | Read Only 35762a2cb19SXuan Hu // | pad1 | WPRI 358c84054caSLinJiawei // | sxl | hardlinked to 10, use 00 to pass xv6 test 359e30fd06aSYinan Xu // | uxl | hardlinked to 10 360c84054caSLinJiawei // | pad0 | 361c84054caSLinJiawei // | tsr | 362c84054caSLinJiawei // | tw | 3638e7b11e5SWilliam Wang // | tvm | 364c84054caSLinJiawei // | mxr | 365c84054caSLinJiawei // | sum | 366c84054caSLinJiawei // | mprv | 367c84054caSLinJiawei // | xs | 00 | 36880dd83d8SYinan Xu // | fs | 01 | 369c84054caSLinJiawei // | mpp | 00 | 37062a2cb19SXuan Hu // | vs | 01 | 371c84054caSLinJiawei // | spp | 0 | 3728e7b11e5SWilliam Wang // | pie | 0000 | pie.h is used as UBE 373c84054caSLinJiawei // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 374bc5ff277Swangkaifan 375c84054caSLinJiawei val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 376c84054caSLinJiawei def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 377c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 37862a2cb19SXuan Hu // Cat(sd, other) 37962a2cb19SXuan Hu val mstatusNew = Cat( 38062a2cb19SXuan Hu mstatusOld.xs === ContextStatus.dirty || mstatusOld.fs === ContextStatus.dirty || mstatusOld.vs === ContextStatus.dirty, 38162a2cb19SXuan Hu mstatus(XLEN-2, 0) 38262a2cb19SXuan Hu ) 383c84054caSLinJiawei mstatusNew 384c84054caSLinJiawei } 38585052be5Speixiaokun def vsstatusUpdateSideEffect(vsstatus: UInt): UInt = { 38685052be5Speixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 38785052be5Speixiaokun val vsstatusNew = Cat(vsstatusOld.xs === "b11".U || vsstatusOld.fs === "b11".U, vsstatus(XLEN-2, 0)) 38885052be5Speixiaokun vsstatusNew 38985052be5Speixiaokun } 390e30fd06aSYinan Xu val mstatusWMask = (~ZeroExt(( 391d0de7e4aSpeixiaokun (if(HasHExtension) { 392d0de7e4aSpeixiaokun GenMask(XLEN - 2, 40) | 393d0de7e4aSpeixiaokun GenMask(37, 36) // MBE SBE 394d0de7e4aSpeixiaokun } else 39562a2cb19SXuan Hu GenMask(63) | // SD is read-only 396e25e4d90SXuan Hu GenMask(62, 36) ) | // WPRI 397e30fd06aSYinan Xu GenMask(35, 32) | // SXL and UXL cannot be changed 398e30fd06aSYinan Xu GenMask(31, 23) | // WPRI 399705cbec3SLemover GenMask(16, 15) | // XS is read-only 400443741b9SYinan Xu GenMask(6) | // UBE, always little-endian (0) 401d0de7e4aSpeixiaokun GenMask(2) // WPRI 402d0de7e4aSpeixiaokun ), 64)).asUInt 403d0de7e4aSpeixiaokun val mstatusMask = (~ZeroExt(( 404d0de7e4aSpeixiaokun (if (HasHExtension) { 405d0de7e4aSpeixiaokun GenMask(XLEN - 2, 40) | 406d0de7e4aSpeixiaokun GenMask(37, 36) // MBE SBE 407d0de7e4aSpeixiaokun } else 408d0de7e4aSpeixiaokun GenMask(XLEN - 2, 36)) | // WPRI 409d0de7e4aSpeixiaokun GenMask(31, 23) | // WPRI 410d0de7e4aSpeixiaokun GenMask(10, 9) | // WPRI 411d0de7e4aSpeixiaokun GenMask(6) | // WPRI 412443741b9SYinan Xu GenMask(4) | // WPRI 413443741b9SYinan Xu GenMask(2) | // WPRI 414443741b9SYinan Xu GenMask(0) // WPRI 4155d669833SYinan Xu ), 64)).asUInt 4168e7b11e5SWilliam Wang 417c84054caSLinJiawei val medeleg = RegInit(UInt(XLEN.W), 0.U) 418d0de7e4aSpeixiaokun val midelegInit = if(HasHExtension){((1 << 12) | (1 << 10) | (1 << 6) | (1 << 2)).U}else{0.U} 419d0de7e4aSpeixiaokun val medelegWMask = if(HasHExtension) { 420e20ac1e1Sxuzefan "hf0b7ff".U(XLEN.W) 421d0de7e4aSpeixiaokun }else { 422d0de7e4aSpeixiaokun "hb3ff".U(XLEN.W) 423d0de7e4aSpeixiaokun } 424d0de7e4aSpeixiaokun 425d0de7e4aSpeixiaokun 426d0de7e4aSpeixiaokun val mideleg = RegInit(UInt(XLEN.W), midelegInit) 427c84054caSLinJiawei val mscratch = RegInit(UInt(XLEN.W), 0.U) 428c84054caSLinJiawei 429d0de7e4aSpeixiaokun val midelegWMask = "h222".U(XLEN.W) 430b6982e83SLemover // PMP Mapping 431ca2f90a6SLemover val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter 432ca2f90a6SLemover val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter 433ca2f90a6SLemover val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp) 434ca2f90a6SLemover val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma) 435672c4648Sceba // !WARNNING: pmp and pma CSRs are not checked in difftest. 436c84054caSLinJiawei 437d0de7e4aSpeixiaokun // Supervisor-Level CSRs 438c84054caSLinJiawei 43962a2cb19SXuan Hu val sstatusWNmask: BigInt = ( 44062a2cb19SXuan Hu BigIntGenMask(63) | // SD is read-only 44162a2cb19SXuan Hu BigIntGenMask(62, 34) | // WPRI 44262a2cb19SXuan Hu BigIntGenMask(33, 32) | // UXL is hard-wired to 64(b10) 44362a2cb19SXuan Hu BigIntGenMask(31, 20) | // WPRI 44462a2cb19SXuan Hu BigIntGenMask(17) | // WPRI 44562a2cb19SXuan Hu BigIntGenMask(16, 15) | // XS is read-only to zero 44662a2cb19SXuan Hu BigIntGenMask(12, 11) | // WPRI 44762a2cb19SXuan Hu BigIntGenMask(7) | // WPRI 44862a2cb19SXuan Hu BigIntGenMask(6) | // UBE is always little-endian (0) 44962a2cb19SXuan Hu BigIntGenMask(4, 2) | // WPRI 45062a2cb19SXuan Hu BigIntGenMask(0) // WPRI 45162a2cb19SXuan Hu ) 45262a2cb19SXuan Hu 45362a2cb19SXuan Hu val sstatusWmask = BigIntNot(sstatusWNmask).U(XLEN.W) 45462a2cb19SXuan Hu val sstatusRmask = ( 45562a2cb19SXuan Hu BigIntGenMask(63) | // SD 45662a2cb19SXuan Hu BigIntGenMask(33, 32) | // UXL 45762a2cb19SXuan Hu BigIntGenMask(19) | // MXR 45862a2cb19SXuan Hu BigIntGenMask(18) | // SUM 45962a2cb19SXuan Hu BigIntGenMask(16, 15) | // XS 46062a2cb19SXuan Hu BigIntGenMask(14, 13) | // FS 46162a2cb19SXuan Hu BigIntGenMask(10, 9 ) | // VS 46262a2cb19SXuan Hu BigIntGenMask(8) | // SPP 46362a2cb19SXuan Hu BigIntGenMask(6) | // UBE: hard wired to 0 46462a2cb19SXuan Hu BigIntGenMask(5) | // SPIE 46562a2cb19SXuan Hu BigIntGenMask(1) 46662a2cb19SXuan Hu ).U(XLEN.W) 46762a2cb19SXuan Hu 46862a2cb19SXuan Hu println(s"sstatusWNmask: 0x${sstatusWNmask.toString(16)}") 46962a2cb19SXuan Hu println(s"sstatusWmask: 0x${sstatusWmask.litValue.toString(16)}") 47062a2cb19SXuan Hu println(s"sstatusRmask: 0x${sstatusRmask.litValue.toString(16)}") 47162a2cb19SXuan Hu 472a4e57ea3SLi Qianruo // stvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 473a4e57ea3SLi Qianruo val stvecMask = ~(0x2.U(XLEN.W)) 474c84054caSLinJiawei val stvec = RegInit(UInt(XLEN.W), 0.U) 475c84054caSLinJiawei // val sie = RegInit(0.U(XLEN.W)) 476c84054caSLinJiawei val sieMask = "h222".U & mideleg 477c84054caSLinJiawei val sipMask = "h222".U & mideleg 4785dabf2dfSYinan Xu val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode 47934230194Sjinyue110 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 480df2b1479SZhangZifei // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 48145f497a4Shappy-lx // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0 48245f497a4Shappy-lx // TODO: use config to control the length of asid 48345f497a4Shappy-lx // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0 484705cbec3SLemover val satpMask = Cat("h8".U(Satp_Mode_len.W), satp_part_wmask(Satp_Asid_len, AsidLength), satp_part_wmask(Satp_Addr_len, PAddrBits-12)) 485c84054caSLinJiawei val sepc = RegInit(UInt(XLEN.W), 0.U) 486e30fd06aSYinan Xu // Page 60 in riscv-priv: The low bit of sepc (sepc[0]) is always zero. 487e30fd06aSYinan Xu val sepcMask = ~(0x1.U(XLEN.W)) 488c84054caSLinJiawei val scause = RegInit(UInt(XLEN.W), 0.U) 489d0de7e4aSpeixiaokun val stval = RegInit(UInt(XLEN.W), 0.U) 490c84054caSLinJiawei val sscratch = RegInit(UInt(XLEN.W), 0.U) 491c84054caSLinJiawei val scounteren = RegInit(UInt(XLEN.W), 0.U) 4926ade72d9Sxuzefan val senvcfg = RegInit(UInt(XLEN.W), 0.U) // !WARNING: there is no logic about this CSR. 493e4b1ccacSxuzefan // Currently, XiangShan don't support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 494e4b1ccacSxuzefan val scounterenMask = 0.U(XLEN.W) 495fcff7e94SZhangZifei 496eedc2e58SSteve Gou // sbpctl 497eedc2e58SSteve Gou // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB} 498eedc2e58SSteve Gou val sbpctl = RegInit(UInt(XLEN.W), "h7f".U) 499eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0) 500eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.btb_enable := sbpctl(1) 501eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.bim_enable := sbpctl(2) 502eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3) 503eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.sc_enable := sbpctl(4) 504eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ras_enable := sbpctl(5) 505eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6) 5062b8b2e7aSWilliam Wang 507ecccf78fSJay // spfctl Bit 0: L1I Cache Prefetcher Enable 5082b8b2e7aSWilliam Wang // spfctl Bit 1: L2Cache Prefetcher Enable 50985de5caeSLinJiawei // spfctl Bit 2: L1D Cache Prefetcher Enable 51085de5caeSLinJiawei // spfctl Bit 3: L1D train prefetch on hit 51185de5caeSLinJiawei // spfctl Bit 4: L1D prefetch enable agt 51285de5caeSLinJiawei // spfctl Bit 5: L1D prefetch enable pht 513c65495a4SLinJiawei // spfctl Bit [9:6]: L1D prefetch active page threshold 514c65495a4SLinJiawei // spfctl Bit [15:10]: L1D prefetch active page stride 5155d13017eSLinJiawei // turn off L2 BOP, turn on L1 SMS by default 516c65495a4SLinJiawei val spfctl = RegInit(UInt(XLEN.W), Seq( 517edbf1204SLinJiawei 0 << 17, // L2 pf store only [17] init: false 518edbf1204SLinJiawei 1 << 16, // L1D pf enable stride [16] init: true 519f1d78cf7SLinJiawei 30 << 10, // L1D active page stride [15:10] init: 30 520f1d78cf7SLinJiawei 12 << 6, // L1D active page threshold [9:6] init: 12 521f1d78cf7SLinJiawei 1 << 5, // L1D enable pht [5] init: true 522f1d78cf7SLinJiawei 1 << 4, // L1D enable agt [4] init: true 523f1d78cf7SLinJiawei 0 << 3, // L1D train on hit [3] init: false 524f1d78cf7SLinJiawei 1 << 2, // L1D pf enable [2] init: true 525f1d78cf7SLinJiawei 1 << 1, // L2 pf enable [1] init: true 526f1d78cf7SLinJiawei 1 << 0, // L1I pf enable [0] init: true 527c65495a4SLinJiawei ).reduce(_|_).U(XLEN.W)) 528ecccf78fSJay csrio.customCtrl.l1I_pf_enable := spfctl(0) 52935a47a38SYinan Xu csrio.customCtrl.l2_pf_enable := spfctl(1) 53085de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable := spfctl(2) 53185de5caeSLinJiawei csrio.customCtrl.l1D_pf_train_on_hit := spfctl(3) 53285de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable_agt := spfctl(4) 53385de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable_pht := spfctl(5) 5345d13017eSLinJiawei csrio.customCtrl.l1D_pf_active_threshold := spfctl(9, 6) 535c65495a4SLinJiawei csrio.customCtrl.l1D_pf_active_stride := spfctl(15, 10) 536edbf1204SLinJiawei csrio.customCtrl.l1D_pf_enable_stride := spfctl(16) 537edbf1204SLinJiawei csrio.customCtrl.l2_pf_store_only := spfctl(17) 5382b8b2e7aSWilliam Wang 539ecccf78fSJay // sfetchctl Bit 0: L1I Cache Parity check enable 540ecccf78fSJay val sfetchctl = RegInit(UInt(XLEN.W), "b0".U) 541ecccf78fSJay csrio.customCtrl.icache_parity_enable := sfetchctl(0) 542ecccf78fSJay 5432b8b2e7aSWilliam Wang // sdsid: Differentiated Services ID 5442b8b2e7aSWilliam Wang val sdsid = RegInit(UInt(XLEN.W), 0.U) 54535a47a38SYinan Xu csrio.customCtrl.dsid := sdsid 54635a47a38SYinan Xu 5472b8b2e7aSWilliam Wang // slvpredctl: load violation predict settings 5486ef4f6f6SYinan Xu // Default reset period: 2^16 5496ef4f6f6SYinan Xu // Why this number: reset more frequently while keeping the overhead low 5506ef4f6f6SYinan Xu // Overhead: extra two redirections in every 64K cycles => ~0.1% overhead 551560b69b7SHaojin Tang val slvpredctl = Reg(UInt(XLEN.W)) 552560b69b7SHaojin Tang when(reset.asBool) { 553560b69b7SHaojin Tang slvpredctl := Constantin.createRecord("slvpredctl", "h60".U) 554560b69b7SHaojin Tang } 5552b8b2e7aSWilliam Wang csrio.customCtrl.lvpred_disable := slvpredctl(0) 5562b8b2e7aSWilliam Wang csrio.customCtrl.no_spec_load := slvpredctl(1) 557c7160cd3SWilliam Wang csrio.customCtrl.storeset_wait_store := slvpredctl(2) 558c7160cd3SWilliam Wang csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3) 559c7160cd3SWilliam Wang csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4) 5602b8b2e7aSWilliam Wang 561f3f22d72SYinan Xu // smblockctl: memory block configurations 56237225120Ssfencevma // +------------------------------+---+----+----+-----+--------+ 56337225120Ssfencevma // |XLEN-1 8| 7 | 6 | 5 | 4 |3 0| 56437225120Ssfencevma // +------------------------------+---+----+----+-----+--------+ 56537225120Ssfencevma // | Reserved | O | CE | SP | LVC | Th | 56637225120Ssfencevma // +------------------------------+---+----+----+-----+--------+ 56737225120Ssfencevma // Description: 56837225120Ssfencevma // Bit 3-0 : Store buffer flush threshold (Th). 56937225120Ssfencevma // Bit 4 : Enable load violation check after reset (LVC). 57037225120Ssfencevma // Bit 5 : Enable soft-prefetch after reset (SP). 57137225120Ssfencevma // Bit 6 : Enable cache error after reset (CE). 57237225120Ssfencevma // Bit 7 : Enable uncache write outstanding (O). 57337225120Ssfencevma // Others : Reserved. 57437225120Ssfencevma 57567682d05SWilliam Wang val smblockctl_init_val = 57667ba96b4SYinan Xu (0xf & StoreBufferThreshold) | 57767ba96b4SYinan Xu (EnableLdVioCheckAfterReset.toInt << 4) | 57867ba96b4SYinan Xu (EnableSoftPrefetchAfterReset.toInt << 5) | 579dcfaba1dSczw (EnableCacheErrorAfterReset.toInt << 6) | 58067ba96b4SYinan Xu (EnableUncacheWriteOutstanding.toInt << 7) 58167ba96b4SYinan Xu val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val.U) 582f3f22d72SYinan Xu csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0) 58367682d05SWilliam Wang // bits 4: enable load load violation check 584a4e57ea3SLi Qianruo csrio.customCtrl.ldld_vio_check_enable := smblockctl(4) 585a4e57ea3SLi Qianruo csrio.customCtrl.soft_prefetch_enable := smblockctl(5) 586a4e57ea3SLi Qianruo csrio.customCtrl.cache_error_enable := smblockctl(6) 58737225120Ssfencevma csrio.customCtrl.uncache_write_outstanding_enable := smblockctl(7) 588a4e57ea3SLi Qianruo 589a4e57ea3SLi Qianruo println("CSR smblockctl init value:") 590a4e57ea3SLi Qianruo println(" Store buffer replace threshold: " + StoreBufferThreshold) 591a4e57ea3SLi Qianruo println(" Enable ld-ld vio check after reset: " + EnableLdVioCheckAfterReset) 592a4e57ea3SLi Qianruo println(" Enable soft prefetch after reset: " + EnableSoftPrefetchAfterReset) 593a4e57ea3SLi Qianruo println(" Enable cache error after reset: " + EnableCacheErrorAfterReset) 59437225120Ssfencevma println(" Enable uncache write outstanding: " + EnableUncacheWriteOutstanding) 595f3f22d72SYinan Xu 5965b47c58cSYinan Xu val srnctl = RegInit(UInt(XLEN.W), "h7".U) 5975b47c58cSYinan Xu csrio.customCtrl.fusion_enable := srnctl(0) 598af2f7849Shappy-lx csrio.customCtrl.svinval_enable := srnctl(1) 5995b47c58cSYinan Xu csrio.customCtrl.wfi_enable := srnctl(2) 600aac4464eSYinan Xu 601d0de7e4aSpeixiaokun // Hypervisor CSRs 602d0de7e4aSpeixiaokun val hstatusWMask = "h7003c0".U(XLEN.W) 603d0de7e4aSpeixiaokun // hstatus: vtsr, vtw, vtvm, hu, spvp, spv, gva, 604d0de7e4aSpeixiaokun val hstatus = RegInit("h200000000".U(XLEN.W)) 605d0de7e4aSpeixiaokun val hstatusStruct = hstatus.asTypeOf(new HstatusStruct) 606d0de7e4aSpeixiaokun val hedeleg = RegInit(UInt(XLEN.W), 0.U) 607d0de7e4aSpeixiaokun val hideleg = RegInit(UInt(XLEN.W), 0.U) 608d0de7e4aSpeixiaokun val hidelegRMask = mideleg 609d0de7e4aSpeixiaokun val hidelegWMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 610d0de7e4aSpeixiaokun val hgeie = RegInit(UInt(XLEN.W), 0.U) 611d0de7e4aSpeixiaokun val htval = RegInit(UInt(XLEN.W), 0.U) 612d0de7e4aSpeixiaokun // hvip hip hie is part of mip or mie 613d0de7e4aSpeixiaokun val hvipMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 614d0de7e4aSpeixiaokun val hipRMask = (((1 << 12).U | hvipMask) & mideleg) 615d0de7e4aSpeixiaokun val hipWMask = ((1 << 2).U & mideleg)// vssip 616d0de7e4aSpeixiaokun val hieMask = hipRMask 617d0de7e4aSpeixiaokun val htinst = RegInit(UInt(XLEN.W), 0.U) 618d0de7e4aSpeixiaokun val hgeip = RegInit(UInt(XLEN.W), 0.U) 619d0de7e4aSpeixiaokun val henvcfg = RegInit(UInt(XLEN.W), 0.U) 620d0de7e4aSpeixiaokun val hgatp = RegInit(UInt(XLEN.W), 0.U) 621d0de7e4aSpeixiaokun val hgatpMask = Cat("h8".U(Hgatp_Mode_len.W), satp_part_wmask(Hgatp_Vmid_len, VmidLength), satp_part_wmask(Hgatp_Addr_len, PAddrBits-12)) 622d0de7e4aSpeixiaokun val htimedelta = RegInit(UInt(XLEN.W), 0.U) 623d0de7e4aSpeixiaokun val hcounteren = RegInit(UInt(XLEN.W), 0.U) 624e4b1ccacSxuzefan // Currently, XiangShan don't support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 625e4b1ccacSxuzefan val hcounterenMask = 0.U(XLEN.W) 626d0de7e4aSpeixiaokun 627f2a38010Sxuzefan val vsstatus = RegInit("h200002000".U(XLEN.W)) 628d0de7e4aSpeixiaokun val vsstatusStruct = vsstatus.asTypeOf(new MstatusStruct) 629d0de7e4aSpeixiaokun //vsie vsip 630d0de7e4aSpeixiaokun val vsMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 631d0de7e4aSpeixiaokun val vsip_ie_Mask = ZeroExt((hideleg & mideleg & vsMask), XLEN) 632d0de7e4aSpeixiaokun val vsip_WMask = ZeroExt((hideleg & mideleg & vssip_Mask), XLEN) 633d0de7e4aSpeixiaokun val vstvec = RegInit(UInt(XLEN.W), 0.U) 634d0de7e4aSpeixiaokun val vsscratch = RegInit(UInt(XLEN.W), 0.U) 635d0de7e4aSpeixiaokun val vsepc = RegInit(UInt(XLEN.W), 0.U) 636d0de7e4aSpeixiaokun val vscause = RegInit(UInt(XLEN.W), 0.U) 637d0de7e4aSpeixiaokun val vstval = RegInit(UInt(XLEN.W), 0.U) 638d0de7e4aSpeixiaokun val vsatp = RegInit(UInt(XLEN.W), 0.U) 6392b8b2e7aSWilliam Wang val tlbBundle = Wire(new TlbCsrBundle) 64045f497a4Shappy-lx tlbBundle.satp.apply(satp) 641d0de7e4aSpeixiaokun tlbBundle.vsatp.apply(vsatp) 642d0de7e4aSpeixiaokun tlbBundle.hgatp.apply(hgatp) 6432b8b2e7aSWilliam Wang csrio.tlb := tlbBundle 6442b8b2e7aSWilliam Wang 645c84054caSLinJiawei // User-Level CSRs 646c84054caSLinJiawei val uepc = Reg(UInt(XLEN.W)) 647c84054caSLinJiawei 648c84054caSLinJiawei // fcsr 649c84054caSLinJiawei class FcsrStruct extends Bundle { 650c84054caSLinJiawei val reserved = UInt((XLEN-3-5).W) 651c84054caSLinJiawei val frm = UInt(3.W) 652c84054caSLinJiawei val fflags = UInt(5.W) 653c84054caSLinJiawei assert(this.getWidth == XLEN) 654c84054caSLinJiawei } 655c84054caSLinJiawei val fcsr = RegInit(0.U(XLEN.W)) 656c84054caSLinJiawei // set mstatus->sd and mstatus->fs when true 657c84054caSLinJiawei val csrw_dirty_fp_state = WireInit(false.B) 658c84054caSLinJiawei 659c84054caSLinJiawei def frm_wfn(wdata: UInt): UInt = { 660c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 661c84054caSLinJiawei csrw_dirty_fp_state := true.B 662c84054caSLinJiawei fcsrOld.frm := wdata(2,0) 6635d669833SYinan Xu fcsrOld.asUInt 664c84054caSLinJiawei } 665c84054caSLinJiawei def frm_rfn(rdata: UInt): UInt = rdata(7,5) 666c84054caSLinJiawei 6677132faa5SLinJiawei def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 6687132faa5SLinJiawei val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 6697132faa5SLinJiawei val fcsrNew = WireInit(fcsrOld) 6707132faa5SLinJiawei if (update) { 6717132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 6727132faa5SLinJiawei } else { 6737132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) 6747132faa5SLinJiawei } 6755d669833SYinan Xu fcsrNew.asUInt 676c84054caSLinJiawei } 677c84054caSLinJiawei def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 678c84054caSLinJiawei 679c84054caSLinJiawei def fcsr_wfn(wdata: UInt): UInt = { 680c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 681c84054caSLinJiawei csrw_dirty_fp_state := true.B 682c84054caSLinJiawei Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 683c84054caSLinJiawei } 684c84054caSLinJiawei 685c84054caSLinJiawei val fcsrMapping = Map( 6867132faa5SLinJiawei MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 687c84054caSLinJiawei MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 688c84054caSLinJiawei MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 689c84054caSLinJiawei ) 690c84054caSLinJiawei 6910ba52110SZiyue Zhang // Vector extension CSRs 6927f733d3dSxiaofeibao-xjtu val vstart = RegInit(0.U(XLEN.W)) 6930ba52110SZiyue Zhang val vcsr = RegInit(0.U(XLEN.W)) 6940ba52110SZiyue Zhang val vl = Reg(UInt(XLEN.W)) 6950ba52110SZiyue Zhang val vtype = Reg(UInt(XLEN.W)) 696*5f28e666Schengguanghui val vlenb = RegInit(VDataBytes.U(XLEN.W)) 697daa01159SZiyue Zhang 698daa01159SZiyue Zhang // set mstatus->sd and mstatus->vs when true 699daa01159SZiyue Zhang val csrw_dirty_vs_state = WireInit(false.B) 7000ba52110SZiyue Zhang 7010ba52110SZiyue Zhang // vcsr is mapped to vxrm and vxsat 7020ba52110SZiyue Zhang class VcsrStruct extends Bundle { 7030ba52110SZiyue Zhang val reserved = UInt((XLEN-3).W) 7040ba52110SZiyue Zhang val vxrm = UInt(2.W) 7050ba52110SZiyue Zhang val vxsat = UInt(1.W) 7060ba52110SZiyue Zhang assert(this.getWidth == XLEN) 7070ba52110SZiyue Zhang } 7080ba52110SZiyue Zhang 7090ba52110SZiyue Zhang def vxrm_wfn(wdata: UInt): UInt = { 7100ba52110SZiyue Zhang val vcsrOld = WireInit(vcsr.asTypeOf(new VcsrStruct)) 711daa01159SZiyue Zhang csrw_dirty_vs_state := true.B 7120ba52110SZiyue Zhang vcsrOld.vxrm := wdata(1,0) 7130ba52110SZiyue Zhang vcsrOld.asUInt 7140ba52110SZiyue Zhang } 7150ba52110SZiyue Zhang def vxrm_rfn(rdata: UInt): UInt = rdata(2,1) 7160ba52110SZiyue Zhang 7176355a2b7Sczw def vxsat_wfn(update: Boolean)(wdata: UInt): UInt = { 7180ba52110SZiyue Zhang val vcsrOld = WireInit(vcsr.asTypeOf(new VcsrStruct)) 7196355a2b7Sczw val vcsrNew = WireInit(vcsrOld) 720daa01159SZiyue Zhang csrw_dirty_vs_state := true.B 7216355a2b7Sczw if (update) { 7226355a2b7Sczw vcsrNew.vxsat := wdata(0) | vcsrOld.vxsat 7236355a2b7Sczw } else { 7246355a2b7Sczw vcsrNew.vxsat := wdata(0) 7256355a2b7Sczw } 7266355a2b7Sczw vcsrNew.asUInt 7270ba52110SZiyue Zhang } 7280ba52110SZiyue Zhang def vxsat_rfn(rdata: UInt): UInt = rdata(0) 7290ba52110SZiyue Zhang 7300ba52110SZiyue Zhang def vcsr_wfn(wdata: UInt): UInt = { 7310ba52110SZiyue Zhang val vcsrOld = WireInit(vcsr.asTypeOf(new VcsrStruct)) 732daa01159SZiyue Zhang csrw_dirty_vs_state := true.B 7330ba52110SZiyue Zhang vcsrOld.vxrm := wdata.asTypeOf(vcsrOld).vxrm 7340ba52110SZiyue Zhang vcsrOld.vxsat := wdata.asTypeOf(vcsrOld).vxsat 7350ba52110SZiyue Zhang vcsrOld.asUInt 7360ba52110SZiyue Zhang } 7370ba52110SZiyue Zhang 7380ba52110SZiyue Zhang val vcsrMapping = Map( 7390ba52110SZiyue Zhang MaskedRegMap(Vstart, vstart), 7400ba52110SZiyue Zhang MaskedRegMap(Vxrm, vcsr, wfn = vxrm_wfn, rfn = vxrm_rfn), 7416355a2b7Sczw MaskedRegMap(Vxsat, vcsr, wfn = vxsat_wfn(false), rfn = vxsat_rfn), 7420ba52110SZiyue Zhang MaskedRegMap(Vcsr, vcsr, wfn = vcsr_wfn), 7430ba52110SZiyue Zhang MaskedRegMap(Vl, vl), 74435d1557aSZiyue Zhang MaskedRegMap(Vtype, vtype), 74535d1557aSZiyue Zhang MaskedRegMap(Vlenb, vlenb), 7460ba52110SZiyue Zhang ) 7470ba52110SZiyue Zhang 748321934c7SKunlin You // Hart Privilege Mode 749321934c7SKunlin You val privilegeMode = RegInit(UInt(2.W), ModeM) 750c84054caSLinJiawei 751cd365d4cSrvcoresjw //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool()))) 7528635f18fSwangkaifan // Perf Counter 7538635f18fSwangkaifan val nrPerfCnts = 29 // 3...31 754321934c7SKunlin You val privilegeModeOH = UIntToOH(privilegeMode) 755cd365d4cSrvcoresjw val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool()))) 7568635f18fSwangkaifan val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 7578c7b0b2fSrvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 75812c44ce5Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 75912c44ce5Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 76012c44ce5Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 761cd365d4cSrvcoresjw for (i <-0 until nrPerfCnts) { 762321934c7SKunlin You perfEventscounten(i) := (perfEvents(i)(63,60) & privilegeModeOH).orR 763cd365d4cSrvcoresjw } 764cd365d4cSrvcoresjw 7651ca0e4f3SYinan Xu val hpmEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 766cd365d4cSrvcoresjw for (i <- 0 until numPCntHc * coreParams.L2NBanks) { 7671ca0e4f3SYinan Xu hpmEvents(i) := csrio.perf.perfEventsHc(i) 768cd365d4cSrvcoresjw } 769cd365d4cSrvcoresjw 7709a128342SHaoyuan Feng // print perfEvents 7719a128342SHaoyuan Feng val allPerfEvents = hpmEvents.map(x => (s"Hc", x.value)) 7729a128342SHaoyuan Feng if (printEventCoding) { 7739a128342SHaoyuan Feng for (((name, inc), i) <- allPerfEvents.zipWithIndex) { 7749a128342SHaoyuan Feng println("CSR perfEvents Set", name, inc, i) 7759a128342SHaoyuan Feng } 7769a128342SHaoyuan Feng } 7779a128342SHaoyuan Feng 77812c44ce5Srvcoresjw val csrevents = perfEvents.slice(24, 29) 7791ca0e4f3SYinan Xu val hpm_hc = HPerfMonitor(csrevents, hpmEvents) 7808635f18fSwangkaifan val mcountinhibit = RegInit(0.U(XLEN.W)) 781b03ddc86Swangkaifan val mcycle = RegInit(0.U(XLEN.W)) 782b03ddc86Swangkaifan mcycle := mcycle + 1.U 783b03ddc86Swangkaifan val minstret = RegInit(0.U(XLEN.W)) 7841ca0e4f3SYinan Xu val perf_events = csrio.perf.perfEventsFrontend ++ 7851ca0e4f3SYinan Xu csrio.perf.perfEventsCtrl ++ 7861ca0e4f3SYinan Xu csrio.perf.perfEventsLsu ++ 7871ca0e4f3SYinan Xu hpm_hc.getPerf 788b03ddc86Swangkaifan minstret := minstret + RegNext(csrio.perf.retiredInstr) 7895fd90906Srvcoresjw for(i <- 0 until 29){ 7901ca0e4f3SYinan Xu perfCnts(i) := Mux(mcountinhibit(i+3) | !perfEventscounten(i), perfCnts(i), perfCnts(i) + perf_events(i).value) 7915fd90906Srvcoresjw } 7928635f18fSwangkaifan 793c84054caSLinJiawei // CSR reg map 79421fa8708Swangkaifan val basicPrivMapping = Map( 795c84054caSLinJiawei 796f7af4c74Schengguanghui // Unprivileged Floating-Point CSRs 797f7af4c74Schengguanghui // Has been mapped above 798c84054caSLinJiawei 799e4b1ccacSxuzefan // TODO: support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 800f7af4c74Schengguanghui // Unprivileged Counter/Timers 801f7af4c74Schengguanghui MaskedRegMap(Cycle, mcycle), 802f7af4c74Schengguanghui // We don't support read time CSR. 803f7af4c74Schengguanghui // MaskedRegMap(Time, mtime), 804f7af4c74Schengguanghui MaskedRegMap(Instret, minstret), 805c84054caSLinJiawei 80621fa8708Swangkaifan //--- Supervisor Trap Setup --- 807c84054caSLinJiawei MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 808c84054caSLinJiawei // MaskedRegMap(Sedeleg, Sedeleg), 809c84054caSLinJiawei // MaskedRegMap(Sideleg, Sideleg), 810c84054caSLinJiawei MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 811a4e57ea3SLi Qianruo MaskedRegMap(Stvec, stvec, stvecMask, MaskedRegMap.NoSideEffect, stvecMask), 812e4b1ccacSxuzefan MaskedRegMap(Scounteren, scounteren, scounterenMask), 813c84054caSLinJiawei 8146ade72d9Sxuzefan //--- Supervisor Configuration --- 8156ade72d9Sxuzefan MaskedRegMap(Senvcfg, senvcfg), 8166ade72d9Sxuzefan 81721fa8708Swangkaifan //--- Supervisor Trap Handling --- 818c84054caSLinJiawei MaskedRegMap(Sscratch, sscratch), 819e30fd06aSYinan Xu MaskedRegMap(Sepc, sepc, sepcMask, MaskedRegMap.NoSideEffect, sepcMask), 820c84054caSLinJiawei MaskedRegMap(Scause, scause), 821c84054caSLinJiawei MaskedRegMap(Stval, stval), 8225390caa7Speixiaokun MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask, x => (mipWire.asUInt | x) & sipMask), 823c84054caSLinJiawei 82421fa8708Swangkaifan //--- Supervisor Protection and Translation --- 825c5334b11SZhangZifei MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 826c84054caSLinJiawei 82735a47a38SYinan Xu //--- Supervisor Custom Read/Write Registers 828eedc2e58SSteve Gou MaskedRegMap(Sbpctl, sbpctl), 82935a47a38SYinan Xu MaskedRegMap(Spfctl, spfctl), 830ecccf78fSJay MaskedRegMap(Sfetchctl, sfetchctl), 83135a47a38SYinan Xu MaskedRegMap(Sdsid, sdsid), 8322b8b2e7aSWilliam Wang MaskedRegMap(Slvpredctl, slvpredctl), 833f3f22d72SYinan Xu MaskedRegMap(Smblockctl, smblockctl), 834aac4464eSYinan Xu MaskedRegMap(Srnctl, srnctl), 83535a47a38SYinan Xu 83621fa8708Swangkaifan //--- Machine Information Registers --- 8375dabf2dfSYinan Xu MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8385dabf2dfSYinan Xu MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8395dabf2dfSYinan Xu MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8405dabf2dfSYinan Xu MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8417d9edc86SLemover MaskedRegMap(Mconfigptr, mconfigptr, 0.U(XLEN.W), MaskedRegMap.Unwritable), 842c84054caSLinJiawei 84306490c40Speixiaokun //--- Machine Configuration Registers --- 84406490c40Speixiaokun MaskedRegMap(Menvcfg, menvcfg), 84506490c40Speixiaokun 84621fa8708Swangkaifan //--- Machine Trap Setup --- 847443741b9SYinan Xu MaskedRegMap(Mstatus, mstatus, mstatusWMask, mstatusUpdateSideEffect), 8485e4ec482SWilliam Wang MaskedRegMap(Misa, misa, 0.U, MaskedRegMap.Unwritable), // now whole misa is unchangeable 849d0de7e4aSpeixiaokun MaskedRegMap(Medeleg, medeleg, medelegWMask), 850b436d3b6Speixiaokun MaskedRegMap(Mideleg, mideleg, midelegWMask), 851b436d3b6Speixiaokun MaskedRegMap(Mie, mie, mieWMask), 852a4e57ea3SLi Qianruo MaskedRegMap(Mtvec, mtvec, mtvecMask, MaskedRegMap.NoSideEffect, mtvecMask), 853e4b1ccacSxuzefan MaskedRegMap(Mcounteren, mcounteren, mcounterenMask), 854c84054caSLinJiawei 85521fa8708Swangkaifan //--- Machine Trap Handling --- 856c84054caSLinJiawei MaskedRegMap(Mscratch, mscratch), 857e30fd06aSYinan Xu MaskedRegMap(Mepc, mepc, mepcMask, MaskedRegMap.NoSideEffect, mepcMask), 858c84054caSLinJiawei MaskedRegMap(Mcause, mcause), 859c84054caSLinJiawei MaskedRegMap(Mtval, mtval), 8605390caa7Speixiaokun MaskedRegMap(Mip, mipReg.asUInt, mipWMask, MaskedRegMap.NoSideEffect, mipMask, x => (mipWire.asUInt | x) & mipMask), 8616ade72d9Sxuzefan 86272951335SLi Qianruo //--- Trigger --- 863716f717fSLi Qianruo MaskedRegMap(Tselect, tselectPhy, WritableMask, WriteTselect), 864f7af4c74Schengguanghui // Todo: support chain length = 2 865f7af4c74Schengguanghui MaskedRegMap(Tdata1, tdata1RegVec(tselectPhy), 866f7af4c74Schengguanghui WritableMask, 867f7af4c74Schengguanghui x => Tdata1Bundle.Write(x, tdata1RegVec(tselectPhy), newTriggerChainIsLegal, debug_mode = debugMode), 868f7af4c74Schengguanghui WritableMask, 869f7af4c74Schengguanghui x => Tdata1Bundle.Read(x)), 870f7af4c74Schengguanghui MaskedRegMap(Tdata2, tdata2RegVec(tselectPhy)), 871716f717fSLi Qianruo MaskedRegMap(Tinfo, tinfo, 0.U(XLEN.W), MaskedRegMap.Unwritable), 87272951335SLi Qianruo 873d4aca96cSlqre //--- Debug Mode --- 874d4aca96cSlqre MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect), 875d4aca96cSlqre MaskedRegMap(Dpc, dpc), 876f7af4c74Schengguanghui MaskedRegMap(Dscratch0, dscratch0), 87712c44ce5Srvcoresjw MaskedRegMap(Dscratch1, dscratch1), 878b03ddc86Swangkaifan MaskedRegMap(Mcountinhibit, mcountinhibit), 879b03ddc86Swangkaifan MaskedRegMap(Mcycle, mcycle), 880b03ddc86Swangkaifan MaskedRegMap(Minstret, minstret), 881b03ddc86Swangkaifan ) 88212c44ce5Srvcoresjw 883d0de7e4aSpeixiaokun // hypervisor csr map 884d0de7e4aSpeixiaokun val hcsrMapping = Map( 885d0de7e4aSpeixiaokun //--- Hypervisor Trap Setup --- 886d0de7e4aSpeixiaokun MaskedRegMap(Hstatus, hstatus, hstatusWMask), 887d0de7e4aSpeixiaokun MaskedRegMap(Hedeleg, hedeleg), 888d0de7e4aSpeixiaokun MaskedRegMap(Hideleg, hideleg, hidelegWMask, MaskedRegMap.NoSideEffect, hidelegRMask), 889d0de7e4aSpeixiaokun MaskedRegMap(Hie, mie, hieMask, MaskedRegMap.NoSideEffect, hieMask), 890cc063a70Speixiaokun MaskedRegMap(Hcounteren, hcounteren, hcounterenMask), 891d0de7e4aSpeixiaokun MaskedRegMap(Hgeie, hgeie), 892d0de7e4aSpeixiaokun 893d0de7e4aSpeixiaokun //--- Hypervisor Trap Handling --- 894d0de7e4aSpeixiaokun MaskedRegMap(Htval, htval), 8955390caa7Speixiaokun MaskedRegMap(Hip, mipReg.asUInt, hipWMask, MaskedRegMap.NoSideEffect, hipRMask, x => (mipWire.asUInt | x) & hipRMask), 8965390caa7Speixiaokun MaskedRegMap(Hvip, mipReg.asUInt, hvipMask, MaskedRegMap.NoSideEffect, hvipMask, x => (mipWire.asUInt | x) & hvipMask), 897d0de7e4aSpeixiaokun MaskedRegMap(Htinst, htinst), 898d0de7e4aSpeixiaokun MaskedRegMap(Hgeip, hgeip), 899d0de7e4aSpeixiaokun 900d0de7e4aSpeixiaokun //--- Hypervisor Configuration --- 901d0de7e4aSpeixiaokun MaskedRegMap(Henvcfg, henvcfg), 902d0de7e4aSpeixiaokun 903d0de7e4aSpeixiaokun //--- Hypervisor Protection and Translation --- 904a1d4b4bfSpeixiaokun MaskedRegMap(Hgatp, hgatp, hgatpMask, MaskedRegMap.NoSideEffect, hgatpMask), 905d0de7e4aSpeixiaokun 906d0de7e4aSpeixiaokun //--- Hypervisor Counter/Timer Virtualization Registers --- 907d0de7e4aSpeixiaokun MaskedRegMap(Htimedelta, htimedelta), 908d0de7e4aSpeixiaokun 909d0de7e4aSpeixiaokun //--- Virtual Supervisor Registers --- 91085052be5Speixiaokun MaskedRegMap(Vsstatus, vsstatus, rmask = sstatusRmask, wmask = sstatusWmask, wfn = vsstatusUpdateSideEffect), 911d0de7e4aSpeixiaokun MaskedRegMap(Vsie, mie, rmask = vsip_ie_Mask, wmask = vsip_ie_Mask), 912d0de7e4aSpeixiaokun MaskedRegMap(Vstvec, vstvec), 913d0de7e4aSpeixiaokun MaskedRegMap(Vsscratch, vsscratch), 914d0de7e4aSpeixiaokun MaskedRegMap(Vsepc, vsepc), 915d0de7e4aSpeixiaokun MaskedRegMap(Vscause, vscause), 916d0de7e4aSpeixiaokun MaskedRegMap(Vstval, vstval), 917d7e392d1Sxuzefan MaskedRegMap(Vsip, mipReg.asUInt, vsip_WMask, MaskedRegMap.NoSideEffect, vsip_ie_Mask, x => mipWire.asUInt | x), 918d0de7e4aSpeixiaokun MaskedRegMap(Vsatp, vsatp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 919d0de7e4aSpeixiaokun 920d0de7e4aSpeixiaokun //--- Machine Registers --- 921d0de7e4aSpeixiaokun MaskedRegMap(Mtval2, mtval2), 922d0de7e4aSpeixiaokun MaskedRegMap(Mtinst, mtinst), 923d0de7e4aSpeixiaokun ) 924d0de7e4aSpeixiaokun 92512c44ce5Srvcoresjw val perfCntMapping = (0 until 29).map(i => {Map( 92612c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmevent3 +i, 92712c44ce5Srvcoresjw reg = perfEvents(i), 92812c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)), 92912c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmcounter3 +i, 930f7af4c74Schengguanghui reg = perfCnts(i)), 931f7af4c74Schengguanghui MaskedRegMap(addr = Hpmcounter3 + i, 93212c44ce5Srvcoresjw reg = perfCnts(i)) 93312c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 9346d96ebcdSwakafa // TODO: mechanism should be implemented later 9356d96ebcdSwakafa // val MhpmcounterStart = Mhpmcounter3 9366d96ebcdSwakafa // val MhpmeventStart = Mhpmevent3 9376d96ebcdSwakafa // for (i <- 0 until nrPerfCnts) { 9386d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 9396d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 9406d96ebcdSwakafa // } 9418635f18fSwangkaifan 942e19f7967SWilliam Wang val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 943e19f7967SWilliam Wang name -> RegInit(0.U(attribute("width").toInt.W)) 944e19f7967SWilliam Wang }} 945ad3ba452Szhanglinjuan val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 946ad3ba452Szhanglinjuan MaskedRegMap( 947ad3ba452Szhanglinjuan Scachebase + attribute("offset").toInt, 948e19f7967SWilliam Wang cacheopRegs(name) 949ad3ba452Szhanglinjuan ) 950ad3ba452Szhanglinjuan }} 951b6982e83SLemover 95221fa8708Swangkaifan val mapping = basicPrivMapping ++ 9538635f18fSwangkaifan perfCntMapping ++ 95421fa8708Swangkaifan pmpMapping ++ 955ca2f90a6SLemover pmaMapping ++ 956ad3ba452Szhanglinjuan (if (HasFPU) fcsrMapping else Nil) ++ 9570ba52110SZiyue Zhang (if (HasVPU) vcsrMapping else Nil) ++ 958d0de7e4aSpeixiaokun (if (HasCustomCSRCacheOp) cacheopMapping else Nil) ++ 959d0de7e4aSpeixiaokun (if (HasHExtension) hcsrMapping else Nil) 960c84054caSLinJiawei 961f7af4c74Schengguanghui 962f7af4c74Schengguanghui println("XiangShan CSR Lists") 963f7af4c74Schengguanghui 964f7af4c74Schengguanghui for (addr <- mapping.keys.toSeq.sorted) { 965f7af4c74Schengguanghui println(f"$addr%#03x ${mapping(addr)._1}") 966f7af4c74Schengguanghui } 967f7af4c74Schengguanghui 968d0de7e4aSpeixiaokun val vs_s_csr_map = Map( 969d0de7e4aSpeixiaokun Sstatus.U -> Vsstatus.U, 970d0de7e4aSpeixiaokun Sie.U -> Vsie.U, 971d0de7e4aSpeixiaokun Stvec.U -> Vstvec.U, 972d0de7e4aSpeixiaokun Sscratch.U -> Vsscratch.U, 973d0de7e4aSpeixiaokun Sepc.U -> Vsepc.U, 974d0de7e4aSpeixiaokun Scause.U -> Vscause.U, 975d0de7e4aSpeixiaokun Stval.U -> Vstval.U, 976d0de7e4aSpeixiaokun Sip.U -> Vsip.U, 977d0de7e4aSpeixiaokun Satp.U -> Vsatp.U 978d0de7e4aSpeixiaokun ) 979d0de7e4aSpeixiaokun val addr = Wire(UInt(12.W)) 980d0de7e4aSpeixiaokun val vscsr_addr = LookupTreeDefault(src2(11, 0), src2(11, 0), vs_s_csr_map) 981d0de7e4aSpeixiaokun when(virtMode){ 982d0de7e4aSpeixiaokun addr := vscsr_addr 983d0de7e4aSpeixiaokun }.otherwise{ 984d0de7e4aSpeixiaokun addr := src2(11, 0) 985d0de7e4aSpeixiaokun } 986b1860798SZhangfw val csri = ZeroExt(src2(16, 12), XLEN) 987c84054caSLinJiawei val rdata = Wire(UInt(XLEN.W)) 988d0de7e4aSpeixiaokun val rdata_tmp = Wire(UInt(XLEN.W)) 989d0de7e4aSpeixiaokun val wdata_tmp = LookupTree(func, List( 990c84054caSLinJiawei CSROpType.wrt -> src1, 991c84054caSLinJiawei CSROpType.set -> (rdata | src1), 9925d669833SYinan Xu CSROpType.clr -> (rdata & (~src1).asUInt), 993b0ae3ac4SLinJiawei CSROpType.wrti -> csri, 994c84054caSLinJiawei CSROpType.seti -> (rdata | csri), 9955d669833SYinan Xu CSROpType.clri -> (rdata & (~csri).asUInt) 996c84054caSLinJiawei )) 997d0de7e4aSpeixiaokun val is_vsip_ie = addr === Vsip.U || addr === Vsie.U 998a1d4b4bfSpeixiaokun // for the difftest with NEMU(stay consistent with Spike) 999a1d4b4bfSpeixiaokun val is_satp = addr === Satp.U 1000a1d4b4bfSpeixiaokun val is_vsatp = addr === Vsatp.U 1001a1d4b4bfSpeixiaokun val is_hgatp = addr === Hgatp.U 1002a1d4b4bfSpeixiaokun val check_apt_mode = wdata_tmp(wdata_tmp.getWidth-1, 64-Satp_Mode_len) === 8.U || wdata_tmp(wdata_tmp.getWidth-1, 64-Satp_Mode_len) === 0.U 1003a1d4b4bfSpeixiaokun val wdata = MuxCase(wdata_tmp, Seq( 1004a1d4b4bfSpeixiaokun is_vsip_ie -> ZeroExt(wdata_tmp << 1, XLEN), 1005a1d4b4bfSpeixiaokun (is_satp && !check_apt_mode) -> satp, 1006a1d4b4bfSpeixiaokun (is_vsatp && !check_apt_mode) -> vsatp, 1007a1d4b4bfSpeixiaokun (is_hgatp && !check_apt_mode) -> hgatp 1008a1d4b4bfSpeixiaokun )) 1009e377d77eSWilliam Wang val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) || 10104d5d2702Swakafa (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U) || 1011f7af4c74Schengguanghui (addr >= Cycle.U) && (addr <= Hpmcounter31.U) || 10124d5d2702Swakafa addr === Mip.U 1013e377d77eSWilliam Wang csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp 10148635f18fSwangkaifan 101547a386bfSZhangZifei // satp wen check 101647a386bfSZhangZifei val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 10172f5f05fdSWilliam Wang 1018e5adbe81SLemover // csr access check, special case 1019d0de7e4aSpeixiaokun val tvmNotPermit = (privilegeMode === ModeS && !virtMode && mstatusStruct.tvm.asBool) 1020e5adbe81SLemover val accessPermitted = !(addr === Satp.U && tvmNotPermit) 1021d0de7e4aSpeixiaokun val vtvmNotPermit = (privilegeMode === ModeS && virtMode && hstatusStruct.vtvm.asBool) 1022d0de7e4aSpeixiaokun val vaccessPermitted = !(addr === Vsatp.U && vtvmNotPermit) 1023d0de7e4aSpeixiaokun csrio.disableSfence := (tvmNotPermit || !virtMode && privilegeMode < ModeS) || (vtvmNotPermit || virtMode && privilegeMode < ModeS) 1024d0de7e4aSpeixiaokun csrio.disableHfenceg := !((!virtMode && privilegeMode === ModeS && !mstatusStruct.tvm.asBool) || (privilegeMode === ModeM)) // only valid in HS and mstatus.tvm == 0 or in M 1025d0de7e4aSpeixiaokun csrio.disableHfencev := !(privilegeMode === ModeM || (!virtMode && privilegeMode === ModeS)) 1026e5adbe81SLemover 10272f5f05fdSWilliam Wang // general CSR wen check 1028d0de7e4aSpeixiaokun val wen = valid && CSROpType.needAccess(func) && ((addr=/=Satp.U && addr =/= Vsatp.U) || satpLegalMode) 102972951335SLi Qianruo val dcsrPermitted = dcsrPermissionCheck(addr, false.B, debugMode) 103072951335SLi Qianruo val triggerPermitted = triggerPermissionCheck(addr, true.B, debugMode) // todo dmode 10310214776eSpeixiaokun val HasH = (HasHExtension == true).asBool 1032d0de7e4aSpeixiaokun val csrAccess = csrAccessPermissionCheck(addr, false.B, privilegeMode, virtMode, HasH) 1033d0de7e4aSpeixiaokun val modePermitted = csrAccess === 0.U && dcsrPermitted && triggerPermitted 1034321934c7SKunlin You val perfcntPermitted = perfcntPermissionCheck(addr, privilegeMode, mcounteren, scounteren) 1035d0de7e4aSpeixiaokun val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && Mux(virtMode, vaccessPermitted, accessPermitted) 1036d0de7e4aSpeixiaokun MaskedRegMap.generate(mapping, addr, rdata_tmp, wen && permitted, wdata) 1037d0de7e4aSpeixiaokun rdata := Mux(is_vsip_ie, ZeroExt(rdata_tmp >> 1, XLEN), rdata_tmp) 10386a35d972SXuan Hu io.out.bits.res.data := rdata 10396a35d972SXuan Hu io.out.bits.ctrl.flushPipe.get := flushPipe 1040c1e19666Sxiaofeibao-xjtu connect0LatencyCtrlSingal 1041c84054caSLinJiawei 1042b6982e83SLemover // send distribute csr a w signal 1043b6982e83SLemover csrio.customCtrl.distribute_csr.w.valid := wen && permitted 1044b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.data := wdata 1045b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.addr := addr 1046b6982e83SLemover 1047a4e57ea3SLi Qianruo when (RegNext(csrio.fpu.fflags.valid)) { 1048577fcf2aSZhaoyang You fcsr := fflags_wfn(update = true)(RegEnable(csrio.fpu.fflags.bits, csrio.fpu.fflags.valid)) 1049c84054caSLinJiawei } 10506355a2b7Sczw when(RegNext(csrio.vpu.set_vxsat.valid)) { 1051c84054caSLinJiawei fcsr := fflags_wfn(update = true)(RegNext(csrio.fpu.fflags.bits)) 10526355a2b7Sczw } 1053c84054caSLinJiawei // set fs and sd in mstatus 1054a4e57ea3SLi Qianruo when (csrw_dirty_fp_state || RegNext(csrio.fpu.dirty_fs)) { 1055c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1056c84054caSLinJiawei mstatusNew.fs := "b11".U 1057c84054caSLinJiawei mstatusNew.sd := true.B 10585d669833SYinan Xu mstatus := mstatusNew.asUInt 1059cf025d06Speixiaokun when(virtMode){ 1060cf025d06Speixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1061cf025d06Speixiaokun vsstatusNew.fs := "b11".U 1062cf025d06Speixiaokun vsstatusNew.sd := true.B 1063cf025d06Speixiaokun vsstatus := vsstatusNew.asUInt 1064c84054caSLinJiawei } 1065c84054caSLinJiawei } 1066c84054caSLinJiawei csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 1067c84054caSLinJiawei 106835d1557aSZiyue Zhang when (RegNext(csrio.vpu.set_vstart.valid)) { 1069577fcf2aSZhaoyang You vstart := RegEnable(csrio.vpu.set_vstart.bits, csrio.vpu.set_vstart.valid) 1070daa01159SZiyue Zhang } 107135d1557aSZiyue Zhang when (RegNext(csrio.vpu.set_vtype.valid)) { 1072577fcf2aSZhaoyang You vtype := RegEnable(csrio.vpu.set_vtype.bits, csrio.vpu.set_vtype.valid) 1073daa01159SZiyue Zhang } 1074daa01159SZiyue Zhang when (RegNext(csrio.vpu.set_vl.valid)) { 1075c04d0602SZiyue Zhang vl := RegEnable(csrio.vpu.set_vl.bits, csrio.vpu.set_vl.valid) 1076daa01159SZiyue Zhang } 1077daa01159SZiyue Zhang // set vs and sd in mstatus 107862a2cb19SXuan Hu when(csrw_dirty_vs_state || RegNext(csrio.vpu.dirty_vs)) { 107962a2cb19SXuan Hu val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 108062a2cb19SXuan Hu mstatusNew.vs := ContextStatus.dirty 108162a2cb19SXuan Hu mstatusNew.sd := true.B 108262a2cb19SXuan Hu mstatus := mstatusNew.asUInt 108362a2cb19SXuan Hu } 1084daa01159SZiyue Zhang 1085daa01159SZiyue Zhang csrio.vpu.vstart := vstart 1086daa01159SZiyue Zhang csrio.vpu.vxrm := vcsr.asTypeOf(new VcsrStruct).vxrm 1087daa01159SZiyue Zhang csrio.vpu.vxsat := vcsr.asTypeOf(new VcsrStruct).vxsat 108835d1557aSZiyue Zhang csrio.vpu.vcsr := vcsr 108935d1557aSZiyue Zhang csrio.vpu.vtype := vtype 1090daa01159SZiyue Zhang csrio.vpu.vl := vl 1091daa01159SZiyue Zhang csrio.vpu.vlenb := vlenb 1092daa01159SZiyue Zhang csrio.vpu.vill := vtype.asTypeOf(new VtypeStruct).vill 1093daa01159SZiyue Zhang csrio.vpu.vma := vtype.asTypeOf(new VtypeStruct).vma 1094daa01159SZiyue Zhang csrio.vpu.vta := vtype.asTypeOf(new VtypeStruct).vta 1095daa01159SZiyue Zhang csrio.vpu.vsew := vtype.asTypeOf(new VtypeStruct).vsew 1096daa01159SZiyue Zhang csrio.vpu.vlmul := vtype.asTypeOf(new VtypeStruct).vlmul 109772951335SLi Qianruo 109872951335SLi Qianruo // Trigger Ctrl 1099f7af4c74Schengguanghui val triggerEnableVec = tdata1RegVec.map { tdata1 => 1100f7af4c74Schengguanghui val mcontrolData = tdata1.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData) 1101f7af4c74Schengguanghui tdata1.asTypeOf(new Tdata1Bundle).type_.asUInt === TrigTypeEnum.MCONTROL && ( 11020ffeff0dSXuan Hu mcontrolData.m && privilegeMode === ModeM || 11030ffeff0dSXuan Hu mcontrolData.s && privilegeMode === ModeS || 11040ffeff0dSXuan Hu mcontrolData.u && privilegeMode === ModeU) 110572951335SLi Qianruo } 1106f7af4c74Schengguanghui val fetchTriggerEnableVec = triggerEnableVec.zip(tdata1WireVec).map { 1107f7af4c74Schengguanghui case (tEnable, tdata1) => tEnable && tdata1.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isFetchTrigger 1108f7af4c74Schengguanghui } 1109f7af4c74Schengguanghui val memAccTriggerEnableVec = triggerEnableVec.zip(tdata1WireVec).map { 1110f7af4c74Schengguanghui case (tEnable, tdata1) => tEnable && tdata1.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isMemAccTrigger 1111f7af4c74Schengguanghui } 1112f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tEnableVec := fetchTriggerEnableVec 1113f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tEnableVec := memAccTriggerEnableVec 1114f7af4c74Schengguanghui 1115f7af4c74Schengguanghui val tdata1Update = wen && (addr === Tdata1.U) 1116f7af4c74Schengguanghui val tdata2Update = wen && (addr === Tdata2.U) 1117f7af4c74Schengguanghui val triggerUpdate = wen && (addr === Tdata1.U || addr === Tdata2.U) 1118f7af4c74Schengguanghui val frontendTriggerUpdate = 1119f7af4c74Schengguanghui tdata1Update && wdata.asTypeOf(new Tdata1Bundle).type_.asUInt === TrigTypeEnum.MCONTROL && 1120f7af4c74Schengguanghui wdata.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isFetchTrigger || 1121f7af4c74Schengguanghui tdata1Selected.data.asTypeOf(new MControlData).isFetchTrigger && triggerUpdate 1122f7af4c74Schengguanghui val memTriggerUpdate = 1123f7af4c74Schengguanghui tdata1Update && wdata.asTypeOf(new Tdata1Bundle).type_.asUInt === TrigTypeEnum.MCONTROL && 1124f7af4c74Schengguanghui wdata.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isMemAccTrigger || 1125f7af4c74Schengguanghui tdata1Selected.data.asTypeOf(new MControlData).isMemAccTrigger && triggerUpdate 1126f7af4c74Schengguanghui 1127f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tUpdate.valid := RegNext(RegNext(frontendTriggerUpdate)) 1128f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tUpdate.valid := RegNext(RegNext(memTriggerUpdate)) 1129f7af4c74Schengguanghui XSDebug(triggerEnableVec.reduce(_ || _), p"Debug Mode: At least 1 trigger is enabled," + 1130f7af4c74Schengguanghui p"trigger enable is ${Binary(triggerEnableVec.asUInt)}\n") 113172951335SLi Qianruo 1132c84054caSLinJiawei // CSR inst decode 1133c84054caSLinJiawei val isEbreak = addr === privEbreak && func === CSROpType.jmp 1134c84054caSLinJiawei val isEcall = addr === privEcall && func === CSROpType.jmp 1135c84054caSLinJiawei val isMret = addr === privMret && func === CSROpType.jmp 1136c84054caSLinJiawei val isSret = addr === privSret && func === CSROpType.jmp 1137c84054caSLinJiawei val isUret = addr === privUret && func === CSROpType.jmp 1138d4aca96cSlqre val isDret = addr === privDret && func === CSROpType.jmp 11395d669833SYinan Xu val isWFI = func === CSROpType.wfi 1140c84054caSLinJiawei 1141321934c7SKunlin You // Illegal privileged operation list 1142321934c7SKunlin You val illegalMret = valid && isMret && privilegeMode < ModeM 1143321934c7SKunlin You val illegalSret = valid && isSret && privilegeMode < ModeS 1144d0de7e4aSpeixiaokun val illegalSModeSret = valid && isSret && privilegeMode === ModeS && virtMode === false.B && mstatusStruct.tsr.asBool 1145d0de7e4aSpeixiaokun // when hstatus.vtsr == 1, if sret is executed in VS-mode, it will cause virtual instruction 1146d0de7e4aSpeixiaokun val illegalVSModeSret = valid && isSret && privilegeMode === ModeS && virtMode && hstatusStruct.vtsr.asBool 11475d669833SYinan Xu // When TW=1, then if WFI is executed in any less-privileged mode, 11485d669833SYinan Xu // and it does not complete within an implementation-specific, bounded time limit, 11495d669833SYinan Xu // the WFI instruction causes an illegal instruction exception. 11505d669833SYinan Xu // The time limit may always be 0, in which case WFI always causes 11515d669833SYinan Xu // an illegal instruction exception in less-privileged modes when TW=1. 1152d0de7e4aSpeixiaokun val illegalWFI = valid && isWFI && (privilegeMode < ModeM && mstatusStruct.tw === 1.U || privilegeMode === ModeU && !virtMode) 1153d0de7e4aSpeixiaokun val illegalVWFI = valid && isWFI && ((virtMode && privilegeMode === ModeS && hstatusStruct.vtw === 1.U && mstatusStruct.tw === 0.U)|| 1154d0de7e4aSpeixiaokun (virtMode && privilegeMode === ModeU && mstatusStruct.tw === 0.U)) 1155321934c7SKunlin You // Illegal privileged instruction check 11565d669833SYinan Xu val isIllegalAddr = valid && CSROpType.needAccess(func) && MaskedRegMap.isIllegalAddr(mapping, addr) 1157d0de7e4aSpeixiaokun val isIllegalAccess = !virtMode && wen && !(Mux(addrInPerfCnt, perfcntPermitted, csrAccess === 0.U && dcsrPermitted && triggerPermitted) && accessPermitted) 11585d669833SYinan Xu val isIllegalPrivOp = illegalMret || illegalSret || illegalSModeSret || illegalWFI 1159c84054caSLinJiawei 1160d0de7e4aSpeixiaokun val isIllegalVAccess = virtMode && wen && (csrAccess === 2.U || !vaccessPermitted) 1161d0de7e4aSpeixiaokun val isIllegalVPrivOp = illegalVSModeSret || illegalVWFI 1162ad3ba452Szhanglinjuan // expose several csr bits for tlb 1163fcff7e94SZhangZifei tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 1164fcff7e94SZhangZifei tlbBundle.priv.sum := mstatusStruct.sum.asBool 1165d0de7e4aSpeixiaokun tlbBundle.priv.vmxr := vsstatusStruct.mxr.asBool 1166d0de7e4aSpeixiaokun tlbBundle.priv.vsum := vsstatusStruct.sum.asBool 1167d0de7e4aSpeixiaokun tlbBundle.priv.spvp := hstatusStruct.spvp 1168d0de7e4aSpeixiaokun tlbBundle.priv.virt := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpv & (mstatusStruct.mpp =/= ModeM), virtMode) 1169321934c7SKunlin You tlbBundle.priv.imode := privilegeMode 11700ffeff0dSXuan Hu tlbBundle.priv.dmode := Mux((debugMode && dcsr.asTypeOf(new DcsrStruct).mprven || !debugMode) && mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode) 1171c84054caSLinJiawei 1172e9341afdSYinan Xu // Branch control 1173f7af4c74Schengguanghui val retTarget = WireInit(0.U) 117482e4705bSpeixiaokun val resetSatp = (addr === Satp.U || addr === Hgatp.U || addr === Vsatp.U) && wen // write to satp will cause the pipeline be flushed 1175c84054caSLinJiawei 1176f7af4c74Schengguanghui val w_fcsr_change_rm = wen && addr === Fcsr.U && wdata(7, 5) =/= fcsr(7, 5) 1177f7af4c74Schengguanghui val w_frm_change_rm = wen && addr === Frm.U && wdata(2, 0) =/= fcsr(7, 5) 1178f7af4c74Schengguanghui val frm_change = w_fcsr_change_rm || w_frm_change_rm 1179f7af4c74Schengguanghui val isXRet = valid && func === CSROpType.jmp && !isEcall && !isEbreak 1180f7af4c74Schengguanghui flushPipe := resetSatp || frm_change || isXRet || frontendTriggerUpdate 1181c84054caSLinJiawei 1182f7af4c74Schengguanghui private val illegalRetTarget = WireInit(false.B) 1183f7af4c74Schengguanghui when(valid) { 1184f7af4c74Schengguanghui when(isDret) { 1185d4aca96cSlqre retTarget := dpc(VAddrBits - 1, 0) 1186f7af4c74Schengguanghui }.elsewhen(isMret && !illegalMret) { 1187f7af4c74Schengguanghui retTarget := mepc(VAddrBits - 1, 0) 1188d0de7e4aSpeixiaokun }.elsewhen(isSret && !illegalSret && !illegalSModeSret && !illegalVSModeSret) { 1189d0de7e4aSpeixiaokun retTarget := Mux(virtMode, vsepc(VAddrBits - 1, 0), sepc(VAddrBits - 1, 0)) 1190f7af4c74Schengguanghui }.elsewhen(isUret) { 1191f7af4c74Schengguanghui retTarget := uepc(VAddrBits - 1, 0) 1192f7af4c74Schengguanghui }.otherwise { 1193f7af4c74Schengguanghui illegalRetTarget := true.B 1194f7af4c74Schengguanghui } 1195f7af4c74Schengguanghui }.otherwise { 1196f7af4c74Schengguanghui illegalRetTarget := true.B // when illegalRetTarget setted, retTarget should never be used 1197f7af4c74Schengguanghui } 1198f7af4c74Schengguanghui 1199f7af4c74Schengguanghui // Mux tree for regs 1200f7af4c74Schengguanghui when(valid) { 1201f7af4c74Schengguanghui when(isDret) { 1202f7af4c74Schengguanghui val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1203f7af4c74Schengguanghui val debugModeNew = WireInit(debugMode) 1204f7af4c74Schengguanghui when(dcsr.asTypeOf(new DcsrStruct).prv =/= ModeM) { 1205f7af4c74Schengguanghui mstatusNew.mprv := 0.U 1206f7af4c74Schengguanghui } //If the new privilege mode is less privileged than M-mode, MPRV in mstatus is cleared. 1207f7af4c74Schengguanghui mstatus := mstatusNew.asUInt 12080ffeff0dSXuan Hu privilegeMode := dcsr.asTypeOf(new DcsrStruct).prv 1209d4aca96cSlqre debugModeNew := false.B 1210d4aca96cSlqre debugIntrEnable := true.B 1211d4aca96cSlqre debugMode := debugModeNew 1212d4aca96cSlqre XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 1213f7af4c74Schengguanghui }.elsewhen(isMret && !illegalMret) { 1214c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1215c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1216c84054caSLinJiawei mstatusNew.ie.m := mstatusOld.pie.m 1217321934c7SKunlin You privilegeMode := mstatusOld.mpp 1218d0de7e4aSpeixiaokun if (HasHExtension) { 1219d0de7e4aSpeixiaokun virtMode := mstatusOld.mpv 1220d0de7e4aSpeixiaokun mstatusNew.mpv := 0.U 1221d0de7e4aSpeixiaokun } 1222c84054caSLinJiawei mstatusNew.pie.m := true.B 1223c84054caSLinJiawei mstatusNew.mpp := ModeU 1224f7af4c74Schengguanghui when(mstatusOld.mpp =/= ModeM) { 1225f7af4c74Schengguanghui mstatusNew.mprv := 0.U 1226c84054caSLinJiawei } 1227f7af4c74Schengguanghui mstatus := mstatusNew.asUInt 122878233deeSXuan Hu }.elsewhen(isSret && !illegalSret && !illegalSModeSret && !illegalVSModeSret) { 1229c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1230c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1231d0de7e4aSpeixiaokun val hstatusOld = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1232d0de7e4aSpeixiaokun val hstatusNew = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1233d0de7e4aSpeixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1234d0de7e4aSpeixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1235d0de7e4aSpeixiaokun when(virtMode === 0.U) { 1236d0de7e4aSpeixiaokun virtMode := hstatusOld.spv 1237d0de7e4aSpeixiaokun hstatusNew.spv := 0.U 1238c84054caSLinJiawei mstatusNew.ie.s := mstatusOld.pie.s 1239321934c7SKunlin You privilegeMode := Cat(0.U(1.W), mstatusOld.spp) 1240c84054caSLinJiawei mstatusNew.pie.s := true.B 1241c84054caSLinJiawei mstatusNew.spp := ModeU 1242f7af4c74Schengguanghui when(mstatusOld.spp =/= ModeM) { 1243f7af4c74Schengguanghui mstatusNew.mprv := 0.U 1244c84054caSLinJiawei } 1245c84054caSLinJiawei mstatus := mstatusNew.asUInt 1246d0de7e4aSpeixiaokun hstatus := hstatusNew.asUInt 1247d0de7e4aSpeixiaokun }.otherwise { 1248d0de7e4aSpeixiaokun privilegeMode := vsstatusOld.spp 1249d0de7e4aSpeixiaokun vsstatusNew.spp := ModeU 1250d0de7e4aSpeixiaokun vsstatusNew.ie.s := vsstatusOld.pie.s 1251d0de7e4aSpeixiaokun vsstatusNew.pie.s := 1.U 1252d0de7e4aSpeixiaokun vsstatus := vsstatusNew.asUInt 1253d0de7e4aSpeixiaokun } 1254f7af4c74Schengguanghui }.elsewhen(isUret) { 1255c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1256c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1257c84054caSLinJiawei // mstatusNew.mpp.m := ModeU //TODO: add mode U 1258c84054caSLinJiawei mstatusNew.ie.u := mstatusOld.pie.u 1259321934c7SKunlin You privilegeMode := ModeU 1260c84054caSLinJiawei mstatusNew.pie.u := true.B 1261c84054caSLinJiawei mstatus := mstatusNew.asUInt 1262f7af4c74Schengguanghui } 1263c84054caSLinJiawei } 1264c84054caSLinJiawei 1265e9341afdSYinan Xu io.in.ready := true.B 1266e9341afdSYinan Xu io.out.valid := valid 1267e9341afdSYinan Xu 1268f7af4c74Schengguanghui // In this situation, hart will enter debug mode instead of handling a breakpoint exception simply. 1269f7af4c74Schengguanghui // Ebreak block instructions backwards, so it's ok to not keep extra info to distinguish between breakpoint 1270f7af4c74Schengguanghui // exception and enter-debug-mode exception. 1271f7af4c74Schengguanghui val ebreakEnterDebugMode = 12725b0f0029SXuan Hu (privilegeMode === ModeM && dcsrData.ebreakm) || 12735b0f0029SXuan Hu (privilegeMode === ModeS && dcsrData.ebreaks) || 12745b0f0029SXuan Hu (privilegeMode === ModeU && dcsrData.ebreaku) 1275f7af4c74Schengguanghui 1276f7af4c74Schengguanghui // raise a debug exception waiting to enter debug mode, instead of a breakpoint exception 1277f7af4c74Schengguanghui val raiseDebugException = !debugMode && isEbreak && ebreakEnterDebugMode 1278d4aca96cSlqre 12793b739f49SXuan Hu val csrExceptionVec = WireInit(0.U.asTypeOf(ExceptionVec())) 1280f7af4c74Schengguanghui csrExceptionVec(breakPoint) := io.in.valid && isEbreak 1281321934c7SKunlin You csrExceptionVec(ecallM) := privilegeMode === ModeM && io.in.valid && isEcall 1282d0de7e4aSpeixiaokun csrExceptionVec(ecallVS) := privilegeMode === ModeS && virtMode && io.in.valid && isEcall 1283d0de7e4aSpeixiaokun csrExceptionVec(ecallS) := privilegeMode === ModeS && !virtMode && io.in.valid && isEcall 1284321934c7SKunlin You csrExceptionVec(ecallU) := privilegeMode === ModeU && io.in.valid && isEcall 1285baf8def6SYinan Xu // Trigger an illegal instr exception when: 1286baf8def6SYinan Xu // * unimplemented csr is being read/written 1287baf8def6SYinan Xu // * csr access is illegal 12885d669833SYinan Xu csrExceptionVec(illegalInstr) := isIllegalAddr || isIllegalAccess || isIllegalPrivOp 1289d0de7e4aSpeixiaokun csrExceptionVec(virtualInstr) := isIllegalVAccess || isIllegalVPrivOp 12906a35d972SXuan Hu io.out.bits.ctrl.exceptionVec.get := csrExceptionVec 1291baf8def6SYinan Xu 1292f7af4c74Schengguanghui XSDebug(io.in.valid, s"Debug Mode: an Ebreak is executed, ebreak cause enter-debug-mode exception ? ${raiseDebugException}\n") 129384e47f35SLi Qianruo 1294e9341afdSYinan Xu /** 1295e9341afdSYinan Xu * Exception and Intr 1296e9341afdSYinan Xu */ 1297d0de7e4aSpeixiaokun val idelegS = (mideleg & mip.asUInt) 1298d0de7e4aSpeixiaokun val idelegVS = (hideleg & mideleg & mip.asUInt) 1299d0de7e4aSpeixiaokun def privilegedEnableDetect(idelegS: Bool, idelegVS: Bool): Bool = Mux(idelegS, 1300d0de7e4aSpeixiaokun Mux(idelegVS, (virtMode && privilegeMode === ModeS && vsstatusStruct.ie.s) || (virtMode && privilegeMode < ModeS), 1301d0de7e4aSpeixiaokun ((privilegeMode === ModeS) && mstatusStruct.ie.s) || (privilegeMode < ModeS) || virtMode), 1302321934c7SKunlin You ((privilegeMode === ModeM) && mstatusStruct.ie.m) || (privilegeMode < ModeM)) 1303e9341afdSYinan Xu 1304d4aca96cSlqre val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 1305d4aca96cSlqre XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 13069aca92b9SYinan Xu // send interrupt information to ROB 1307d0de7e4aSpeixiaokun val intrVecEnable = Wire(Vec(13, Bool())) 1308052ee9a1SLi Qianruo val disableInterrupt = debugMode || (dcsrData.step && !dcsrData.stepie) 1309d0de7e4aSpeixiaokun intrVecEnable.zip(idelegS.asBools).zip(idelegVS.asBools).map{case((x,y),z) => x := privilegedEnableDetect(y, z) && !disableInterrupt} 1310d7dd1af1SLi Qianruo val intrVec = Cat(debugIntr && !debugMode, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 13115d669833SYinan Xu val intrBitSet = intrVec.orR 1312e9341afdSYinan Xu csrio.interrupt := intrBitSet 13135c95ea2eSYinan Xu // Page 45 in RISC-V Privileged Specification 13145c95ea2eSYinan Xu // The WFI instruction can also be executed when interrupts are disabled. The operation of WFI 13155c95ea2eSYinan Xu // must be unaffected by the global interrupt bits in mstatus (MIE and SIE) and the delegation 13165c95ea2eSYinan Xu // register mideleg, but should honor the individual interrupt enables (e.g, MTIE). 13174ede3fe2SLi Qianruo csrio.wfi_event := debugIntr || (mie(11, 0) & mip.asUInt).orR 1318e9341afdSYinan Xu mipWire.t.m := csrio.externalInterrupt.mtip 1319e9341afdSYinan Xu mipWire.s.m := csrio.externalInterrupt.msip 1320e9341afdSYinan Xu mipWire.e.m := csrio.externalInterrupt.meip 1321b3d79b37SYinan Xu mipWire.e.s := csrio.externalInterrupt.seip 1322e9341afdSYinan Xu 1323e9341afdSYinan Xu // interrupts 1324e9341afdSYinan Xu val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 1325f7af4c74Schengguanghui val hasIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 1326a4e57ea3SLi Qianruo val ivmEnable = tlbBundle.priv.imode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 13273b739f49SXuan Hu val iexceptionPC = Mux(ivmEnable, SignExt(csrio.exception.bits.pc, XLEN), csrio.exception.bits.pc) 1328e25e4d90SXuan Hu val iexceptionGPAddr = Mux(ivmEnable, SignExt(csrio.exception.bits.gpaddr, XLEN), csrio.exception.bits.gpaddr) 1329a4e57ea3SLi Qianruo val dvmEnable = tlbBundle.priv.dmode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 13303b739f49SXuan Hu val dexceptionPC = Mux(dvmEnable, SignExt(csrio.exception.bits.pc, XLEN), csrio.exception.bits.pc) 1331f7af4c74Schengguanghui XSDebug(hasIntr, "interrupt: pc=0x%x, %d\n", dexceptionPC, intrNO) 1332f7af4c74Schengguanghui val hasDebugIntr = intrNO === IRQ_DEBUG.U && hasIntr 1333e9341afdSYinan Xu 1334f7af4c74Schengguanghui // exceptions from rob need to handle 1335f7af4c74Schengguanghui val exceptionVecFromRob = csrio.exception.bits.exceptionVec 1336f7af4c74Schengguanghui val hasException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 1337f7af4c74Schengguanghui val hasInstrPageFault = hasException && exceptionVecFromRob(instrPageFault) 1338f7af4c74Schengguanghui val hasLoadPageFault = hasException && exceptionVecFromRob(loadPageFault) 1339f7af4c74Schengguanghui val hasStorePageFault = hasException && exceptionVecFromRob(storePageFault) 1340f7af4c74Schengguanghui val hasStoreAddrMisalign = hasException && exceptionVecFromRob(storeAddrMisaligned) 1341f7af4c74Schengguanghui val hasLoadAddrMisalign = hasException && exceptionVecFromRob(loadAddrMisaligned) 1342f7af4c74Schengguanghui val hasInstrAccessFault = hasException && exceptionVecFromRob(instrAccessFault) 1343f7af4c74Schengguanghui val hasLoadAccessFault = hasException && exceptionVecFromRob(loadAccessFault) 1344f7af4c74Schengguanghui val hasStoreAccessFault = hasException && exceptionVecFromRob(storeAccessFault) 1345f7af4c74Schengguanghui val hasBreakPoint = hasException && exceptionVecFromRob(breakPoint) 13461f518b57SXuan Hu val hasInstGuestPageFault = hasException && exceptionVecFromRob(instrGuestPageFault) 13471f518b57SXuan Hu val hasLoadGuestPageFault = hasException && exceptionVecFromRob(loadGuestPageFault) 13481f518b57SXuan Hu val hasStoreGuestPageFault = hasException && exceptionVecFromRob(storeGuestPageFault) 1349f7af4c74Schengguanghui val hasSingleStep = hasException && csrio.exception.bits.singleStep 1350f7af4c74Schengguanghui val hasTriggerFire = hasException && csrio.exception.bits.trigger.canFire 1351f7af4c74Schengguanghui val triggerFrontendHitVec = csrio.exception.bits.trigger.frontendHit 1352f7af4c74Schengguanghui val triggerMemHitVec = csrio.exception.bits.trigger.backendHit 1353f7af4c74Schengguanghui val triggerHitVec = triggerFrontendHitVec | triggerMemHitVec // Todo: update mcontrol.hit 1354f7af4c74Schengguanghui val triggerCanFireVec = csrio.exception.bits.trigger.frontendCanFire | csrio.exception.bits.trigger.backendCanFire 1355f7af4c74Schengguanghui // More than one triggers can hit at the same time, but only fire one 1356f7af4c74Schengguanghui // We select the first hit trigger to fire 1357f7af4c74Schengguanghui val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 1358f7af4c74Schengguanghui val triggerFireAction = PriorityMux(triggerFireOH, tdata1WireVec.map(_.getTriggerAction)).asUInt 1359f7af4c74Schengguanghui 136084e47f35SLi Qianruo 136184e47f35SLi Qianruo XSDebug(hasSingleStep, "Debug Mode: single step exception\n") 1362f7af4c74Schengguanghui XSDebug(hasTriggerFire, p"Debug Mode: trigger fire, frontend hit vec ${Binary(csrio.exception.bits.trigger.frontendHit.asUInt)} " + 1363f7af4c74Schengguanghui p"backend hit vec ${Binary(csrio.exception.bits.trigger.backendHit.asUInt)}\n") 1364e9341afdSYinan Xu 1365f7af4c74Schengguanghui val hasExceptionVec = csrio.exception.bits.exceptionVec 1366f7af4c74Schengguanghui val regularExceptionNO = ExceptionNO.priorities.foldRight(0.U)((i: Int, sum: UInt) => Mux(hasExceptionVec(i), i.U, sum)) 1367f7af4c74Schengguanghui val exceptionNO = Mux(hasSingleStep || hasTriggerFire, 3.U, regularExceptionNO) 1368f7af4c74Schengguanghui val causeNO = (hasIntr << (XLEN - 1)).asUInt | Mux(hasIntr, intrNO, exceptionNO) 1369e9341afdSYinan Xu 1370f7af4c74Schengguanghui val hasExceptionIntr = csrio.exception.valid 1371d4aca96cSlqre 1372f7af4c74Schengguanghui val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode 1373f7af4c74Schengguanghui val hasDebugTriggerException = hasTriggerFire && triggerFireAction === TrigActionEnum.DEBUG_MODE 1374f7af4c74Schengguanghui val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep 1375f7af4c74Schengguanghui val hasDebugTrap = hasDebugException || hasDebugIntr 1376f7af4c74Schengguanghui val ebreakEnterParkLoop = debugMode && hasExceptionIntr 1377f7af4c74Schengguanghui 1378f7af4c74Schengguanghui XSDebug(hasExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 1379f7af4c74Schengguanghui dexceptionPC, intrNO, intrVec, exceptionNO, hasExceptionVec.asUInt 1380e9341afdSYinan Xu ) 1381f7af4c74Schengguanghui XSDebug(hasExceptionIntr, 1382e9341afdSYinan Xu "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 1383a4e57ea3SLi Qianruo dexceptionPC, 1384e9341afdSYinan Xu mstatus, 1385e9341afdSYinan Xu mideleg, 1386e9341afdSYinan Xu medeleg, 1387321934c7SKunlin You privilegeMode 1388e9341afdSYinan Xu ) 1389e9341afdSYinan Xu 1390e9341afdSYinan Xu // mtval write logic 13918a33de1fSYinan Xu // Due to timing reasons of memExceptionVAddr, we delay the write of mtval and stval 1392e9341afdSYinan Xu val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 1393d0de7e4aSpeixiaokun val memExceptionGPAddr = SignExt(csrio.memExceptionGPAddr, XLEN) 1394a4e57ea3SLi Qianruo val updateTval = VecInit(Seq( 1395a4e57ea3SLi Qianruo hasInstrPageFault, 1396a4e57ea3SLi Qianruo hasLoadPageFault, 1397a4e57ea3SLi Qianruo hasStorePageFault, 1398a4e57ea3SLi Qianruo hasInstrAccessFault, 1399a4e57ea3SLi Qianruo hasLoadAccessFault, 1400a4e57ea3SLi Qianruo hasStoreAccessFault, 1401f7af4c74Schengguanghui hasLoadAddrMisalign, 14025b0f0029SXuan Hu hasStoreAddrMisalign, 1403d0de7e4aSpeixiaokun hasInstGuestPageFault, 1404d0de7e4aSpeixiaokun hasLoadGuestPageFault, 14051797fef6SXuan Hu hasStoreGuestPageFault, 14061797fef6SXuan Hu hasBreakPoint, 1407d0de7e4aSpeixiaokun )).asUInt.orR 1408d0de7e4aSpeixiaokun val updateTval_h = VecInit(Seq( 1409d0de7e4aSpeixiaokun hasInstGuestPageFault, 1410d0de7e4aSpeixiaokun hasLoadGuestPageFault, 1411d0de7e4aSpeixiaokun hasStoreGuestPageFault 1412a4e57ea3SLi Qianruo )).asUInt.orR 1413a4e57ea3SLi Qianruo when (RegNext(RegNext(updateTval))) { 141495fbbc80SYinan Xu val tval = Mux( 14151797fef6SXuan Hu RegNext(RegNext(hasInstrPageFault || hasInstrAccessFault || hasInstGuestPageFault || hasBreakPoint)), 141695fbbc80SYinan Xu RegNext(RegNext(Mux( 14173b739f49SXuan Hu csrio.exception.bits.crossPageIPFFix, 14183b739f49SXuan Hu SignExt(csrio.exception.bits.pc + 2.U, XLEN), 1419a4e57ea3SLi Qianruo iexceptionPC 142095fbbc80SYinan Xu ))), 1421e9341afdSYinan Xu memExceptionAddr 142295fbbc80SYinan Xu ) 1423d0de7e4aSpeixiaokun // because we update tval two beats later, we can choose xtval according to the privilegeMode which has been updated 1424321934c7SKunlin You when (RegNext(privilegeMode === ModeM)) { 1425e9341afdSYinan Xu mtval := tval 1426e9341afdSYinan Xu }.otherwise { 1427d0de7e4aSpeixiaokun when (virtMode){ 1428d0de7e4aSpeixiaokun vstval := tval 1429d0de7e4aSpeixiaokun }.otherwise{ 1430e9341afdSYinan Xu stval := tval 1431e9341afdSYinan Xu } 1432e9341afdSYinan Xu } 1433d0de7e4aSpeixiaokun } 1434d0de7e4aSpeixiaokun 1435d0de7e4aSpeixiaokun when(RegNext(RegNext(updateTval_h))) { 1436d0de7e4aSpeixiaokun val tval_tmp = Mux( 1437d0de7e4aSpeixiaokun RegNext(RegNext(hasInstGuestPageFault)), 1438d0de7e4aSpeixiaokun RegNext(RegNext(Mux( 1439e25e4d90SXuan Hu csrio.exception.bits.crossPageIPFFix, 1440e25e4d90SXuan Hu SignExt(csrio.exception.bits.gpaddr + 2.U, XLEN), 1441d0de7e4aSpeixiaokun iexceptionGPAddr 1442d0de7e4aSpeixiaokun ))), 1443d0de7e4aSpeixiaokun memExceptionGPAddr 1444d0de7e4aSpeixiaokun ) 1445d0de7e4aSpeixiaokun val tval = tval_tmp >> 2 1446d0de7e4aSpeixiaokun when(RegNext(privilegeMode === ModeM)) { 1447d0de7e4aSpeixiaokun mtval2 := tval 1448d0de7e4aSpeixiaokun }.otherwise { 1449d0de7e4aSpeixiaokun htval := tval 1450d0de7e4aSpeixiaokun } 1451d0de7e4aSpeixiaokun } 1452e9341afdSYinan Xu 1453d4aca96cSlqre val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 1454f7af4c74Schengguanghui val deleg = Mux(hasIntr, mideleg , medeleg) 14551f518b57SXuan Hu val hdeleg = Mux(hasIntr, hideleg, hedeleg) 1456321934c7SKunlin You // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (privilegeMode < ModeM); 14575b0f0029SXuan Hu val delegS = deleg(causeNO(7,0)) && (privilegeMode < ModeM) 1458d0de7e4aSpeixiaokun val delegVS = virtMode && delegS && hdeleg(causeNO(7, 0)) && (privilegeMode < ModeM) 1459f7af4c74Schengguanghui val clearTval = !updateTval || hasIntr 146013096f7eSYinan Xu 14611f518b57SXuan Hu val clearTval_h = !updateTval_h || hasIntr 1462e25e4d90SXuan Hu val isHyperInst = csrio.exception.bits.isHls 146313096f7eSYinan Xu // ctrl block will use theses later for flush 146413096f7eSYinan Xu val isXRetFlag = RegInit(false.B) 14653b739f49SXuan Hu when (DelayN(io.flush.valid, 5)) { 146613096f7eSYinan Xu isXRetFlag := false.B 146713096f7eSYinan Xu }.elsewhen (isXRet) { 146813096f7eSYinan Xu isXRetFlag := true.B 146913096f7eSYinan Xu } 147013096f7eSYinan Xu csrio.isXRet := isXRetFlag 1471f7af4c74Schengguanghui private val retTargetReg = RegEnable(retTarget, isXRet && !illegalRetTarget) 1472d0de7e4aSpeixiaokun private val illegalXret = RegEnable(illegalMret || illegalSret || illegalSModeSret || illegalVSModeSret, isXRet) 1473a4e57ea3SLi Qianruo 1474e25e4d90SXuan Hu private val xtvec = Mux(delegS, Mux(delegVS, vstvec, stvec), mtvec) 1475f7af4c74Schengguanghui private val xtvecBase = xtvec(VAddrBits - 1, 2) 1476a4e57ea3SLi Qianruo // When MODE=Vectored, all synchronous exceptions into M/S mode 1477a4e57ea3SLi Qianruo // cause the pc to be set to the address in the BASE field, whereas 1478a4e57ea3SLi Qianruo // interrupts cause the pc to be set to the address in the BASE field 1479a4e57ea3SLi Qianruo // plus four times the interrupt cause number. 1480f7af4c74Schengguanghui private val pcFromXtvec = Cat(xtvecBase + Mux(xtvec(0) && hasIntr, causeNO(3, 0), 0.U), 0.U(2.W)) 1481e9341afdSYinan Xu 1482f7af4c74Schengguanghui // XRet sends redirect instead of Flush and isXRetFlag is true.B before redirect.valid. 1483f7af4c74Schengguanghui // ROB sends exception at T0 while CSR receives at T2. 1484f7af4c74Schengguanghui // We add a RegNext here and trapTarget is valid at T3. 1485f7af4c74Schengguanghui csrio.trapTarget := RegEnable( 1486f7af4c74Schengguanghui MuxCase(pcFromXtvec, Seq( 1487f7af4c74Schengguanghui (isXRetFlag && !illegalXret) -> retTargetReg, 1488f7af4c74Schengguanghui ((hasDebugTrap && !debugMode) || ebreakEnterParkLoop) -> debugTrapTarget 1489f7af4c74Schengguanghui )), 1490f7af4c74Schengguanghui isXRetFlag || csrio.exception.valid) 1491f7af4c74Schengguanghui 1492f7af4c74Schengguanghui when(hasExceptionIntr) { 1493c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1494c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1495d0de7e4aSpeixiaokun val hstatusOld = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1496d0de7e4aSpeixiaokun val hstatusNew = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1497d0de7e4aSpeixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1498d0de7e4aSpeixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1499d4aca96cSlqre val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1500d4aca96cSlqre val debugModeNew = WireInit(debugMode) 1501f7af4c74Schengguanghui when(hasDebugTrap && !debugMode) { 1502f7af4c74Schengguanghui import DcsrStruct._ 1503d4aca96cSlqre debugModeNew := true.B 15040ffeff0dSXuan Hu dcsrNew.prv := privilegeMode 15050ffeff0dSXuan Hu privilegeMode := ModeM 1506f7af4c74Schengguanghui when(hasDebugIntr) { 1507a4e57ea3SLi Qianruo dpc := iexceptionPC 1508f7af4c74Schengguanghui dcsrNew.cause := CAUSE_HALTREQ 1509f7af4c74Schengguanghui XSDebug(hasDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 1510f7af4c74Schengguanghui }.otherwise { // hasDebugException 1511f7af4c74Schengguanghui dpc := iexceptionPC // TODO: check it when hasSingleStep 1512f7af4c74Schengguanghui dcsrNew.cause := MuxCase(0.U, Seq( 1513f7af4c74Schengguanghui hasTriggerFire -> CAUSE_TRIGGER, 1514*5f28e666Schengguanghui raiseDebugException -> CAUSE_EBREAK, 1515f7af4c74Schengguanghui hasBreakPoint -> CAUSE_HALTREQ, 1516f7af4c74Schengguanghui hasSingleStep -> CAUSE_STEP 1517f7af4c74Schengguanghui )) 1518d4aca96cSlqre } 1519d4aca96cSlqre dcsr := dcsrNew.asUInt 1520d4aca96cSlqre debugIntrEnable := false.B 1521d7dd1af1SLi Qianruo }.elsewhen (debugMode) { 1522d7dd1af1SLi Qianruo //do nothing 1523d61cd5eeSpeixiaokun }.elsewhen (delegVS) { 152496544367Speixiaokun vscause := (hasIntr << (XLEN-1)).asUInt | Mux(hasIntr, intrNO - 1.U, exceptionNO) 1525d0de7e4aSpeixiaokun vsepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1526d0de7e4aSpeixiaokun vsstatusNew.spp := privilegeMode 1527d0de7e4aSpeixiaokun vsstatusNew.pie.s := vsstatusOld.ie.s 1528d0de7e4aSpeixiaokun vsstatusNew.ie.s := false.B 1529d0de7e4aSpeixiaokun when (clearTval) {vstval := 0.U} 1530d0de7e4aSpeixiaokun virtMode := true.B 1531d0de7e4aSpeixiaokun privilegeMode := ModeS 1532d4aca96cSlqre }.elsewhen (delegS) { 15330214776eSpeixiaokun val virt = Mux(mstatusOld.mprv.asBool, mstatusOld.mpv, virtMode) 1534d0de7e4aSpeixiaokun // to do hld st 1535d0de7e4aSpeixiaokun hstatusNew.gva := (hasInstGuestPageFault || hasLoadGuestPageFault || hasStoreGuestPageFault || 15361f518b57SXuan Hu ((virt.asBool || isHyperInst) && ((hasException && 0.U <= exceptionNO && exceptionNO <= 7.U && exceptionNO =/= 2.U) 1537d0de7e4aSpeixiaokun || hasInstrPageFault || hasLoadPageFault || hasStorePageFault))) 1538d0de7e4aSpeixiaokun hstatusNew.spv := virtMode 1539d0de7e4aSpeixiaokun when(virtMode){ 1540d0de7e4aSpeixiaokun hstatusNew.spvp := privilegeMode 1541d0de7e4aSpeixiaokun } 1542d0de7e4aSpeixiaokun virtMode := false.B 1543c84054caSLinJiawei scause := causeNO 1544a4e57ea3SLi Qianruo sepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1545321934c7SKunlin You mstatusNew.spp := privilegeMode 1546c84054caSLinJiawei mstatusNew.pie.s := mstatusOld.ie.s 1547c84054caSLinJiawei mstatusNew.ie.s := false.B 1548321934c7SKunlin You privilegeMode := ModeS 1549a4e57ea3SLi Qianruo when (clearTval) { stval := 0.U } 1550d0de7e4aSpeixiaokun when (clearTval_h) {htval := 0.U} 1551c84054caSLinJiawei }.otherwise { 15520214776eSpeixiaokun val virt = Mux(mstatusOld.mprv.asBool, mstatusOld.mpv, virtMode) 1553d0de7e4aSpeixiaokun // to do hld st 1554d0de7e4aSpeixiaokun mstatusNew.gva := (hasInstGuestPageFault || hasLoadGuestPageFault || hasStoreGuestPageFault || 15551f518b57SXuan Hu ((virt.asBool || isHyperInst) && ((hasException && 0.U <= exceptionNO && exceptionNO <= 7.U && exceptionNO =/= 2.U) 1556d0de7e4aSpeixiaokun || hasInstrPageFault || hasLoadPageFault || hasStorePageFault))) 1557d0de7e4aSpeixiaokun mstatusNew.mpv := virtMode 1558d0de7e4aSpeixiaokun virtMode := false.B 1559c84054caSLinJiawei mcause := causeNO 1560a4e57ea3SLi Qianruo mepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1561321934c7SKunlin You mstatusNew.mpp := privilegeMode 1562c84054caSLinJiawei mstatusNew.pie.m := mstatusOld.ie.m 1563c84054caSLinJiawei mstatusNew.ie.m := false.B 1564321934c7SKunlin You privilegeMode := ModeM 1565a4e57ea3SLi Qianruo when (clearTval) { mtval := 0.U } 1566d0de7e4aSpeixiaokun when (clearTval_h) {mtval2 := 0.U} 1567c84054caSLinJiawei } 1568c84054caSLinJiawei mstatus := mstatusNew.asUInt 1569d0de7e4aSpeixiaokun vsstatus := vsstatusNew.asUInt 1570d0de7e4aSpeixiaokun hstatus := hstatusNew.asUInt 1571d4aca96cSlqre debugMode := debugModeNew 1572c84054caSLinJiawei } 1573c84054caSLinJiawei 1574e19f7967SWilliam Wang // Distributed CSR update req 1575e19f7967SWilliam Wang // 1576e19f7967SWilliam Wang // For now we use it to implement customized cache op 157770899835SWilliam Wang // It can be delayed if necessary 1578e19f7967SWilliam Wang 157970899835SWilliam Wang val delayedUpdate0 = DelayN(csrio.distributedUpdate(0), 2) 158070899835SWilliam Wang val delayedUpdate1 = DelayN(csrio.distributedUpdate(1), 2) 158170899835SWilliam Wang val distributedUpdateValid = delayedUpdate0.w.valid || delayedUpdate1.w.valid 158270899835SWilliam Wang val distributedUpdateAddr = Mux(delayedUpdate0.w.valid, 158370899835SWilliam Wang delayedUpdate0.w.bits.addr, 158470899835SWilliam Wang delayedUpdate1.w.bits.addr 158570899835SWilliam Wang ) 158670899835SWilliam Wang val distributedUpdateData = Mux(delayedUpdate0.w.valid, 158770899835SWilliam Wang delayedUpdate0.w.bits.data, 158870899835SWilliam Wang delayedUpdate1.w.bits.data 158970899835SWilliam Wang ) 159070899835SWilliam Wang 159170899835SWilliam Wang assert(!(delayedUpdate0.w.valid && delayedUpdate1.w.valid)) 159270899835SWilliam Wang 159370899835SWilliam Wang when(distributedUpdateValid){ 1594e19f7967SWilliam Wang // cacheopRegs can be distributed updated 1595e19f7967SWilliam Wang CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 159670899835SWilliam Wang when((Scachebase + attribute("offset").toInt).U === distributedUpdateAddr){ 159770899835SWilliam Wang cacheopRegs(name) := distributedUpdateData 1598e19f7967SWilliam Wang } 1599e19f7967SWilliam Wang }} 1600e19f7967SWilliam Wang } 1601e19f7967SWilliam Wang 16029ef181f4SWilliam Wang // Cache error debug support 16039ef181f4SWilliam Wang if(HasCustomCSRCacheOp){ 16049ef181f4SWilliam Wang val cache_error_decoder = Module(new CSRCacheErrorDecoder) 16059ef181f4SWilliam Wang cache_error_decoder.io.encoded_cache_error := cacheopRegs("CACHE_ERROR") 16069ef181f4SWilliam Wang } 16079ef181f4SWilliam Wang 1608e30fd06aSYinan Xu // Implicit add reset values for mepc[0] and sepc[0] 1609e30fd06aSYinan Xu // TODO: rewrite mepc and sepc using a struct-like style with the LSB always being 0 161067ba96b4SYinan Xu when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 1611e30fd06aSYinan Xu mepc := Cat(mepc(XLEN - 1, 1), 0.U(1.W)) 1612e30fd06aSYinan Xu sepc := Cat(sepc(XLEN - 1, 1), 0.U(1.W)) 161321ae6bc4Speixiaokun vsepc := Cat(vsepc(XLEN - 1, 1), 0.U(1.W)) 1614e30fd06aSYinan Xu } 1615e30fd06aSYinan Xu 1616c84054caSLinJiawei def readWithScala(addr: Int): UInt = mapping(addr)._1 1617c84054caSLinJiawei 1618f7af4c74Schengguanghui val difftestIntrNO = Mux(hasIntr, causeNO, 0.U) 1619a165bd69Swangkaifan 1620cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1621cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 16227d45a146SYinan Xu val difftest = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 16237d45a146SYinan Xu difftest.coreid := csrio.hartId 16247d45a146SYinan Xu difftest.valid := csrio.exception.valid 1625f7af4c74Schengguanghui difftest.interrupt := Mux(hasIntr, causeNO, 0.U) 1626f7af4c74Schengguanghui difftest.exception := Mux(hasException, causeNO, 0.U) 16277d45a146SYinan Xu difftest.exceptionPC := dexceptionPC 1628a4e57ea3SLi Qianruo if (env.EnableDifftest) { 16294b0d80d8SXuan Hu difftest.exceptionInst := csrio.exception.bits.instr 1630a4e57ea3SLi Qianruo } 16312225d46eSJiawei Lin } 16322225d46eSJiawei Lin 1633cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1634cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 16357d45a146SYinan Xu val difftest = DifftestModule(new DiffCSRState) 16367d45a146SYinan Xu difftest.coreid := csrio.hartId 1637321934c7SKunlin You difftest.privilegeMode := privilegeMode 16387d45a146SYinan Xu difftest.mstatus := mstatus 16397d45a146SYinan Xu difftest.sstatus := mstatus & sstatusRmask 16407d45a146SYinan Xu difftest.mepc := mepc 16417d45a146SYinan Xu difftest.sepc := sepc 16427d45a146SYinan Xu difftest.mtval:= mtval 16437d45a146SYinan Xu difftest.stval:= stval 16447d45a146SYinan Xu difftest.mtvec := mtvec 16457d45a146SYinan Xu difftest.stvec := stvec 16467d45a146SYinan Xu difftest.mcause := mcause 16477d45a146SYinan Xu difftest.scause := scause 16487d45a146SYinan Xu difftest.satp := satp 16497d45a146SYinan Xu difftest.mip := mipReg 16507d45a146SYinan Xu difftest.mie := mie 16517d45a146SYinan Xu difftest.mscratch := mscratch 16527d45a146SYinan Xu difftest.sscratch := sscratch 16537d45a146SYinan Xu difftest.mideleg := mideleg 16547d45a146SYinan Xu difftest.medeleg := medeleg 1655a165bd69Swangkaifan } 1656a4e57ea3SLi Qianruo 1657a4e57ea3SLi Qianruo if (env.AlwaysBasicDiff || env.EnableDifftest) { 165887d0ba30Speixiaokun val difftest = DifftestModule(new DiffHCSRState) 165987d0ba30Speixiaokun difftest.coreid := csrio.hartId 166087d0ba30Speixiaokun difftest.virtMode := virtMode 166187d0ba30Speixiaokun difftest.mtval2 := mtval2 166287d0ba30Speixiaokun difftest.mtinst := mtinst 166387d0ba30Speixiaokun difftest.hstatus := hstatus 166487d0ba30Speixiaokun difftest.hideleg := hideleg 166587d0ba30Speixiaokun difftest.hedeleg := hedeleg 166687d0ba30Speixiaokun difftest.hcounteren := hcounteren 166787d0ba30Speixiaokun difftest.htval := htval 166887d0ba30Speixiaokun difftest.htinst := htinst 166987d0ba30Speixiaokun difftest.hgatp := hgatp 167087d0ba30Speixiaokun difftest.vsstatus := vsstatus 167187d0ba30Speixiaokun difftest.vstvec := vstvec 167287d0ba30Speixiaokun difftest.vsepc := vsepc 167387d0ba30Speixiaokun difftest.vscause := vscause 167487d0ba30Speixiaokun difftest.vstval := vstval 167587d0ba30Speixiaokun difftest.vsatp := vsatp 167687d0ba30Speixiaokun difftest.vsscratch := vsscratch 1677d0de7e4aSpeixiaokun } 1678d0de7e4aSpeixiaokun 1679d0de7e4aSpeixiaokun if(env.AlwaysBasicDiff || env.EnableDifftest) { 16807d45a146SYinan Xu val difftest = DifftestModule(new DiffDebugMode) 16817d45a146SYinan Xu difftest.coreid := csrio.hartId 16827d45a146SYinan Xu difftest.debugMode := debugMode 16837d45a146SYinan Xu difftest.dcsr := dcsr 16847d45a146SYinan Xu difftest.dpc := dpc 1685f7af4c74Schengguanghui difftest.dscratch0 := dscratch0 16867d45a146SYinan Xu difftest.dscratch1 := dscratch1 1687a4e57ea3SLi Qianruo } 168835d1557aSZiyue Zhang 168935d1557aSZiyue Zhang if (env.AlwaysBasicDiff || env.EnableDifftest) { 169083ba63b3SXuan Hu val difftest = DifftestModule(new DiffVecCSRState) 169183ba63b3SXuan Hu difftest.coreid := csrio.hartId 169283ba63b3SXuan Hu difftest.vstart := vstart 169383ba63b3SXuan Hu difftest.vxsat := vcsr.asTypeOf(new VcsrStruct).vxsat 169483ba63b3SXuan Hu difftest.vxrm := vcsr.asTypeOf(new VcsrStruct).vxrm 169583ba63b3SXuan Hu difftest.vcsr := vcsr 169683ba63b3SXuan Hu difftest.vl := vl 169783ba63b3SXuan Hu difftest.vtype := vtype 169883ba63b3SXuan Hu difftest.vlenb := vlenb 169935d1557aSZiyue Zhang } 1700c84054caSLinJiawei} 17011545277aSYinan Xu 1702cd365d4cSrvcoresjwclass PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst { 1703cd365d4cSrvcoresjw val io = IO(new Bundle { 1704cd365d4cSrvcoresjw val distribute_csr = Flipped(new DistributedCSRIO()) 1705cd365d4cSrvcoresjw val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1706cd365d4cSrvcoresjw }) 1707cd365d4cSrvcoresjw 1708cd365d4cSrvcoresjw val w = io.distribute_csr.w 1709cd365d4cSrvcoresjw 17105fd90906Srvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 17115fd90906Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 17125fd90906Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 17135fd90906Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 1714cd365d4cSrvcoresjw 171512c44ce5Srvcoresjw val perfEventMapping = (0 until 29).map(i => {Map( 171612c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmevent3 +i, 171712c44ce5Srvcoresjw reg = perfEvents(i), 171812c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)) 171912c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 1720cd365d4cSrvcoresjw 1721cd365d4cSrvcoresjw val rdata = Wire(UInt(XLEN.W)) 1722cd365d4cSrvcoresjw MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 17235fd90906Srvcoresjw for(i <- 0 until 29){ 17245fd90906Srvcoresjw io.hpmevent(i) := perfEvents(i) 17255fd90906Srvcoresjw } 1726cd365d4cSrvcoresjw} 1727