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._ 3192c61038SXuan Huimport xiangshan.backend.Bundles.{ExceptionInfo, TrapInstInfo} 32c1b28b66STang Haojinimport xiangshan.backend.fu.NewCSR.CSREvents.TargetPCBundle 33039cdc35SXuan Huimport xiangshan.backend.fu.NewCSR.CSRNamedConstant.ContextStatus 34c1b28b66STang Haojinimport xiangshan.backend.rob.RobPtr 3562a2cb19SXuan Huimport utils.MathUtils.{BigIntGenMask, BigIntNot} 364907ec88Schengguanghuiimport xiangshan.backend.trace._ 37075d4937Sjunxiong-jiimport freechips.rocketchip.rocket.CSRs 38c84054caSLinJiawei 392225d46eSJiawei Linclass FpuCsrIO extends Bundle { 407f1506e3SLinJiawei val fflags = Output(Valid(UInt(5.W))) 41c84054caSLinJiawei val isIllegal = Output(Bool()) 42c84054caSLinJiawei val dirty_fs = Output(Bool()) 43c84054caSLinJiawei val frm = Input(UInt(3.W)) 44c84054caSLinJiawei} 45c84054caSLinJiawei 46daa01159SZiyue Zhangclass VpuCsrIO(implicit p: Parameters) extends XSBundle { 47daa01159SZiyue Zhang val vstart = Input(UInt(XLEN.W)) 48daa01159SZiyue Zhang val vxrm = Input(UInt(2.W)) 49daa01159SZiyue Zhang 50d8a50338SZiyue Zhang val vl = Output(UInt(XLEN.W)) 51daa01159SZiyue Zhang 5235d1557aSZiyue Zhang val set_vstart = Output(Valid(UInt(XLEN.W))) 5335d1557aSZiyue Zhang val set_vtype = Output(Valid(UInt(XLEN.W))) 546355a2b7Sczw val set_vxsat = Output(Valid(UInt(1.W))) 55daa01159SZiyue Zhang 56daa01159SZiyue Zhang val dirty_vs = Output(Bool()) 57daa01159SZiyue Zhang} 58daa01159SZiyue Zhang 59b2e234ebSLinJiawei 602225d46eSJiawei Linclass PerfCounterIO(implicit p: Parameters) extends XSBundle { 611ca0e4f3SYinan Xu val perfEventsFrontend = Vec(numCSRPCntFrontend, new PerfEvent) 62e1a85e9fSchengguanghui val perfEventsBackend = Vec(numCSRPCntCtrl, new PerfEvent) 631ca0e4f3SYinan Xu val perfEventsLsu = Vec(numCSRPCntLsu, new PerfEvent) 648bb30a57SJiru Sun val perfEventsHc = Vec(numPCntHc * coreParams.L2NBanks + 1, new PerfEvent) 658419d406SXuan Hu val retiredInstr = UInt(7.W) 66edd6ddbcSwakafa val frontendInfo = new Bundle { 67edd6ddbcSwakafa val ibufFull = Bool() 68e0d9a9f0SLingrui98 val bpuInfo = new Bundle { 69e0d9a9f0SLingrui98 val bpRight = UInt(XLEN.W) 70e0d9a9f0SLingrui98 val bpWrong = UInt(XLEN.W) 71e0d9a9f0SLingrui98 } 72edd6ddbcSwakafa } 73edd6ddbcSwakafa val ctrlInfo = new Bundle { 749aca92b9SYinan Xu val robFull = Bool() 75edd6ddbcSwakafa val intdqFull = Bool() 76edd6ddbcSwakafa val fpdqFull = Bool() 77edd6ddbcSwakafa val lsdqFull = Bool() 78edd6ddbcSwakafa } 79edd6ddbcSwakafa val memInfo = new Bundle { 80edd6ddbcSwakafa val sqFull = Bool() 81edd6ddbcSwakafa val lqFull = Bool() 82edd6ddbcSwakafa val dcacheMSHRFull = Bool() 83edd6ddbcSwakafa } 8462ab1317SYinan Xu} 8562ab1317SYinan Xu 862225d46eSJiawei Linclass CSRFileIO(implicit p: Parameters) extends XSBundle { 87f57f7f2aSYangyu Chen val hartId = Input(UInt(hartIdLen.W)) 88129a273eSYinan Xu // output (for func === CSROpType.jmp) 89edd6ddbcSwakafa val perf = Input(new PerfCounterIO) 90a751b11aSchengguanghui val criticalErrorState = Output(Bool()) 918635f18fSwangkaifan val isPerfCnt = Output(Bool()) 92129a273eSYinan Xu // to FPU 93129a273eSYinan Xu val fpu = Flipped(new FpuCsrIO) 94daa01159SZiyue Zhang // to VPU 95daa01159SZiyue Zhang val vpu = Flipped(new VpuCsrIO) 96bf9968b2SYinan Xu // from rob 973a474d38SYinan Xu val exception = Flipped(ValidIO(new ExceptionInfo)) 98c1b28b66STang Haojin val robDeqPtr = Input(new RobPtr) 99129a273eSYinan Xu // to ROB 100ac5a5d53SLinJiawei val isXRet = Output(Bool()) 101c1b28b66STang Haojin val trapTarget = Output(new TargetPCBundle) 102129a273eSYinan Xu val interrupt = Output(Bool()) 1035c95ea2eSYinan Xu val wfi_event = Output(Bool()) 104c308d936Schengguanghui //trace 105c308d936Schengguanghui val traceCSR = Output(new TraceCSR) 106129a273eSYinan Xu // from LSQ 107db6cfb5aSHaoyuan Feng val memExceptionVAddr = Input(UInt(XLEN.W)) 108db6cfb5aSHaoyuan Feng val memExceptionGPAddr = Input(UInt(XLEN.W)) 109ad415ae0SXiaokun-Pei val memExceptionIsForVSnonLeafPTE = Input(Bool()) 110129a273eSYinan Xu // from outside cpu,externalInterrupt 1115f705224Sxiaofeibao-xjtu val externalInterrupt = Input(new ExternalInterruptIO) 112129a273eSYinan Xu // TLB 113129a273eSYinan Xu val tlb = Output(new TlbCsrBundle) 114d4aca96cSlqre // Debug Mode 115d7dd1af1SLi Qianruo // val singleStep = Output(Bool()) 116d4aca96cSlqre val debugMode = Output(Bool()) 117e377d77eSWilliam Wang // Custom microarchiture ctrl signal 118e377d77eSWilliam Wang val customCtrl = Output(new CustomCSRCtrlIO) 119c1b28b66STang Haojin // instruction fetch address translation type 120c1b28b66STang Haojin val instrAddrTransType = Output(new AddrTransType) 121*8cfc24b2STang Haojin // ack for axireg from imsic. which indicates imsic can work actively 122*8cfc24b2STang Haojin val msiAck = Output(Bool()) 12335a47a38SYinan Xu} 12435a47a38SYinan Xu 125a8db15d8Sfdyclass VtypeStruct(implicit p: Parameters) extends XSBundle { 126a8db15d8Sfdy val vill = UInt(1.W) 127a8db15d8Sfdy val reserved = UInt((XLEN - 9).W) 128a8db15d8Sfdy val vma = UInt(1.W) 129a8db15d8Sfdy val vta = UInt(1.W) 130a8db15d8Sfdy val vsew = UInt(3.W) 131a8db15d8Sfdy val vlmul = UInt(3.W) 132a8db15d8Sfdy} 1337e0f64b0SGuanghui Cheng/* 134d91483a6Sfdyclass CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) 1353b739f49SXuan Hu with HasCSRConst 1363b739f49SXuan Hu with PMPMethod 1373b739f49SXuan Hu with PMAMethod 1383b739f49SXuan Hu with HasXSParameter 139f7af4c74Schengguanghui with SdtrigExt 140f7af4c74Schengguanghui with DebugCSR 14135a47a38SYinan Xu{ 1423b739f49SXuan Hu val csrio = io.csrio.get 143c84054caSLinJiawei 144e18c367fSLinJiawei val flushPipe = Wire(Bool()) 145c84054caSLinJiawei 146e18c367fSLinJiawei val (valid, src1, src2, func) = ( 147e18c367fSLinJiawei io.in.valid, 1486a35d972SXuan Hu io.in.bits.data.src(0), 1496a35d972SXuan Hu io.in.bits.data.imm, 1506a35d972SXuan Hu io.in.bits.ctrl.fuOpType 151e18c367fSLinJiawei ) 152c84054caSLinJiawei 153c84054caSLinJiawei // CSR define 154d0de7e4aSpeixiaokun val virtMode = RegInit(false.B) 155d0de7e4aSpeixiaokun csrio.customCtrl.virtMode := virtMode 156c84054caSLinJiawei 157c84054caSLinJiawei class Priv extends Bundle { 158c84054caSLinJiawei val m = Output(Bool()) 159d0de7e4aSpeixiaokun val h = Output(Bool()) // unused 160c84054caSLinJiawei val s = Output(Bool()) 161c84054caSLinJiawei val u = Output(Bool()) 162c84054caSLinJiawei } 163c84054caSLinJiawei 164c84054caSLinJiawei class MstatusStruct extends Bundle { 165c84054caSLinJiawei val sd = Output(UInt(1.W)) 1668e7b11e5SWilliam Wang 167d0de7e4aSpeixiaokun val pad1 = if (XLEN == 64 && HasHExtension) Output(UInt(23.W)) else if (XLEN == 64) Output(UInt(25.W)) else null 168d0de7e4aSpeixiaokun val mpv = if (XLEN == 64 && HasHExtension) Output(UInt(1.W)) else null 169d0de7e4aSpeixiaokun val gva = if (XLEN == 64 && HasHExtension) Output(UInt(1.W)) else null 1707d9edc86SLemover val mbe = if (XLEN == 64) Output(UInt(1.W)) else null 1717d9edc86SLemover val sbe = if (XLEN == 64) Output(UInt(1.W)) else null 1728e7b11e5SWilliam Wang val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 1738e7b11e5SWilliam Wang val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 1748e7b11e5SWilliam Wang val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 1758e7b11e5SWilliam Wang 176c84054caSLinJiawei val tsr = Output(UInt(1.W)) 177c84054caSLinJiawei val tw = Output(UInt(1.W)) 1788e7b11e5SWilliam Wang val tvm = Output(UInt(1.W)) 179c84054caSLinJiawei val mxr = Output(UInt(1.W)) 180c84054caSLinJiawei val sum = Output(UInt(1.W)) 181c84054caSLinJiawei val mprv = Output(UInt(1.W)) 182c84054caSLinJiawei val xs = Output(UInt(2.W)) 183c84054caSLinJiawei val fs = Output(UInt(2.W)) 184c84054caSLinJiawei val mpp = Output(UInt(2.W)) 185daa01159SZiyue Zhang val vs = Output(UInt(2.W)) 186c84054caSLinJiawei val spp = Output(UInt(1.W)) 187c84054caSLinJiawei val pie = new Priv 188c84054caSLinJiawei val ie = new Priv 189c84054caSLinJiawei assert(this.getWidth == XLEN) 1907d9edc86SLemover 1917d9edc86SLemover def ube = pie.h // a little ugly 1927d9edc86SLemover def ube_(r: UInt): Unit = { 1937d9edc86SLemover pie.h := r(0) 1947d9edc86SLemover } 195c84054caSLinJiawei } 196c84054caSLinJiawei 197d0de7e4aSpeixiaokun class HstatusStruct extends Bundle { 198d0de7e4aSpeixiaokun val pad4 = if (HSXLEN == 64) Output(UInt(30.W)) else null 199d0de7e4aSpeixiaokun val vsxl = if (HSXLEN == 64) Output(UInt(2.W)) else null 200d0de7e4aSpeixiaokun val pad3 = Output(UInt(9.W)) 201d0de7e4aSpeixiaokun val vtsr = Output(UInt(1.W)) 202d0de7e4aSpeixiaokun val vtw = Output(UInt(1.W)) 203d0de7e4aSpeixiaokun val vtvm = Output(UInt(1.W)) 204d0de7e4aSpeixiaokun val pad2 = Output(UInt(2.W)) 205d0de7e4aSpeixiaokun val vgein = Output(UInt(6.W)) 206d0de7e4aSpeixiaokun val pad1 = Output(UInt(2.W)) 207d0de7e4aSpeixiaokun val hu = Output(UInt(1.W)) 208d0de7e4aSpeixiaokun val spvp = Output(UInt(1.W)) 209d0de7e4aSpeixiaokun val spv = Output(UInt(1.W)) 210d0de7e4aSpeixiaokun val gva = Output(UInt(1.W)) 211d0de7e4aSpeixiaokun val vsbe = Output(UInt(1.W)) 212d0de7e4aSpeixiaokun val pad0 = Output(UInt(5.W)) 213d0de7e4aSpeixiaokun assert(this.getWidth == XLEN) 214d0de7e4aSpeixiaokun } 215d0de7e4aSpeixiaokun 216c84054caSLinJiawei class Interrupt extends Bundle { 217d4aca96cSlqre// val d = Output(Bool()) // Debug 218c84054caSLinJiawei val e = new Priv 219c84054caSLinJiawei val t = new Priv 220c84054caSLinJiawei val s = new Priv 221c84054caSLinJiawei } 222c84054caSLinJiawei 223d4aca96cSlqre // Debug CSRs 224f7af4c74Schengguanghui val dcsr = RegInit(UInt(32.W), DcsrStruct.init) 225d4aca96cSlqre val dpc = Reg(UInt(64.W)) 226f7af4c74Schengguanghui val dscratch0 = Reg(UInt(64.W)) 227d4aca96cSlqre val dscratch1 = Reg(UInt(64.W)) 228d4aca96cSlqre val debugMode = RegInit(false.B) 229f7af4c74Schengguanghui val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable 230d4aca96cSlqre csrio.debugMode := debugMode 231d4aca96cSlqre 232d4aca96cSlqre val dpcPrev = RegNext(dpc) 2331097f021SLi Qianruo XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x\n", dpc, dpcPrev) 234d4aca96cSlqre 235d4aca96cSlqre val dcsrData = Wire(new DcsrStruct) 236d4aca96cSlqre dcsrData := dcsr.asTypeOf(new DcsrStruct) 237d7dd1af1SLi Qianruo val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(4) | GenMask(2, 0), XLEN)// Dcsr write mask 238d4aca96cSlqre def dcsrUpdateSideEffect(dcsr: UInt): UInt = { 239d4aca96cSlqre val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct)) 240d4aca96cSlqre val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11 241d4aca96cSlqre dcsrNew 242d4aca96cSlqre } 243d7dd1af1SLi Qianruo // csrio.singleStep := dcsrData.step 244d7dd1af1SLi Qianruo csrio.customCtrl.singlestep := dcsrData.step && !debugMode 245d4aca96cSlqre 24672951335SLi Qianruo // Trigger CSRs 247f7af4c74Schengguanghui private val tselectPhy = RegInit(0.U(log2Up(TriggerNum).W)) 24872951335SLi Qianruo 249f7af4c74Schengguanghui private val tdata1RegVec = RegInit(VecInit(Seq.fill(TriggerNum)(Tdata1Bundle.default))) 250f7af4c74Schengguanghui private val tdata2RegVec = RegInit(VecInit(Seq.fill(TriggerNum)(0.U(64.W)))) 251f7af4c74Schengguanghui private val tdata1WireVec = tdata1RegVec.map(_.asTypeOf(new Tdata1Bundle)) 252f7af4c74Schengguanghui private val tdata2WireVec = tdata2RegVec 253f7af4c74Schengguanghui private val tdata1Selected = tdata1RegVec(tselectPhy).asTypeOf(new Tdata1Bundle) 254f7af4c74Schengguanghui private val tdata2Selected = tdata2RegVec(tselectPhy) 255f7af4c74Schengguanghui private val newTriggerChainVec = UIntToOH(tselectPhy, TriggerNum).asBools | tdata1WireVec.map(_.data.asTypeOf(new MControlData).chain) 256f7af4c74Schengguanghui private val newTriggerChainIsLegal = TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength) 257f7af4c74Schengguanghui val tinfo = RegInit((BigInt(1) << TrigTypeEnum.MCONTROL.litValue.toInt).U(XLEN.W)) // This value should be 4.U 258716f717fSLi Qianruo 25972951335SLi Qianruo 26072951335SLi Qianruo def WriteTselect(wdata: UInt) = { 2615f28e666Schengguanghui Mux(wdata < TriggerNum.U, wdata(log2Up(TriggerNum) - 1, 0), tselectPhy) 26272951335SLi Qianruo } 26372951335SLi Qianruo 264f7af4c74Schengguanghui def GenTdataDistribute(tdata1: Tdata1Bundle, tdata2: UInt): MatchTriggerIO = { 26572951335SLi Qianruo val res = Wire(new MatchTriggerIO) 266f7af4c74Schengguanghui val mcontrol: MControlData = WireInit(tdata1.data.asTypeOf(new MControlData)) 267f7af4c74Schengguanghui res.matchType := mcontrol.match_.asUInt 268f7af4c74Schengguanghui res.select := mcontrol.select 269f7af4c74Schengguanghui res.timing := mcontrol.timing 270f7af4c74Schengguanghui res.action := mcontrol.action.asUInt 271f7af4c74Schengguanghui res.chain := mcontrol.chain 272f7af4c74Schengguanghui res.execute := mcontrol.execute 273f7af4c74Schengguanghui res.load := mcontrol.load 274f7af4c74Schengguanghui res.store := mcontrol.store 27572951335SLi Qianruo res.tdata2 := tdata2 27672951335SLi Qianruo res 27772951335SLi Qianruo } 27872951335SLi Qianruo 279f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tUpdate.bits.addr := tselectPhy 280f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tUpdate.bits.addr := tselectPhy 281f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tUpdate.bits.tdata := GenTdataDistribute(tdata1Selected, tdata2Selected) 282f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tUpdate.bits.tdata := GenTdataDistribute(tdata1Selected, tdata2Selected) 28372951335SLi Qianruo 284c84054caSLinJiawei // Machine-Level CSRs 285a4e57ea3SLi Qianruo // mtvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 286a4e57ea3SLi Qianruo val mtvecMask = ~(0x2.U(XLEN.W)) 287c84054caSLinJiawei val mtvec = RegInit(UInt(XLEN.W), 0.U) 288c84054caSLinJiawei val mcounteren = RegInit(UInt(XLEN.W), 0.U) 289e4b1ccacSxuzefan // Currently, XiangShan don't support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 290e4b1ccacSxuzefan val mcounterenMask = 0.U(XLEN.W) 291c84054caSLinJiawei val mcause = RegInit(UInt(XLEN.W), 0.U) 292c84054caSLinJiawei val mtval = RegInit(UInt(XLEN.W), 0.U) 293d0de7e4aSpeixiaokun val mtval2 = RegInit(UInt(XLEN.W), 0.U) 294d0de7e4aSpeixiaokun val mtinst = RegInit(UInt(XLEN.W), 0.U) 295d0de7e4aSpeixiaokun val mepc = RegInit(UInt(XLEN.W), 0.U) 296e30fd06aSYinan Xu // Page 36 in riscv-priv: The low bit of mepc (mepc[0]) is always zero. 297e30fd06aSYinan Xu val mepcMask = ~(0x1.U(XLEN.W)) 298c84054caSLinJiawei 299c84054caSLinJiawei val mie = RegInit(0.U(XLEN.W)) 300c84054caSLinJiawei val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 3015dabf2dfSYinan Xu val mipReg = RegInit(0.U(XLEN.W)) 302d7e392d1Sxuzefan val mipMask = ZeroExt(Array( 303d7e392d1Sxuzefan 1, // SSIP 304d7e392d1Sxuzefan 2, // VSSIP 305d7e392d1Sxuzefan 3, // MSIP 306d7e392d1Sxuzefan 5, // STIP 307d7e392d1Sxuzefan 6, // VSTIP 308d7e392d1Sxuzefan 7, // MTIP 309d7e392d1Sxuzefan 9, // SEIP 310d7e392d1Sxuzefan 10, // VSEIP 311d7e392d1Sxuzefan 11, // MEIP 312d7e392d1Sxuzefan 12, // SGEIP 313d7e392d1Sxuzefan ).map(GenMask(_)).reduce(_ | _), XLEN) 314c84054caSLinJiawei val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 315c84054caSLinJiawei 316d0de7e4aSpeixiaokun val mip_mie_WMask_H = if(HasHExtension){((1 << 2) | (1 << 6) | (1 << 10) | (1 << 12)).U(XLEN.W)}else{0.U(XLEN.W)} 317d0de7e4aSpeixiaokun val vssip_Mask = (1 << 2).U(XLEN.W) 318d0de7e4aSpeixiaokun 319d0de7e4aSpeixiaokun val mipWMask = vssip_Mask | ((1 << 9) | (1 << 5) | (1 << 1)).U(XLEN.W) 32044f8e3e4Speixiaokun val mieWMask = mip_mie_WMask_H | "haaa".U(XLEN.W) 321d0de7e4aSpeixiaokun 32267ba96b4SYinan Xu def getMisaMxl(mxl: BigInt): BigInt = mxl << (XLEN - 2) 32367ba96b4SYinan Xu def getMisaExt(ext: Char): Long = 1 << (ext.toInt - 'a'.toInt) 324c84054caSLinJiawei var extList = List('a', 's', 'i', 'u') 325c84054caSLinJiawei if (HasMExtension) { extList = extList :+ 'm' } 326c84054caSLinJiawei if (HasCExtension) { extList = extList :+ 'c' } 327d0de7e4aSpeixiaokun if (HasHExtension) { extList = extList :+ 'h' } 328c84054caSLinJiawei if (HasFPU) { extList = extList ++ List('f', 'd') } 3290ba52110SZiyue Zhang if (HasVPU) { extList = extList :+ 'v' } 330d0de7e4aSpeixiaokun val misaInitVal = getMisaMxl(2) | extList.foldLeft(0L)((sum, i) => sum | getMisaExt(i)) //"h8000000000141185".U 33167ba96b4SYinan Xu val misa = RegInit(UInt(XLEN.W), misaInitVal.U) 332ddb6dcf0SXuan Hu println(s"[CSR] supported isa ext: $extList") 333bc5ff277Swangkaifan 334c84054caSLinJiawei // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 335c84054caSLinJiawei // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 336c84054caSLinJiawei 33706490c40Speixiaokun // Machine Configuration 33806490c40Speixiaokun val menvcfg = RegInit(UInt(XLEN.W), 0.U) 33906490c40Speixiaokun 340c84054caSLinJiawei val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 341e1b773eaSLuo 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 342c84054caSLinJiawei val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 34367ba96b4SYinan Xu val mhartid = Reg(UInt(XLEN.W)) // the hardware thread running the code 34467ba96b4SYinan Xu when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 34567ba96b4SYinan Xu mhartid := csrio.hartId 34667ba96b4SYinan Xu } 3477d9edc86SLemover val mconfigptr = RegInit(UInt(XLEN.W), 0.U) // the read-only pointer pointing to the platform config structure, 0 for not supported. 34862a2cb19SXuan Hu val mstatus = RegInit("ha00002200".U(XLEN.W)) 349bc5ff277Swangkaifan 350c84054caSLinJiawei // mstatus Value Table 35162a2cb19SXuan Hu // | sd | Read Only 35262a2cb19SXuan Hu // | pad1 | WPRI 353c84054caSLinJiawei // | sxl | hardlinked to 10, use 00 to pass xv6 test 354e30fd06aSYinan Xu // | uxl | hardlinked to 10 355c84054caSLinJiawei // | pad0 | 356c84054caSLinJiawei // | tsr | 357c84054caSLinJiawei // | tw | 3588e7b11e5SWilliam Wang // | tvm | 359c84054caSLinJiawei // | mxr | 360c84054caSLinJiawei // | sum | 361c84054caSLinJiawei // | mprv | 362c84054caSLinJiawei // | xs | 00 | 36380dd83d8SYinan Xu // | fs | 01 | 364c84054caSLinJiawei // | mpp | 00 | 36562a2cb19SXuan Hu // | vs | 01 | 366c84054caSLinJiawei // | spp | 0 | 3678e7b11e5SWilliam Wang // | pie | 0000 | pie.h is used as UBE 368c84054caSLinJiawei // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 369bc5ff277Swangkaifan 370c84054caSLinJiawei val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 371c84054caSLinJiawei def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 372c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 37362a2cb19SXuan Hu // Cat(sd, other) 37462a2cb19SXuan Hu val mstatusNew = Cat( 37562a2cb19SXuan Hu mstatusOld.xs === ContextStatus.dirty || mstatusOld.fs === ContextStatus.dirty || mstatusOld.vs === ContextStatus.dirty, 37662a2cb19SXuan Hu mstatus(XLEN-2, 0) 37762a2cb19SXuan Hu ) 378c84054caSLinJiawei mstatusNew 379c84054caSLinJiawei } 38085052be5Speixiaokun def vsstatusUpdateSideEffect(vsstatus: UInt): UInt = { 38185052be5Speixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 38285052be5Speixiaokun val vsstatusNew = Cat(vsstatusOld.xs === "b11".U || vsstatusOld.fs === "b11".U, vsstatus(XLEN-2, 0)) 38385052be5Speixiaokun vsstatusNew 38485052be5Speixiaokun } 385e30fd06aSYinan Xu val mstatusWMask = (~ZeroExt(( 38662a2cb19SXuan Hu GenMask(63) | // SD is read-only 3872c64ad7cSXiaokun-Pei (if(HasHExtension) 3882c64ad7cSXiaokun-Pei GenMask(62, 40) // WPRI 3892c64ad7cSXiaokun-Pei else 3902c64ad7cSXiaokun-Pei GenMask(62, 38) )| // WPRI 391e30fd06aSYinan Xu GenMask(35, 32) | // SXL and UXL cannot be changed 392e30fd06aSYinan Xu GenMask(31, 23) | // WPRI 393705cbec3SLemover GenMask(16, 15) | // XS is read-only 394443741b9SYinan Xu GenMask(6) | // UBE, always little-endian (0) 395443741b9SYinan Xu GenMask(4) | // WPRI 396443741b9SYinan Xu GenMask(2) | // WPRI 397443741b9SYinan Xu GenMask(0) // WPRI 3985d669833SYinan Xu ), 64)).asUInt 3998e7b11e5SWilliam Wang 400c84054caSLinJiawei val medeleg = RegInit(UInt(XLEN.W), 0.U) 401d0de7e4aSpeixiaokun val midelegInit = if(HasHExtension){((1 << 12) | (1 << 10) | (1 << 6) | (1 << 2)).U}else{0.U} 402d0de7e4aSpeixiaokun val medelegWMask = if(HasHExtension) { 403e20ac1e1Sxuzefan "hf0b7ff".U(XLEN.W) 404d0de7e4aSpeixiaokun }else { 405d0de7e4aSpeixiaokun "hb3ff".U(XLEN.W) 406d0de7e4aSpeixiaokun } 407d0de7e4aSpeixiaokun 408d0de7e4aSpeixiaokun 409d0de7e4aSpeixiaokun val mideleg = RegInit(UInt(XLEN.W), midelegInit) 410c84054caSLinJiawei val mscratch = RegInit(UInt(XLEN.W), 0.U) 411c84054caSLinJiawei 412d0de7e4aSpeixiaokun val midelegWMask = "h222".U(XLEN.W) 413b6982e83SLemover // PMP Mapping 414ca2f90a6SLemover val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter 415ca2f90a6SLemover val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter 416ca2f90a6SLemover val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp) 417ca2f90a6SLemover val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma) 418672c4648Sceba // !WARNNING: pmp and pma CSRs are not checked in difftest. 419c84054caSLinJiawei 420d0de7e4aSpeixiaokun // Supervisor-Level CSRs 421c84054caSLinJiawei 42262a2cb19SXuan Hu val sstatusWNmask: BigInt = ( 42362a2cb19SXuan Hu BigIntGenMask(63) | // SD is read-only 42462a2cb19SXuan Hu BigIntGenMask(62, 34) | // WPRI 42562a2cb19SXuan Hu BigIntGenMask(33, 32) | // UXL is hard-wired to 64(b10) 42662a2cb19SXuan Hu BigIntGenMask(31, 20) | // WPRI 42762a2cb19SXuan Hu BigIntGenMask(17) | // WPRI 42862a2cb19SXuan Hu BigIntGenMask(16, 15) | // XS is read-only to zero 42962a2cb19SXuan Hu BigIntGenMask(12, 11) | // WPRI 43062a2cb19SXuan Hu BigIntGenMask(7) | // WPRI 43162a2cb19SXuan Hu BigIntGenMask(6) | // UBE is always little-endian (0) 43262a2cb19SXuan Hu BigIntGenMask(4, 2) | // WPRI 43362a2cb19SXuan Hu BigIntGenMask(0) // WPRI 43462a2cb19SXuan Hu ) 43562a2cb19SXuan Hu 43662a2cb19SXuan Hu val sstatusWmask = BigIntNot(sstatusWNmask).U(XLEN.W) 43762a2cb19SXuan Hu val sstatusRmask = ( 43862a2cb19SXuan Hu BigIntGenMask(63) | // SD 43962a2cb19SXuan Hu BigIntGenMask(33, 32) | // UXL 44062a2cb19SXuan Hu BigIntGenMask(19) | // MXR 44162a2cb19SXuan Hu BigIntGenMask(18) | // SUM 44262a2cb19SXuan Hu BigIntGenMask(16, 15) | // XS 44362a2cb19SXuan Hu BigIntGenMask(14, 13) | // FS 44462a2cb19SXuan Hu BigIntGenMask(10, 9 ) | // VS 44562a2cb19SXuan Hu BigIntGenMask(8) | // SPP 44662a2cb19SXuan Hu BigIntGenMask(6) | // UBE: hard wired to 0 44762a2cb19SXuan Hu BigIntGenMask(5) | // SPIE 44862a2cb19SXuan Hu BigIntGenMask(1) 44962a2cb19SXuan Hu ).U(XLEN.W) 45062a2cb19SXuan Hu 45162a2cb19SXuan Hu println(s"sstatusWNmask: 0x${sstatusWNmask.toString(16)}") 45262a2cb19SXuan Hu println(s"sstatusWmask: 0x${sstatusWmask.litValue.toString(16)}") 45362a2cb19SXuan Hu println(s"sstatusRmask: 0x${sstatusRmask.litValue.toString(16)}") 45462a2cb19SXuan Hu 455a4e57ea3SLi Qianruo // stvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 456a4e57ea3SLi Qianruo val stvecMask = ~(0x2.U(XLEN.W)) 457c84054caSLinJiawei val stvec = RegInit(UInt(XLEN.W), 0.U) 458c84054caSLinJiawei // val sie = RegInit(0.U(XLEN.W)) 459c84054caSLinJiawei val sieMask = "h222".U & mideleg 460c84054caSLinJiawei val sipMask = "h222".U & mideleg 4615dabf2dfSYinan Xu val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode 46234230194Sjinyue110 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 463df2b1479SZhangZifei // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 46445f497a4Shappy-lx // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0 46545f497a4Shappy-lx // TODO: use config to control the length of asid 46645f497a4Shappy-lx // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0 467705cbec3SLemover val satpMask = Cat("h8".U(Satp_Mode_len.W), satp_part_wmask(Satp_Asid_len, AsidLength), satp_part_wmask(Satp_Addr_len, PAddrBits-12)) 468c84054caSLinJiawei val sepc = RegInit(UInt(XLEN.W), 0.U) 469e30fd06aSYinan Xu // Page 60 in riscv-priv: The low bit of sepc (sepc[0]) is always zero. 470e30fd06aSYinan Xu val sepcMask = ~(0x1.U(XLEN.W)) 471c84054caSLinJiawei val scause = RegInit(UInt(XLEN.W), 0.U) 472d0de7e4aSpeixiaokun val stval = RegInit(UInt(XLEN.W), 0.U) 473c84054caSLinJiawei val sscratch = RegInit(UInt(XLEN.W), 0.U) 474c84054caSLinJiawei val scounteren = RegInit(UInt(XLEN.W), 0.U) 4756ade72d9Sxuzefan val senvcfg = RegInit(UInt(XLEN.W), 0.U) // !WARNING: there is no logic about this CSR. 476e4b1ccacSxuzefan // Currently, XiangShan don't support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 477e4b1ccacSxuzefan val scounterenMask = 0.U(XLEN.W) 478fcff7e94SZhangZifei 479eedc2e58SSteve Gou // sbpctl 480eedc2e58SSteve Gou // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB} 481eedc2e58SSteve Gou val sbpctl = RegInit(UInt(XLEN.W), "h7f".U) 482eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0) 483eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.btb_enable := sbpctl(1) 484eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.bim_enable := sbpctl(2) 485eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3) 486eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.sc_enable := sbpctl(4) 487eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ras_enable := sbpctl(5) 488eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6) 4892b8b2e7aSWilliam Wang 490ecccf78fSJay // spfctl Bit 0: L1I Cache Prefetcher Enable 4912b8b2e7aSWilliam Wang // spfctl Bit 1: L2Cache Prefetcher Enable 49285de5caeSLinJiawei // spfctl Bit 2: L1D Cache Prefetcher Enable 49385de5caeSLinJiawei // spfctl Bit 3: L1D train prefetch on hit 49485de5caeSLinJiawei // spfctl Bit 4: L1D prefetch enable agt 49585de5caeSLinJiawei // spfctl Bit 5: L1D prefetch enable pht 496c65495a4SLinJiawei // spfctl Bit [9:6]: L1D prefetch active page threshold 497c65495a4SLinJiawei // spfctl Bit [15:10]: L1D prefetch active page stride 4985d13017eSLinJiawei // turn off L2 BOP, turn on L1 SMS by default 499c65495a4SLinJiawei val spfctl = RegInit(UInt(XLEN.W), Seq( 500edbf1204SLinJiawei 0 << 17, // L2 pf store only [17] init: false 501edbf1204SLinJiawei 1 << 16, // L1D pf enable stride [16] init: true 502f1d78cf7SLinJiawei 30 << 10, // L1D active page stride [15:10] init: 30 503f1d78cf7SLinJiawei 12 << 6, // L1D active page threshold [9:6] init: 12 504f1d78cf7SLinJiawei 1 << 5, // L1D enable pht [5] init: true 505f1d78cf7SLinJiawei 1 << 4, // L1D enable agt [4] init: true 506f1d78cf7SLinJiawei 0 << 3, // L1D train on hit [3] init: false 507f1d78cf7SLinJiawei 1 << 2, // L1D pf enable [2] init: true 508f1d78cf7SLinJiawei 1 << 1, // L2 pf enable [1] init: true 509f1d78cf7SLinJiawei 1 << 0, // L1I pf enable [0] init: true 510c65495a4SLinJiawei ).reduce(_|_).U(XLEN.W)) 511ecccf78fSJay csrio.customCtrl.l1I_pf_enable := spfctl(0) 51235a47a38SYinan Xu csrio.customCtrl.l2_pf_enable := spfctl(1) 51385de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable := spfctl(2) 51485de5caeSLinJiawei csrio.customCtrl.l1D_pf_train_on_hit := spfctl(3) 51585de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable_agt := spfctl(4) 51685de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable_pht := spfctl(5) 5175d13017eSLinJiawei csrio.customCtrl.l1D_pf_active_threshold := spfctl(9, 6) 518c65495a4SLinJiawei csrio.customCtrl.l1D_pf_active_stride := spfctl(15, 10) 519edbf1204SLinJiawei csrio.customCtrl.l1D_pf_enable_stride := spfctl(16) 520edbf1204SLinJiawei csrio.customCtrl.l2_pf_store_only := spfctl(17) 5212b8b2e7aSWilliam Wang 5222b8b2e7aSWilliam Wang // slvpredctl: load violation predict settings 5236ef4f6f6SYinan Xu // Default reset period: 2^16 5246ef4f6f6SYinan Xu // Why this number: reset more frequently while keeping the overhead low 5256ef4f6f6SYinan Xu // Overhead: extra two redirections in every 64K cycles => ~0.1% overhead 526560b69b7SHaojin Tang val slvpredctl = Reg(UInt(XLEN.W)) 527560b69b7SHaojin Tang when(reset.asBool) { 528c686adcdSYinan Xu slvpredctl := Constantin.createRecord("slvpredctl", 0x60) 529560b69b7SHaojin Tang } 5302b8b2e7aSWilliam Wang csrio.customCtrl.lvpred_disable := slvpredctl(0) 5312b8b2e7aSWilliam Wang csrio.customCtrl.no_spec_load := slvpredctl(1) 532c7160cd3SWilliam Wang csrio.customCtrl.storeset_wait_store := slvpredctl(2) 533c7160cd3SWilliam Wang csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3) 534c7160cd3SWilliam Wang csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4) 5352b8b2e7aSWilliam Wang 536f3f22d72SYinan Xu // smblockctl: memory block configurations 53741d8d239Shappy-lx // +------------------------+---+---+---+----+----+-----+--------+ 53841d8d239Shappy-lx // |XLEN-1 10| 9 | 8 | 7 | 6 | 5 | 4 |3 0| 53941d8d239Shappy-lx // +------------------------+---+---+---+----+----+-----+--------+ 54041d8d239Shappy-lx // | Reserved | L | S | O | CE | SP | LVC | Th | 54141d8d239Shappy-lx // +------------------------+---+---+---+----+----+-----+--------+ 54237225120Ssfencevma // Description: 54337225120Ssfencevma // Bit 3-0 : Store buffer flush threshold (Th). 54437225120Ssfencevma // Bit 4 : Enable load violation check after reset (LVC). 54537225120Ssfencevma // Bit 5 : Enable soft-prefetch after reset (SP). 54637225120Ssfencevma // Bit 6 : Enable cache error after reset (CE). 54737225120Ssfencevma // Bit 7 : Enable uncache write outstanding (O). 54841d8d239Shappy-lx // Bit 8 : Enable unaligned store (S). 54941d8d239Shappy-lx // Bit 9 : Enable unaligned load (L). 55037225120Ssfencevma // Others : Reserved. 55137225120Ssfencevma 55267682d05SWilliam Wang val smblockctl_init_val = 55367ba96b4SYinan Xu (0xf & StoreBufferThreshold) | 55467ba96b4SYinan Xu (EnableLdVioCheckAfterReset.toInt << 4) | 55567ba96b4SYinan Xu (EnableSoftPrefetchAfterReset.toInt << 5) | 556dcfaba1dSczw (EnableCacheErrorAfterReset.toInt << 6) | 55741d8d239Shappy-lx (EnableUncacheWriteOutstanding.toInt << 7) | 55841d8d239Shappy-lx (EnableHardwareStoreMisalign.toInt << 8) | 55941d8d239Shappy-lx (EnableHardwareLoadMisalign.toInt << 9) 56067ba96b4SYinan Xu val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val.U) 561f3f22d72SYinan Xu csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0) 56267682d05SWilliam Wang // bits 4: enable load load violation check 563a4e57ea3SLi Qianruo csrio.customCtrl.ldld_vio_check_enable := smblockctl(4) 564a4e57ea3SLi Qianruo csrio.customCtrl.soft_prefetch_enable := smblockctl(5) 565a4e57ea3SLi Qianruo csrio.customCtrl.cache_error_enable := smblockctl(6) 56637225120Ssfencevma csrio.customCtrl.uncache_write_outstanding_enable := smblockctl(7) 56741d8d239Shappy-lx csrio.customCtrl.hd_misalign_st_enable := smblockctl(8) 56841d8d239Shappy-lx csrio.customCtrl.hd_misalign_ld_enable := smblockctl(9) 569a4e57ea3SLi Qianruo 570a4e57ea3SLi Qianruo println("CSR smblockctl init value:") 571a4e57ea3SLi Qianruo println(" Store buffer replace threshold: " + StoreBufferThreshold) 572a4e57ea3SLi Qianruo println(" Enable ld-ld vio check after reset: " + EnableLdVioCheckAfterReset) 573a4e57ea3SLi Qianruo println(" Enable soft prefetch after reset: " + EnableSoftPrefetchAfterReset) 574a4e57ea3SLi Qianruo println(" Enable cache error after reset: " + EnableCacheErrorAfterReset) 57537225120Ssfencevma println(" Enable uncache write outstanding: " + EnableUncacheWriteOutstanding) 57641d8d239Shappy-lx println(" Enable unaligned store: " + EnableHardwareStoreMisalign) 57741d8d239Shappy-lx println(" Enable unaligned load: " + EnableHardwareLoadMisalign) 578f3f22d72SYinan Xu 5795b47c58cSYinan Xu val srnctl = RegInit(UInt(XLEN.W), "h7".U) 5805b47c58cSYinan Xu csrio.customCtrl.fusion_enable := srnctl(0) 5815b47c58cSYinan Xu csrio.customCtrl.wfi_enable := srnctl(2) 582aac4464eSYinan Xu 583d0de7e4aSpeixiaokun // Hypervisor CSRs 584d0de7e4aSpeixiaokun val hstatusWMask = "h7003c0".U(XLEN.W) 585d0de7e4aSpeixiaokun // hstatus: vtsr, vtw, vtvm, hu, spvp, spv, gva, 586d0de7e4aSpeixiaokun val hstatus = RegInit("h200000000".U(XLEN.W)) 587d0de7e4aSpeixiaokun val hstatusStruct = hstatus.asTypeOf(new HstatusStruct) 588d0de7e4aSpeixiaokun val hedeleg = RegInit(UInt(XLEN.W), 0.U) 589d0de7e4aSpeixiaokun val hideleg = RegInit(UInt(XLEN.W), 0.U) 590d0de7e4aSpeixiaokun val hidelegRMask = mideleg 591d0de7e4aSpeixiaokun val hidelegWMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 592d0de7e4aSpeixiaokun val hgeie = RegInit(UInt(XLEN.W), 0.U) 593d0de7e4aSpeixiaokun val htval = RegInit(UInt(XLEN.W), 0.U) 594d0de7e4aSpeixiaokun // hvip hip hie is part of mip or mie 595d0de7e4aSpeixiaokun val hvipMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 596d0de7e4aSpeixiaokun val hipRMask = (((1 << 12).U | hvipMask) & mideleg) 597d0de7e4aSpeixiaokun val hipWMask = ((1 << 2).U & mideleg)// vssip 598d0de7e4aSpeixiaokun val hieMask = hipRMask 599d0de7e4aSpeixiaokun val htinst = RegInit(UInt(XLEN.W), 0.U) 600d0de7e4aSpeixiaokun val hgeip = RegInit(UInt(XLEN.W), 0.U) 601d0de7e4aSpeixiaokun val henvcfg = RegInit(UInt(XLEN.W), 0.U) 602d0de7e4aSpeixiaokun val hgatp = RegInit(UInt(XLEN.W), 0.U) 603d0de7e4aSpeixiaokun val hgatpMask = Cat("h8".U(Hgatp_Mode_len.W), satp_part_wmask(Hgatp_Vmid_len, VmidLength), satp_part_wmask(Hgatp_Addr_len, PAddrBits-12)) 604a13f171cSXu, Zefan // val htimedelta = RegInit(UInt(XLEN.W), 0.U) 605d0de7e4aSpeixiaokun val hcounteren = RegInit(UInt(XLEN.W), 0.U) 606e4b1ccacSxuzefan // Currently, XiangShan don't support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 607e4b1ccacSxuzefan val hcounterenMask = 0.U(XLEN.W) 608d0de7e4aSpeixiaokun 609f2a38010Sxuzefan val vsstatus = RegInit("h200002000".U(XLEN.W)) 610d0de7e4aSpeixiaokun val vsstatusStruct = vsstatus.asTypeOf(new MstatusStruct) 611d0de7e4aSpeixiaokun //vsie vsip 612d0de7e4aSpeixiaokun val vsMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 613d0de7e4aSpeixiaokun val vsip_ie_Mask = ZeroExt((hideleg & mideleg & vsMask), XLEN) 614d0de7e4aSpeixiaokun val vsip_WMask = ZeroExt((hideleg & mideleg & vssip_Mask), XLEN) 615d0de7e4aSpeixiaokun val vstvec = RegInit(UInt(XLEN.W), 0.U) 616d0de7e4aSpeixiaokun val vsscratch = RegInit(UInt(XLEN.W), 0.U) 617d0de7e4aSpeixiaokun val vsepc = RegInit(UInt(XLEN.W), 0.U) 618d0de7e4aSpeixiaokun val vscause = RegInit(UInt(XLEN.W), 0.U) 619d0de7e4aSpeixiaokun val vstval = RegInit(UInt(XLEN.W), 0.U) 620d0de7e4aSpeixiaokun val vsatp = RegInit(UInt(XLEN.W), 0.U) 6212b8b2e7aSWilliam Wang val tlbBundle = Wire(new TlbCsrBundle) 62245f497a4Shappy-lx tlbBundle.satp.apply(satp) 623d0de7e4aSpeixiaokun tlbBundle.vsatp.apply(vsatp) 624d0de7e4aSpeixiaokun tlbBundle.hgatp.apply(hgatp) 6252b8b2e7aSWilliam Wang csrio.tlb := tlbBundle 6262b8b2e7aSWilliam Wang 627c84054caSLinJiawei // User-Level CSRs 628c84054caSLinJiawei val uepc = Reg(UInt(XLEN.W)) 629c84054caSLinJiawei 630c84054caSLinJiawei // fcsr 631c84054caSLinJiawei class FcsrStruct extends Bundle { 632c84054caSLinJiawei val reserved = UInt((XLEN-3-5).W) 633c84054caSLinJiawei val frm = UInt(3.W) 634c84054caSLinJiawei val fflags = UInt(5.W) 635c84054caSLinJiawei assert(this.getWidth == XLEN) 636c84054caSLinJiawei } 637c84054caSLinJiawei val fcsr = RegInit(0.U(XLEN.W)) 638c84054caSLinJiawei // set mstatus->sd and mstatus->fs when true 639c84054caSLinJiawei val csrw_dirty_fp_state = WireInit(false.B) 640c84054caSLinJiawei 641c84054caSLinJiawei def frm_wfn(wdata: UInt): UInt = { 642c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 643c84054caSLinJiawei csrw_dirty_fp_state := true.B 644c84054caSLinJiawei fcsrOld.frm := wdata(2,0) 6455d669833SYinan Xu fcsrOld.asUInt 646c84054caSLinJiawei } 647c84054caSLinJiawei def frm_rfn(rdata: UInt): UInt = rdata(7,5) 648c84054caSLinJiawei 6497132faa5SLinJiawei def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 6507132faa5SLinJiawei val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 6517132faa5SLinJiawei val fcsrNew = WireInit(fcsrOld) 6527132faa5SLinJiawei if (update) { 6537132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 6547132faa5SLinJiawei } else { 6557132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) 6567132faa5SLinJiawei } 6575d669833SYinan Xu fcsrNew.asUInt 658c84054caSLinJiawei } 659c84054caSLinJiawei def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 660c84054caSLinJiawei 661c84054caSLinJiawei def fcsr_wfn(wdata: UInt): UInt = { 662c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 663c84054caSLinJiawei csrw_dirty_fp_state := true.B 664c84054caSLinJiawei Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 665c84054caSLinJiawei } 666c84054caSLinJiawei 667c84054caSLinJiawei val fcsrMapping = Map( 6687132faa5SLinJiawei MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 669c84054caSLinJiawei MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 670c84054caSLinJiawei MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 671c84054caSLinJiawei ) 672c84054caSLinJiawei 6730ba52110SZiyue Zhang // Vector extension CSRs 6747f733d3dSxiaofeibao-xjtu val vstart = RegInit(0.U(XLEN.W)) 6750ba52110SZiyue Zhang val vcsr = RegInit(0.U(XLEN.W)) 6760ba52110SZiyue Zhang val vl = Reg(UInt(XLEN.W)) 6770ba52110SZiyue Zhang val vtype = Reg(UInt(XLEN.W)) 6785f28e666Schengguanghui val vlenb = RegInit(VDataBytes.U(XLEN.W)) 679daa01159SZiyue Zhang 680daa01159SZiyue Zhang // set mstatus->sd and mstatus->vs when true 681daa01159SZiyue Zhang val csrw_dirty_vs_state = WireInit(false.B) 6820ba52110SZiyue Zhang 6830ba52110SZiyue Zhang // vcsr is mapped to vxrm and vxsat 6840ba52110SZiyue Zhang class VcsrStruct extends Bundle { 6850ba52110SZiyue Zhang val reserved = UInt((XLEN-3).W) 6860ba52110SZiyue Zhang val vxrm = UInt(2.W) 6870ba52110SZiyue Zhang val vxsat = UInt(1.W) 6880ba52110SZiyue Zhang assert(this.getWidth == XLEN) 6890ba52110SZiyue Zhang } 6900ba52110SZiyue Zhang 6910ba52110SZiyue Zhang def vxrm_wfn(wdata: UInt): UInt = { 6920ba52110SZiyue Zhang val vcsrOld = WireInit(vcsr.asTypeOf(new VcsrStruct)) 693daa01159SZiyue Zhang csrw_dirty_vs_state := true.B 6940ba52110SZiyue Zhang vcsrOld.vxrm := wdata(1,0) 6950ba52110SZiyue Zhang vcsrOld.asUInt 6960ba52110SZiyue Zhang } 6970ba52110SZiyue Zhang def vxrm_rfn(rdata: UInt): UInt = rdata(2,1) 6980ba52110SZiyue Zhang 6996355a2b7Sczw def vxsat_wfn(update: Boolean)(wdata: UInt): UInt = { 7000ba52110SZiyue Zhang val vcsrOld = WireInit(vcsr.asTypeOf(new VcsrStruct)) 7016355a2b7Sczw val vcsrNew = WireInit(vcsrOld) 702daa01159SZiyue Zhang csrw_dirty_vs_state := true.B 7036355a2b7Sczw if (update) { 7046355a2b7Sczw vcsrNew.vxsat := wdata(0) | vcsrOld.vxsat 7056355a2b7Sczw } else { 7066355a2b7Sczw vcsrNew.vxsat := wdata(0) 7076355a2b7Sczw } 7086355a2b7Sczw vcsrNew.asUInt 7090ba52110SZiyue Zhang } 7100ba52110SZiyue Zhang def vxsat_rfn(rdata: UInt): UInt = rdata(0) 7110ba52110SZiyue Zhang 7120ba52110SZiyue Zhang def vcsr_wfn(wdata: UInt): UInt = { 7130ba52110SZiyue Zhang val vcsrOld = WireInit(vcsr.asTypeOf(new VcsrStruct)) 714daa01159SZiyue Zhang csrw_dirty_vs_state := true.B 7150ba52110SZiyue Zhang vcsrOld.vxrm := wdata.asTypeOf(vcsrOld).vxrm 7160ba52110SZiyue Zhang vcsrOld.vxsat := wdata.asTypeOf(vcsrOld).vxsat 7170ba52110SZiyue Zhang vcsrOld.asUInt 7180ba52110SZiyue Zhang } 7190ba52110SZiyue Zhang 7200ba52110SZiyue Zhang val vcsrMapping = Map( 7210ba52110SZiyue Zhang MaskedRegMap(Vstart, vstart), 7220ba52110SZiyue Zhang MaskedRegMap(Vxrm, vcsr, wfn = vxrm_wfn, rfn = vxrm_rfn), 7236355a2b7Sczw MaskedRegMap(Vxsat, vcsr, wfn = vxsat_wfn(false), rfn = vxsat_rfn), 7240ba52110SZiyue Zhang MaskedRegMap(Vcsr, vcsr, wfn = vcsr_wfn), 7250ba52110SZiyue Zhang MaskedRegMap(Vl, vl), 72635d1557aSZiyue Zhang MaskedRegMap(Vtype, vtype), 72735d1557aSZiyue Zhang MaskedRegMap(Vlenb, vlenb), 7280ba52110SZiyue Zhang ) 7290ba52110SZiyue Zhang 730321934c7SKunlin You // Hart Privilege Mode 731321934c7SKunlin You val privilegeMode = RegInit(UInt(2.W), ModeM) 732c84054caSLinJiawei 733cd365d4cSrvcoresjw //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool()))) 7348635f18fSwangkaifan // Perf Counter 7358635f18fSwangkaifan val nrPerfCnts = 29 // 3...31 736321934c7SKunlin You val privilegeModeOH = UIntToOH(privilegeMode) 737cd365d4cSrvcoresjw val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool()))) 7388635f18fSwangkaifan val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 7398c7b0b2fSrvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 74012c44ce5Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 74112c44ce5Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 74212c44ce5Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 743cd365d4cSrvcoresjw for (i <-0 until nrPerfCnts) { 744321934c7SKunlin You perfEventscounten(i) := (perfEvents(i)(63,60) & privilegeModeOH).orR 745cd365d4cSrvcoresjw } 746cd365d4cSrvcoresjw 7471ca0e4f3SYinan Xu val hpmEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 748cd365d4cSrvcoresjw for (i <- 0 until numPCntHc * coreParams.L2NBanks) { 7491ca0e4f3SYinan Xu hpmEvents(i) := csrio.perf.perfEventsHc(i) 750cd365d4cSrvcoresjw } 751cd365d4cSrvcoresjw 7529a128342SHaoyuan Feng // print perfEvents 7539a128342SHaoyuan Feng val allPerfEvents = hpmEvents.map(x => (s"Hc", x.value)) 7549a128342SHaoyuan Feng if (printEventCoding) { 7559a128342SHaoyuan Feng for (((name, inc), i) <- allPerfEvents.zipWithIndex) { 7569a128342SHaoyuan Feng println("CSR perfEvents Set", name, inc, i) 7579a128342SHaoyuan Feng } 7589a128342SHaoyuan Feng } 7599a128342SHaoyuan Feng 76012c44ce5Srvcoresjw val csrevents = perfEvents.slice(24, 29) 7611ca0e4f3SYinan Xu val hpm_hc = HPerfMonitor(csrevents, hpmEvents) 7628635f18fSwangkaifan val mcountinhibit = RegInit(0.U(XLEN.W)) 763b03ddc86Swangkaifan val mcycle = RegInit(0.U(XLEN.W)) 764b03ddc86Swangkaifan mcycle := mcycle + 1.U 765b03ddc86Swangkaifan val minstret = RegInit(0.U(XLEN.W)) 7661ca0e4f3SYinan Xu val perf_events = csrio.perf.perfEventsFrontend ++ 767e1a85e9fSchengguanghui csrio.perf.perfEventsBackend ++ 7681ca0e4f3SYinan Xu csrio.perf.perfEventsLsu ++ 7691ca0e4f3SYinan Xu hpm_hc.getPerf 770b03ddc86Swangkaifan minstret := minstret + RegNext(csrio.perf.retiredInstr) 7715fd90906Srvcoresjw for(i <- 0 until 29){ 7721ca0e4f3SYinan Xu perfCnts(i) := Mux(mcountinhibit(i+3) | !perfEventscounten(i), perfCnts(i), perfCnts(i) + perf_events(i).value) 7735fd90906Srvcoresjw } 7748635f18fSwangkaifan 775c84054caSLinJiawei // CSR reg map 77621fa8708Swangkaifan val basicPrivMapping = Map( 777c84054caSLinJiawei 778f7af4c74Schengguanghui // Unprivileged Floating-Point CSRs 779f7af4c74Schengguanghui // Has been mapped above 780c84054caSLinJiawei 781e4b1ccacSxuzefan // TODO: support Unprivileged Counter/Timers CSRs ("Zicntr" and "Zihpm") 782f7af4c74Schengguanghui // Unprivileged Counter/Timers 783f7af4c74Schengguanghui MaskedRegMap(Cycle, mcycle), 784f7af4c74Schengguanghui // We don't support read time CSR. 785f7af4c74Schengguanghui // MaskedRegMap(Time, mtime), 786f7af4c74Schengguanghui MaskedRegMap(Instret, minstret), 787c84054caSLinJiawei 78821fa8708Swangkaifan //--- Supervisor Trap Setup --- 789c84054caSLinJiawei MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 790c84054caSLinJiawei // MaskedRegMap(Sedeleg, Sedeleg), 791c84054caSLinJiawei // MaskedRegMap(Sideleg, Sideleg), 792c84054caSLinJiawei MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 793a4e57ea3SLi Qianruo MaskedRegMap(Stvec, stvec, stvecMask, MaskedRegMap.NoSideEffect, stvecMask), 794e4b1ccacSxuzefan MaskedRegMap(Scounteren, scounteren, scounterenMask), 795c84054caSLinJiawei 7966ade72d9Sxuzefan //--- Supervisor Configuration --- 7976ade72d9Sxuzefan MaskedRegMap(Senvcfg, senvcfg), 7986ade72d9Sxuzefan 79921fa8708Swangkaifan //--- Supervisor Trap Handling --- 800c84054caSLinJiawei MaskedRegMap(Sscratch, sscratch), 801e30fd06aSYinan Xu MaskedRegMap(Sepc, sepc, sepcMask, MaskedRegMap.NoSideEffect, sepcMask), 802c84054caSLinJiawei MaskedRegMap(Scause, scause), 803c84054caSLinJiawei MaskedRegMap(Stval, stval), 8045390caa7Speixiaokun MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask, x => (mipWire.asUInt | x) & sipMask), 805c84054caSLinJiawei 80621fa8708Swangkaifan //--- Supervisor Protection and Translation --- 807c5334b11SZhangZifei MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 808c84054caSLinJiawei 80935a47a38SYinan Xu //--- Supervisor Custom Read/Write Registers 810eedc2e58SSteve Gou MaskedRegMap(Sbpctl, sbpctl), 81135a47a38SYinan Xu MaskedRegMap(Spfctl, spfctl), 8122b8b2e7aSWilliam Wang MaskedRegMap(Slvpredctl, slvpredctl), 813f3f22d72SYinan Xu MaskedRegMap(Smblockctl, smblockctl), 814aac4464eSYinan Xu MaskedRegMap(Srnctl, srnctl), 81535a47a38SYinan Xu 81621fa8708Swangkaifan //--- Machine Information Registers --- 8175dabf2dfSYinan Xu MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8185dabf2dfSYinan Xu MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8195dabf2dfSYinan Xu MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8205dabf2dfSYinan Xu MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8217d9edc86SLemover MaskedRegMap(Mconfigptr, mconfigptr, 0.U(XLEN.W), MaskedRegMap.Unwritable), 822c84054caSLinJiawei 82306490c40Speixiaokun //--- Machine Configuration Registers --- 82406490c40Speixiaokun MaskedRegMap(Menvcfg, menvcfg), 82506490c40Speixiaokun 82621fa8708Swangkaifan //--- Machine Trap Setup --- 827443741b9SYinan Xu MaskedRegMap(Mstatus, mstatus, mstatusWMask, mstatusUpdateSideEffect), 8285e4ec482SWilliam Wang MaskedRegMap(Misa, misa, 0.U, MaskedRegMap.Unwritable), // now whole misa is unchangeable 829d0de7e4aSpeixiaokun MaskedRegMap(Medeleg, medeleg, medelegWMask), 830b436d3b6Speixiaokun MaskedRegMap(Mideleg, mideleg, midelegWMask), 831b436d3b6Speixiaokun MaskedRegMap(Mie, mie, mieWMask), 832a4e57ea3SLi Qianruo MaskedRegMap(Mtvec, mtvec, mtvecMask, MaskedRegMap.NoSideEffect, mtvecMask), 833e4b1ccacSxuzefan MaskedRegMap(Mcounteren, mcounteren, mcounterenMask), 834c84054caSLinJiawei 83521fa8708Swangkaifan //--- Machine Trap Handling --- 836c84054caSLinJiawei MaskedRegMap(Mscratch, mscratch), 837e30fd06aSYinan Xu MaskedRegMap(Mepc, mepc, mepcMask, MaskedRegMap.NoSideEffect, mepcMask), 838c84054caSLinJiawei MaskedRegMap(Mcause, mcause), 839c84054caSLinJiawei MaskedRegMap(Mtval, mtval), 8405390caa7Speixiaokun MaskedRegMap(Mip, mipReg.asUInt, mipWMask, MaskedRegMap.NoSideEffect, mipMask, x => (mipWire.asUInt | x) & mipMask), 8416ade72d9Sxuzefan 84272951335SLi Qianruo //--- Trigger --- 843716f717fSLi Qianruo MaskedRegMap(Tselect, tselectPhy, WritableMask, WriteTselect), 844f7af4c74Schengguanghui // Todo: support chain length = 2 845f7af4c74Schengguanghui MaskedRegMap(Tdata1, tdata1RegVec(tselectPhy), 846f7af4c74Schengguanghui WritableMask, 847f7af4c74Schengguanghui x => Tdata1Bundle.Write(x, tdata1RegVec(tselectPhy), newTriggerChainIsLegal, debug_mode = debugMode), 848f7af4c74Schengguanghui WritableMask, 849f7af4c74Schengguanghui x => Tdata1Bundle.Read(x)), 850f7af4c74Schengguanghui MaskedRegMap(Tdata2, tdata2RegVec(tselectPhy)), 851716f717fSLi Qianruo MaskedRegMap(Tinfo, tinfo, 0.U(XLEN.W), MaskedRegMap.Unwritable), 85272951335SLi Qianruo 853d4aca96cSlqre //--- Debug Mode --- 854d4aca96cSlqre MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect), 855d4aca96cSlqre MaskedRegMap(Dpc, dpc), 856f7af4c74Schengguanghui MaskedRegMap(Dscratch0, dscratch0), 85712c44ce5Srvcoresjw MaskedRegMap(Dscratch1, dscratch1), 858b03ddc86Swangkaifan MaskedRegMap(Mcountinhibit, mcountinhibit), 859b03ddc86Swangkaifan MaskedRegMap(Mcycle, mcycle), 860b03ddc86Swangkaifan MaskedRegMap(Minstret, minstret), 861b03ddc86Swangkaifan ) 86212c44ce5Srvcoresjw 863d0de7e4aSpeixiaokun // hypervisor csr map 864d0de7e4aSpeixiaokun val hcsrMapping = Map( 865d0de7e4aSpeixiaokun //--- Hypervisor Trap Setup --- 866d0de7e4aSpeixiaokun MaskedRegMap(Hstatus, hstatus, hstatusWMask), 867d0de7e4aSpeixiaokun MaskedRegMap(Hedeleg, hedeleg), 868d0de7e4aSpeixiaokun MaskedRegMap(Hideleg, hideleg, hidelegWMask, MaskedRegMap.NoSideEffect, hidelegRMask), 869d0de7e4aSpeixiaokun MaskedRegMap(Hie, mie, hieMask, MaskedRegMap.NoSideEffect, hieMask), 870cc063a70Speixiaokun MaskedRegMap(Hcounteren, hcounteren, hcounterenMask), 871d0de7e4aSpeixiaokun MaskedRegMap(Hgeie, hgeie), 872d0de7e4aSpeixiaokun 873d0de7e4aSpeixiaokun //--- Hypervisor Trap Handling --- 874d0de7e4aSpeixiaokun MaskedRegMap(Htval, htval), 8755390caa7Speixiaokun MaskedRegMap(Hip, mipReg.asUInt, hipWMask, MaskedRegMap.NoSideEffect, hipRMask, x => (mipWire.asUInt | x) & hipRMask), 8765390caa7Speixiaokun MaskedRegMap(Hvip, mipReg.asUInt, hvipMask, MaskedRegMap.NoSideEffect, hvipMask, x => (mipWire.asUInt | x) & hvipMask), 877d0de7e4aSpeixiaokun MaskedRegMap(Htinst, htinst), 878d0de7e4aSpeixiaokun MaskedRegMap(Hgeip, hgeip), 879d0de7e4aSpeixiaokun 880d0de7e4aSpeixiaokun //--- Hypervisor Configuration --- 881d0de7e4aSpeixiaokun MaskedRegMap(Henvcfg, henvcfg), 882d0de7e4aSpeixiaokun 883d0de7e4aSpeixiaokun //--- Hypervisor Protection and Translation --- 884a1d4b4bfSpeixiaokun MaskedRegMap(Hgatp, hgatp, hgatpMask, MaskedRegMap.NoSideEffect, hgatpMask), 885d0de7e4aSpeixiaokun 886d0de7e4aSpeixiaokun //--- Hypervisor Counter/Timer Virtualization Registers --- 887a13f171cSXu, Zefan // MaskedRegMap(Htimedelta, htimedelta), 888d0de7e4aSpeixiaokun 889d0de7e4aSpeixiaokun //--- Virtual Supervisor Registers --- 89085052be5Speixiaokun MaskedRegMap(Vsstatus, vsstatus, rmask = sstatusRmask, wmask = sstatusWmask, wfn = vsstatusUpdateSideEffect), 891d0de7e4aSpeixiaokun MaskedRegMap(Vsie, mie, rmask = vsip_ie_Mask, wmask = vsip_ie_Mask), 892d0de7e4aSpeixiaokun MaskedRegMap(Vstvec, vstvec), 893d0de7e4aSpeixiaokun MaskedRegMap(Vsscratch, vsscratch), 894d0de7e4aSpeixiaokun MaskedRegMap(Vsepc, vsepc), 895d0de7e4aSpeixiaokun MaskedRegMap(Vscause, vscause), 896d0de7e4aSpeixiaokun MaskedRegMap(Vstval, vstval), 897d7e392d1Sxuzefan MaskedRegMap(Vsip, mipReg.asUInt, vsip_WMask, MaskedRegMap.NoSideEffect, vsip_ie_Mask, x => mipWire.asUInt | x), 898d0de7e4aSpeixiaokun MaskedRegMap(Vsatp, vsatp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 899d0de7e4aSpeixiaokun 900d0de7e4aSpeixiaokun //--- Machine Registers --- 901d0de7e4aSpeixiaokun MaskedRegMap(Mtval2, mtval2), 902d0de7e4aSpeixiaokun MaskedRegMap(Mtinst, mtinst), 903d0de7e4aSpeixiaokun ) 904d0de7e4aSpeixiaokun 90512c44ce5Srvcoresjw val perfCntMapping = (0 until 29).map(i => {Map( 90612c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmevent3 +i, 90712c44ce5Srvcoresjw reg = perfEvents(i), 90812c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)), 90912c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmcounter3 +i, 910f7af4c74Schengguanghui reg = perfCnts(i)), 911f7af4c74Schengguanghui MaskedRegMap(addr = Hpmcounter3 + i, 91212c44ce5Srvcoresjw reg = perfCnts(i)) 91312c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 9146d96ebcdSwakafa // TODO: mechanism should be implemented later 9156d96ebcdSwakafa // val MhpmcounterStart = Mhpmcounter3 9166d96ebcdSwakafa // val MhpmeventStart = Mhpmevent3 9176d96ebcdSwakafa // for (i <- 0 until nrPerfCnts) { 9186d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 9196d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 9206d96ebcdSwakafa // } 9218635f18fSwangkaifan 922e19f7967SWilliam Wang val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 923e19f7967SWilliam Wang name -> RegInit(0.U(attribute("width").toInt.W)) 924e19f7967SWilliam Wang }} 925ad3ba452Szhanglinjuan val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 926ad3ba452Szhanglinjuan MaskedRegMap( 927ad3ba452Szhanglinjuan Scachebase + attribute("offset").toInt, 928e19f7967SWilliam Wang cacheopRegs(name) 929ad3ba452Szhanglinjuan ) 930ad3ba452Szhanglinjuan }} 931b6982e83SLemover 93221fa8708Swangkaifan val mapping = basicPrivMapping ++ 9338635f18fSwangkaifan perfCntMapping ++ 93421fa8708Swangkaifan pmpMapping ++ 935ca2f90a6SLemover pmaMapping ++ 936ad3ba452Szhanglinjuan (if (HasFPU) fcsrMapping else Nil) ++ 9370ba52110SZiyue Zhang (if (HasVPU) vcsrMapping else Nil) ++ 938d0de7e4aSpeixiaokun (if (HasCustomCSRCacheOp) cacheopMapping else Nil) ++ 939d0de7e4aSpeixiaokun (if (HasHExtension) hcsrMapping else Nil) 940c84054caSLinJiawei 941f7af4c74Schengguanghui 942f7af4c74Schengguanghui println("XiangShan CSR Lists") 943f7af4c74Schengguanghui 944f7af4c74Schengguanghui for (addr <- mapping.keys.toSeq.sorted) { 945f7af4c74Schengguanghui println(f"$addr%#03x ${mapping(addr)._1}") 946f7af4c74Schengguanghui } 947f7af4c74Schengguanghui 948fe73ba60SYangyu Chen val vs_s_csr_map = List( 949d0de7e4aSpeixiaokun Sstatus.U -> Vsstatus.U, 950d0de7e4aSpeixiaokun Sie.U -> Vsie.U, 951d0de7e4aSpeixiaokun Stvec.U -> Vstvec.U, 952d0de7e4aSpeixiaokun Sscratch.U -> Vsscratch.U, 953d0de7e4aSpeixiaokun Sepc.U -> Vsepc.U, 954d0de7e4aSpeixiaokun Scause.U -> Vscause.U, 955d0de7e4aSpeixiaokun Stval.U -> Vstval.U, 956d0de7e4aSpeixiaokun Sip.U -> Vsip.U, 957d0de7e4aSpeixiaokun Satp.U -> Vsatp.U 958d0de7e4aSpeixiaokun ) 959d0de7e4aSpeixiaokun val addr = Wire(UInt(12.W)) 960d0de7e4aSpeixiaokun val vscsr_addr = LookupTreeDefault(src2(11, 0), src2(11, 0), vs_s_csr_map) 961d0de7e4aSpeixiaokun when(virtMode){ 962d0de7e4aSpeixiaokun addr := vscsr_addr 963d0de7e4aSpeixiaokun }.otherwise{ 964d0de7e4aSpeixiaokun addr := src2(11, 0) 965d0de7e4aSpeixiaokun } 966b1860798SZhangfw val csri = ZeroExt(src2(16, 12), XLEN) 967c84054caSLinJiawei val rdata = Wire(UInt(XLEN.W)) 968d0de7e4aSpeixiaokun val rdata_tmp = Wire(UInt(XLEN.W)) 969d0de7e4aSpeixiaokun val wdata_tmp = LookupTree(func, List( 970c84054caSLinJiawei CSROpType.wrt -> src1, 971c84054caSLinJiawei CSROpType.set -> (rdata | src1), 9725d669833SYinan Xu CSROpType.clr -> (rdata & (~src1).asUInt), 973b0ae3ac4SLinJiawei CSROpType.wrti -> csri, 974c84054caSLinJiawei CSROpType.seti -> (rdata | csri), 9755d669833SYinan Xu CSROpType.clri -> (rdata & (~csri).asUInt) 976c84054caSLinJiawei )) 977d0de7e4aSpeixiaokun val is_vsip_ie = addr === Vsip.U || addr === Vsie.U 978a1d4b4bfSpeixiaokun // for the difftest with NEMU(stay consistent with Spike) 979a1d4b4bfSpeixiaokun val is_satp = addr === Satp.U 980a1d4b4bfSpeixiaokun val is_vsatp = addr === Vsatp.U 981a1d4b4bfSpeixiaokun val is_hgatp = addr === Hgatp.U 982a1d4b4bfSpeixiaokun 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 983a1d4b4bfSpeixiaokun val wdata = MuxCase(wdata_tmp, Seq( 984a1d4b4bfSpeixiaokun is_vsip_ie -> ZeroExt(wdata_tmp << 1, XLEN), 985a1d4b4bfSpeixiaokun (is_satp && !check_apt_mode) -> satp, 986a1d4b4bfSpeixiaokun (is_vsatp && !check_apt_mode) -> vsatp, 987a1d4b4bfSpeixiaokun (is_hgatp && !check_apt_mode) -> hgatp 988a1d4b4bfSpeixiaokun )) 989e377d77eSWilliam Wang val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) || 9904d5d2702Swakafa (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U) || 991f7af4c74Schengguanghui (addr >= Cycle.U) && (addr <= Hpmcounter31.U) || 9924d5d2702Swakafa addr === Mip.U 993e377d77eSWilliam Wang csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp 9948635f18fSwangkaifan 99547a386bfSZhangZifei // satp wen check 99647a386bfSZhangZifei val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 9972f5f05fdSWilliam Wang 998e5adbe81SLemover // csr access check, special case 999d0de7e4aSpeixiaokun val tvmNotPermit = (privilegeMode === ModeS && !virtMode && mstatusStruct.tvm.asBool) 1000e5adbe81SLemover val accessPermitted = !(addr === Satp.U && tvmNotPermit) 1001d0de7e4aSpeixiaokun val vtvmNotPermit = (privilegeMode === ModeS && virtMode && hstatusStruct.vtvm.asBool) 1002d0de7e4aSpeixiaokun val vaccessPermitted = !(addr === Vsatp.U && vtvmNotPermit) 10032d3ae4b4SsinceforYy// csrio.disableSfence := (tvmNotPermit || !virtMode && privilegeMode < ModeS) || (vtvmNotPermit || virtMode && privilegeMode < ModeS) 10042d3ae4b4SsinceforYy// csrio.disableHfenceg := !((!virtMode && privilegeMode === ModeS && !mstatusStruct.tvm.asBool) || (privilegeMode === ModeM)) // only valid in HS and mstatus.tvm == 0 or in M 10052d3ae4b4SsinceforYy// csrio.disableHfencev := !(privilegeMode === ModeM || (!virtMode && privilegeMode === ModeS)) 1006e5adbe81SLemover 10072f5f05fdSWilliam Wang // general CSR wen check 10081be7b39aSXuan Hu val wen = valid && CSROpType.isCsrAccess(func) && ((addr=/=Satp.U && addr =/= Vsatp.U) || satpLegalMode) 100972951335SLi Qianruo val dcsrPermitted = dcsrPermissionCheck(addr, false.B, debugMode) 101072951335SLi Qianruo val triggerPermitted = triggerPermissionCheck(addr, true.B, debugMode) // todo dmode 10110214776eSpeixiaokun val HasH = (HasHExtension == true).asBool 1012d0de7e4aSpeixiaokun val csrAccess = csrAccessPermissionCheck(addr, false.B, privilegeMode, virtMode, HasH) 1013d0de7e4aSpeixiaokun val modePermitted = csrAccess === 0.U && dcsrPermitted && triggerPermitted 1014321934c7SKunlin You val perfcntPermitted = perfcntPermissionCheck(addr, privilegeMode, mcounteren, scounteren) 1015d0de7e4aSpeixiaokun val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && Mux(virtMode, vaccessPermitted, accessPermitted) 1016d0de7e4aSpeixiaokun MaskedRegMap.generate(mapping, addr, rdata_tmp, wen && permitted, wdata) 1017d0de7e4aSpeixiaokun rdata := Mux(is_vsip_ie, ZeroExt(rdata_tmp >> 1, XLEN), rdata_tmp) 10186a35d972SXuan Hu io.out.bits.res.data := rdata 10196a35d972SXuan Hu io.out.bits.ctrl.flushPipe.get := flushPipe 1020c1e19666Sxiaofeibao-xjtu connect0LatencyCtrlSingal 1021c84054caSLinJiawei 1022b6982e83SLemover // send distribute csr a w signal 1023b6982e83SLemover csrio.customCtrl.distribute_csr.w.valid := wen && permitted 1024b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.data := wdata 1025b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.addr := addr 1026b6982e83SLemover 1027a4e57ea3SLi Qianruo when (RegNext(csrio.fpu.fflags.valid)) { 1028577fcf2aSZhaoyang You fcsr := fflags_wfn(update = true)(RegEnable(csrio.fpu.fflags.bits, csrio.fpu.fflags.valid)) 1029c84054caSLinJiawei } 10306355a2b7Sczw when(RegNext(csrio.vpu.set_vxsat.valid)) { 103184d38341Ssinsanction vcsr := vxsat_wfn(update = true)(RegEnable(csrio.vpu.set_vxsat.bits, csrio.vpu.set_vxsat.valid)) 10326355a2b7Sczw } 103384d38341Ssinsanction 1034c84054caSLinJiawei // set fs and sd in mstatus 1035a4e57ea3SLi Qianruo when (csrw_dirty_fp_state || RegNext(csrio.fpu.dirty_fs)) { 1036c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1037c84054caSLinJiawei mstatusNew.fs := "b11".U 1038c84054caSLinJiawei mstatusNew.sd := true.B 10395d669833SYinan Xu mstatus := mstatusNew.asUInt 1040cf025d06Speixiaokun when(virtMode){ 1041cf025d06Speixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1042cf025d06Speixiaokun vsstatusNew.fs := "b11".U 1043cf025d06Speixiaokun vsstatusNew.sd := true.B 1044cf025d06Speixiaokun vsstatus := vsstatusNew.asUInt 1045c84054caSLinJiawei } 1046c84054caSLinJiawei } 1047129a273eSYinan Xu csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 1048c84054caSLinJiawei 104935d1557aSZiyue Zhang when (RegNext(csrio.vpu.set_vstart.valid)) { 1050577fcf2aSZhaoyang You vstart := RegEnable(csrio.vpu.set_vstart.bits, csrio.vpu.set_vstart.valid) 1051daa01159SZiyue Zhang } 105235d1557aSZiyue Zhang when (RegNext(csrio.vpu.set_vtype.valid)) { 1053577fcf2aSZhaoyang You vtype := RegEnable(csrio.vpu.set_vtype.bits, csrio.vpu.set_vtype.valid) 1054daa01159SZiyue Zhang } 1055d8a50338SZiyue Zhang vl := csrio.vpu.vl 1056daa01159SZiyue Zhang // set vs and sd in mstatus 105762a2cb19SXuan Hu when(csrw_dirty_vs_state || RegNext(csrio.vpu.dirty_vs)) { 105862a2cb19SXuan Hu val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 105962a2cb19SXuan Hu mstatusNew.vs := ContextStatus.dirty 106062a2cb19SXuan Hu mstatusNew.sd := true.B 106162a2cb19SXuan Hu mstatus := mstatusNew.asUInt 106262a2cb19SXuan Hu } 1063daa01159SZiyue Zhang 1064daa01159SZiyue Zhang csrio.vpu.vstart := vstart 1065daa01159SZiyue Zhang csrio.vpu.vxrm := vcsr.asTypeOf(new VcsrStruct).vxrm 106672951335SLi Qianruo 106772951335SLi Qianruo // Trigger Ctrl 1068f7af4c74Schengguanghui val triggerEnableVec = tdata1RegVec.map { tdata1 => 1069f7af4c74Schengguanghui val mcontrolData = tdata1.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData) 1070f7af4c74Schengguanghui tdata1.asTypeOf(new Tdata1Bundle).type_.asUInt === TrigTypeEnum.MCONTROL && ( 10710ffeff0dSXuan Hu mcontrolData.m && privilegeMode === ModeM || 10720ffeff0dSXuan Hu mcontrolData.s && privilegeMode === ModeS || 10730ffeff0dSXuan Hu mcontrolData.u && privilegeMode === ModeU) 107472951335SLi Qianruo } 1075f7af4c74Schengguanghui val fetchTriggerEnableVec = triggerEnableVec.zip(tdata1WireVec).map { 1076f7af4c74Schengguanghui case (tEnable, tdata1) => tEnable && tdata1.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isFetchTrigger 1077f7af4c74Schengguanghui } 1078f7af4c74Schengguanghui val memAccTriggerEnableVec = triggerEnableVec.zip(tdata1WireVec).map { 1079f7af4c74Schengguanghui case (tEnable, tdata1) => tEnable && tdata1.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isMemAccTrigger 1080f7af4c74Schengguanghui } 1081f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tEnableVec := fetchTriggerEnableVec 1082f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tEnableVec := memAccTriggerEnableVec 1083f7af4c74Schengguanghui 1084f7af4c74Schengguanghui val tdata1Update = wen && (addr === Tdata1.U) 1085f7af4c74Schengguanghui val tdata2Update = wen && (addr === Tdata2.U) 1086f7af4c74Schengguanghui val triggerUpdate = wen && (addr === Tdata1.U || addr === Tdata2.U) 1087f7af4c74Schengguanghui val frontendTriggerUpdate = 1088f7af4c74Schengguanghui tdata1Update && wdata.asTypeOf(new Tdata1Bundle).type_.asUInt === TrigTypeEnum.MCONTROL && 1089f7af4c74Schengguanghui wdata.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isFetchTrigger || 1090f7af4c74Schengguanghui tdata1Selected.data.asTypeOf(new MControlData).isFetchTrigger && triggerUpdate 1091f7af4c74Schengguanghui val memTriggerUpdate = 1092f7af4c74Schengguanghui tdata1Update && wdata.asTypeOf(new Tdata1Bundle).type_.asUInt === TrigTypeEnum.MCONTROL && 1093f7af4c74Schengguanghui wdata.asTypeOf(new Tdata1Bundle).data.asTypeOf(new MControlData).isMemAccTrigger || 1094f7af4c74Schengguanghui tdata1Selected.data.asTypeOf(new MControlData).isMemAccTrigger && triggerUpdate 1095f7af4c74Schengguanghui 1096f7af4c74Schengguanghui csrio.customCtrl.frontend_trigger.tUpdate.valid := RegNext(RegNext(frontendTriggerUpdate)) 1097f7af4c74Schengguanghui csrio.customCtrl.mem_trigger.tUpdate.valid := RegNext(RegNext(memTriggerUpdate)) 1098f7af4c74Schengguanghui XSDebug(triggerEnableVec.reduce(_ || _), p"Debug Mode: At least 1 trigger is enabled," + 1099f7af4c74Schengguanghui p"trigger enable is ${Binary(triggerEnableVec.asUInt)}\n") 110072951335SLi Qianruo 1101c84054caSLinJiawei // CSR inst decode 11028e7b11e5SWilliam Wang val isEbreak = addr === privEbreak && func === CSROpType.jmp 1103c84054caSLinJiawei val isEcall = addr === privEcall && func === CSROpType.jmp 1104c84054caSLinJiawei val isMret = addr === privMret && func === CSROpType.jmp 1105c84054caSLinJiawei val isSret = addr === privSret && func === CSROpType.jmp 1106c84054caSLinJiawei val isUret = addr === privUret && func === CSROpType.jmp 1107d4aca96cSlqre val isDret = addr === privDret && func === CSROpType.jmp 11085d669833SYinan Xu val isWFI = func === CSROpType.wfi 1109c84054caSLinJiawei 1110321934c7SKunlin You // Illegal privileged operation list 1111321934c7SKunlin You val illegalMret = valid && isMret && privilegeMode < ModeM 1112321934c7SKunlin You val illegalSret = valid && isSret && privilegeMode < ModeS 1113d0de7e4aSpeixiaokun val illegalSModeSret = valid && isSret && privilegeMode === ModeS && virtMode === false.B && mstatusStruct.tsr.asBool 1114d0de7e4aSpeixiaokun // when hstatus.vtsr == 1, if sret is executed in VS-mode, it will cause virtual instruction 1115d0de7e4aSpeixiaokun val illegalVSModeSret = valid && isSret && privilegeMode === ModeS && virtMode && hstatusStruct.vtsr.asBool 11165d669833SYinan Xu // When TW=1, then if WFI is executed in any less-privileged mode, 11175d669833SYinan Xu // and it does not complete within an implementation-specific, bounded time limit, 11185d669833SYinan Xu // the WFI instruction causes an illegal instruction exception. 11195d669833SYinan Xu // The time limit may always be 0, in which case WFI always causes 11205d669833SYinan Xu // an illegal instruction exception in less-privileged modes when TW=1. 1121d0de7e4aSpeixiaokun val illegalWFI = valid && isWFI && (privilegeMode < ModeM && mstatusStruct.tw === 1.U || privilegeMode === ModeU && !virtMode) 1122d0de7e4aSpeixiaokun val illegalVWFI = valid && isWFI && ((virtMode && privilegeMode === ModeS && hstatusStruct.vtw === 1.U && mstatusStruct.tw === 0.U)|| 1123d0de7e4aSpeixiaokun (virtMode && privilegeMode === ModeU && mstatusStruct.tw === 0.U)) 1124321934c7SKunlin You // Illegal privileged instruction check 11251be7b39aSXuan Hu val isIllegalAddr = valid && CSROpType.isCsrAccess(func) && MaskedRegMap.isIllegalAddr(mapping, addr) 1126d0de7e4aSpeixiaokun val isIllegalAccess = !virtMode && wen && !(Mux(addrInPerfCnt, perfcntPermitted, csrAccess === 0.U && dcsrPermitted && triggerPermitted) && accessPermitted) 11275d669833SYinan Xu val isIllegalPrivOp = illegalMret || illegalSret || illegalSModeSret || illegalWFI 1128c84054caSLinJiawei 1129d0de7e4aSpeixiaokun val isIllegalVAccess = virtMode && wen && (csrAccess === 2.U || !vaccessPermitted) 1130d0de7e4aSpeixiaokun val isIllegalVPrivOp = illegalVSModeSret || illegalVWFI 1131ad3ba452Szhanglinjuan // expose several csr bits for tlb 1132fcff7e94SZhangZifei tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 1133fcff7e94SZhangZifei tlbBundle.priv.sum := mstatusStruct.sum.asBool 1134d0de7e4aSpeixiaokun tlbBundle.priv.vmxr := vsstatusStruct.mxr.asBool 1135d0de7e4aSpeixiaokun tlbBundle.priv.vsum := vsstatusStruct.sum.asBool 1136d0de7e4aSpeixiaokun tlbBundle.priv.spvp := hstatusStruct.spvp 1137d0de7e4aSpeixiaokun tlbBundle.priv.virt := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpv & (mstatusStruct.mpp =/= ModeM), virtMode) 1138321934c7SKunlin You tlbBundle.priv.imode := privilegeMode 11390ffeff0dSXuan Hu tlbBundle.priv.dmode := Mux((debugMode && dcsr.asTypeOf(new DcsrStruct).mprven || !debugMode) && mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode) 1140c84054caSLinJiawei 1141e9341afdSYinan Xu // Branch control 1142f7af4c74Schengguanghui val retTarget = WireInit(0.U) 114382e4705bSpeixiaokun val resetSatp = (addr === Satp.U || addr === Hgatp.U || addr === Vsatp.U) && wen // write to satp will cause the pipeline be flushed 11445110577fSZiyue Zhang val writeVstart = addr === Vstart.U && wen // write to vstart will cause the pipeline be flushed 11455110577fSZiyue Zhang dontTouch(writeVstart) 1146c84054caSLinJiawei 1147f7af4c74Schengguanghui val w_fcsr_change_rm = wen && addr === Fcsr.U && wdata(7, 5) =/= fcsr(7, 5) 1148f7af4c74Schengguanghui val w_frm_change_rm = wen && addr === Frm.U && wdata(2, 0) =/= fcsr(7, 5) 1149f7af4c74Schengguanghui val frm_change = w_fcsr_change_rm || w_frm_change_rm 1150f7af4c74Schengguanghui val isXRet = valid && func === CSROpType.jmp && !isEcall && !isEbreak 11515110577fSZiyue Zhang flushPipe := resetSatp || frm_change || isXRet || frontendTriggerUpdate || writeVstart 1152c84054caSLinJiawei 1153f7af4c74Schengguanghui private val illegalRetTarget = WireInit(false.B) 1154f7af4c74Schengguanghui when(valid) { 1155f7af4c74Schengguanghui when(isDret) { 1156d4aca96cSlqre retTarget := dpc(VAddrBits - 1, 0) 1157f7af4c74Schengguanghui }.elsewhen(isMret && !illegalMret) { 1158f7af4c74Schengguanghui retTarget := mepc(VAddrBits - 1, 0) 1159d0de7e4aSpeixiaokun }.elsewhen(isSret && !illegalSret && !illegalSModeSret && !illegalVSModeSret) { 1160d0de7e4aSpeixiaokun retTarget := Mux(virtMode, vsepc(VAddrBits - 1, 0), sepc(VAddrBits - 1, 0)) 1161f7af4c74Schengguanghui }.elsewhen(isUret) { 1162f7af4c74Schengguanghui retTarget := uepc(VAddrBits - 1, 0) 1163f7af4c74Schengguanghui }.otherwise { 1164f7af4c74Schengguanghui illegalRetTarget := true.B 1165f7af4c74Schengguanghui } 1166f7af4c74Schengguanghui }.otherwise { 1167f7af4c74Schengguanghui illegalRetTarget := true.B // when illegalRetTarget setted, retTarget should never be used 1168f7af4c74Schengguanghui } 1169f7af4c74Schengguanghui 1170f7af4c74Schengguanghui // Mux tree for regs 1171f7af4c74Schengguanghui when(valid) { 1172f7af4c74Schengguanghui when(isDret) { 1173f7af4c74Schengguanghui val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1174f7af4c74Schengguanghui val debugModeNew = WireInit(debugMode) 1175f7af4c74Schengguanghui when(dcsr.asTypeOf(new DcsrStruct).prv =/= ModeM) { 1176f7af4c74Schengguanghui mstatusNew.mprv := 0.U 1177f7af4c74Schengguanghui } //If the new privilege mode is less privileged than M-mode, MPRV in mstatus is cleared. 1178f7af4c74Schengguanghui mstatus := mstatusNew.asUInt 11790ffeff0dSXuan Hu privilegeMode := dcsr.asTypeOf(new DcsrStruct).prv 1180d4aca96cSlqre debugModeNew := false.B 1181d4aca96cSlqre debugIntrEnable := true.B 1182d4aca96cSlqre debugMode := debugModeNew 1183d4aca96cSlqre XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 1184f7af4c74Schengguanghui }.elsewhen(isMret && !illegalMret) { 1185c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1186c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1187c84054caSLinJiawei mstatusNew.ie.m := mstatusOld.pie.m 1188321934c7SKunlin You privilegeMode := mstatusOld.mpp 1189d0de7e4aSpeixiaokun if (HasHExtension) { 1190d0de7e4aSpeixiaokun virtMode := mstatusOld.mpv 1191d0de7e4aSpeixiaokun mstatusNew.mpv := 0.U 1192d0de7e4aSpeixiaokun } 1193c84054caSLinJiawei mstatusNew.pie.m := true.B 1194c84054caSLinJiawei mstatusNew.mpp := ModeU 1195f7af4c74Schengguanghui when(mstatusOld.mpp =/= ModeM) { 1196f7af4c74Schengguanghui mstatusNew.mprv := 0.U 1197c84054caSLinJiawei } 1198f7af4c74Schengguanghui mstatus := mstatusNew.asUInt 119978233deeSXuan Hu }.elsewhen(isSret && !illegalSret && !illegalSModeSret && !illegalVSModeSret) { 1200c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1201c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1202d0de7e4aSpeixiaokun val hstatusOld = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1203d0de7e4aSpeixiaokun val hstatusNew = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1204d0de7e4aSpeixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1205d0de7e4aSpeixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1206d0de7e4aSpeixiaokun when(virtMode === 0.U) { 1207d0de7e4aSpeixiaokun virtMode := hstatusOld.spv 1208d0de7e4aSpeixiaokun hstatusNew.spv := 0.U 1209c84054caSLinJiawei mstatusNew.ie.s := mstatusOld.pie.s 1210321934c7SKunlin You privilegeMode := Cat(0.U(1.W), mstatusOld.spp) 1211c84054caSLinJiawei mstatusNew.pie.s := true.B 1212c84054caSLinJiawei mstatusNew.spp := ModeU 1213f7af4c74Schengguanghui when(mstatusOld.spp =/= ModeM) { 1214f7af4c74Schengguanghui mstatusNew.mprv := 0.U 1215c84054caSLinJiawei } 1216c84054caSLinJiawei mstatus := mstatusNew.asUInt 1217d0de7e4aSpeixiaokun hstatus := hstatusNew.asUInt 1218d0de7e4aSpeixiaokun }.otherwise { 1219d0de7e4aSpeixiaokun privilegeMode := vsstatusOld.spp 1220d0de7e4aSpeixiaokun vsstatusNew.spp := ModeU 1221d0de7e4aSpeixiaokun vsstatusNew.ie.s := vsstatusOld.pie.s 1222d0de7e4aSpeixiaokun vsstatusNew.pie.s := 1.U 1223d0de7e4aSpeixiaokun vsstatus := vsstatusNew.asUInt 1224d0de7e4aSpeixiaokun } 1225f7af4c74Schengguanghui }.elsewhen(isUret) { 1226c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1227c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1228c84054caSLinJiawei // mstatusNew.mpp.m := ModeU //TODO: add mode U 1229c84054caSLinJiawei mstatusNew.ie.u := mstatusOld.pie.u 1230321934c7SKunlin You privilegeMode := ModeU 1231c84054caSLinJiawei mstatusNew.pie.u := true.B 1232c84054caSLinJiawei mstatus := mstatusNew.asUInt 1233f7af4c74Schengguanghui } 1234c84054caSLinJiawei } 1235c84054caSLinJiawei 1236e9341afdSYinan Xu io.in.ready := true.B 1237e9341afdSYinan Xu io.out.valid := valid 1238e9341afdSYinan Xu 1239f7af4c74Schengguanghui // In this situation, hart will enter debug mode instead of handling a breakpoint exception simply. 1240f7af4c74Schengguanghui // Ebreak block instructions backwards, so it's ok to not keep extra info to distinguish between breakpoint 1241f7af4c74Schengguanghui // exception and enter-debug-mode exception. 1242f7af4c74Schengguanghui val ebreakEnterDebugMode = 12435b0f0029SXuan Hu (privilegeMode === ModeM && dcsrData.ebreakm) || 12445b0f0029SXuan Hu (privilegeMode === ModeS && dcsrData.ebreaks) || 12455b0f0029SXuan Hu (privilegeMode === ModeU && dcsrData.ebreaku) 1246f7af4c74Schengguanghui 1247f7af4c74Schengguanghui // raise a debug exception waiting to enter debug mode, instead of a breakpoint exception 1248f7af4c74Schengguanghui val raiseDebugException = !debugMode && isEbreak && ebreakEnterDebugMode 1249d4aca96cSlqre 12503b739f49SXuan Hu val csrExceptionVec = WireInit(0.U.asTypeOf(ExceptionVec())) 1251f7af4c74Schengguanghui csrExceptionVec(breakPoint) := io.in.valid && isEbreak 1252321934c7SKunlin You csrExceptionVec(ecallM) := privilegeMode === ModeM && io.in.valid && isEcall 1253d0de7e4aSpeixiaokun csrExceptionVec(ecallVS) := privilegeMode === ModeS && virtMode && io.in.valid && isEcall 1254d0de7e4aSpeixiaokun csrExceptionVec(ecallS) := privilegeMode === ModeS && !virtMode && io.in.valid && isEcall 1255321934c7SKunlin You csrExceptionVec(ecallU) := privilegeMode === ModeU && io.in.valid && isEcall 1256baf8def6SYinan Xu // Trigger an illegal instr exception when: 1257baf8def6SYinan Xu // * unimplemented csr is being read/written 1258baf8def6SYinan Xu // * csr access is illegal 12595d669833SYinan Xu csrExceptionVec(illegalInstr) := isIllegalAddr || isIllegalAccess || isIllegalPrivOp 1260d0de7e4aSpeixiaokun csrExceptionVec(virtualInstr) := isIllegalVAccess || isIllegalVPrivOp 12616a35d972SXuan Hu io.out.bits.ctrl.exceptionVec.get := csrExceptionVec 1262baf8def6SYinan Xu 1263f7af4c74Schengguanghui XSDebug(io.in.valid, s"Debug Mode: an Ebreak is executed, ebreak cause enter-debug-mode exception ? ${raiseDebugException}\n") 126484e47f35SLi Qianruo 1265e9341afdSYinan Xu /** 1266e9341afdSYinan Xu * Exception and Intr 1267e9341afdSYinan Xu */ 1268d0de7e4aSpeixiaokun val idelegS = (mideleg & mip.asUInt) 1269d0de7e4aSpeixiaokun val idelegVS = (hideleg & mideleg & mip.asUInt) 1270d0de7e4aSpeixiaokun def privilegedEnableDetect(idelegS: Bool, idelegVS: Bool): Bool = Mux(idelegS, 1271d0de7e4aSpeixiaokun Mux(idelegVS, (virtMode && privilegeMode === ModeS && vsstatusStruct.ie.s) || (virtMode && privilegeMode < ModeS), 1272d0de7e4aSpeixiaokun ((privilegeMode === ModeS) && mstatusStruct.ie.s) || (privilegeMode < ModeS) || virtMode), 1273321934c7SKunlin You ((privilegeMode === ModeM) && mstatusStruct.ie.m) || (privilegeMode < ModeM)) 1274e9341afdSYinan Xu 1275d4aca96cSlqre val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 1276d4aca96cSlqre XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 12779aca92b9SYinan Xu // send interrupt information to ROB 1278d0de7e4aSpeixiaokun val intrVecEnable = Wire(Vec(13, Bool())) 1279052ee9a1SLi Qianruo val disableInterrupt = debugMode || (dcsrData.step && !dcsrData.stepie) 1280d0de7e4aSpeixiaokun intrVecEnable.zip(idelegS.asBools).zip(idelegVS.asBools).map{case((x,y),z) => x := privilegedEnableDetect(y, z) && !disableInterrupt} 1281d7dd1af1SLi Qianruo val intrVec = Cat(debugIntr && !debugMode, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 12825d669833SYinan Xu val intrBitSet = intrVec.orR 1283e9341afdSYinan Xu csrio.interrupt := intrBitSet 12845c95ea2eSYinan Xu // Page 45 in RISC-V Privileged Specification 12855c95ea2eSYinan Xu // The WFI instruction can also be executed when interrupts are disabled. The operation of WFI 12865c95ea2eSYinan Xu // must be unaffected by the global interrupt bits in mstatus (MIE and SIE) and the delegation 12875c95ea2eSYinan Xu // register mideleg, but should honor the individual interrupt enables (e.g, MTIE). 12884ede3fe2SLi Qianruo csrio.wfi_event := debugIntr || (mie(11, 0) & mip.asUInt).orR 1289e9341afdSYinan Xu mipWire.t.m := csrio.externalInterrupt.mtip 1290e9341afdSYinan Xu mipWire.s.m := csrio.externalInterrupt.msip 1291e9341afdSYinan Xu mipWire.e.m := csrio.externalInterrupt.meip 1292b3d79b37SYinan Xu mipWire.e.s := csrio.externalInterrupt.seip 1293e9341afdSYinan Xu 1294e9341afdSYinan Xu // interrupts 1295e9341afdSYinan Xu val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 1296f7af4c74Schengguanghui val hasIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 1297a4e57ea3SLi Qianruo val ivmEnable = tlbBundle.priv.imode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 12983b739f49SXuan Hu val iexceptionPC = Mux(ivmEnable, SignExt(csrio.exception.bits.pc, XLEN), csrio.exception.bits.pc) 1299e25e4d90SXuan Hu val iexceptionGPAddr = Mux(ivmEnable, SignExt(csrio.exception.bits.gpaddr, XLEN), csrio.exception.bits.gpaddr) 1300a4e57ea3SLi Qianruo val dvmEnable = tlbBundle.priv.dmode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 13013b739f49SXuan Hu val dexceptionPC = Mux(dvmEnable, SignExt(csrio.exception.bits.pc, XLEN), csrio.exception.bits.pc) 1302f7af4c74Schengguanghui XSDebug(hasIntr, "interrupt: pc=0x%x, %d\n", dexceptionPC, intrNO) 1303f7af4c74Schengguanghui val hasDebugIntr = intrNO === IRQ_DEBUG.U && hasIntr 1304e9341afdSYinan Xu 1305f7af4c74Schengguanghui // exceptions from rob need to handle 1306f7af4c74Schengguanghui val exceptionVecFromRob = csrio.exception.bits.exceptionVec 1307f7af4c74Schengguanghui val hasException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 1308f7af4c74Schengguanghui val hasInstrPageFault = hasException && exceptionVecFromRob(instrPageFault) 1309f7af4c74Schengguanghui val hasLoadPageFault = hasException && exceptionVecFromRob(loadPageFault) 1310f7af4c74Schengguanghui val hasStorePageFault = hasException && exceptionVecFromRob(storePageFault) 1311f7af4c74Schengguanghui val hasStoreAddrMisalign = hasException && exceptionVecFromRob(storeAddrMisaligned) 1312f7af4c74Schengguanghui val hasLoadAddrMisalign = hasException && exceptionVecFromRob(loadAddrMisaligned) 1313f7af4c74Schengguanghui val hasInstrAccessFault = hasException && exceptionVecFromRob(instrAccessFault) 1314f7af4c74Schengguanghui val hasLoadAccessFault = hasException && exceptionVecFromRob(loadAccessFault) 1315f7af4c74Schengguanghui val hasStoreAccessFault = hasException && exceptionVecFromRob(storeAccessFault) 1316f7af4c74Schengguanghui val hasBreakPoint = hasException && exceptionVecFromRob(breakPoint) 13171f518b57SXuan Hu val hasInstGuestPageFault = hasException && exceptionVecFromRob(instrGuestPageFault) 13181f518b57SXuan Hu val hasLoadGuestPageFault = hasException && exceptionVecFromRob(loadGuestPageFault) 13191f518b57SXuan Hu val hasStoreGuestPageFault = hasException && exceptionVecFromRob(storeGuestPageFault) 1320f7af4c74Schengguanghui val hasSingleStep = hasException && csrio.exception.bits.singleStep 1321f7af4c74Schengguanghui val hasTriggerFire = hasException && csrio.exception.bits.trigger.canFire 1322f7af4c74Schengguanghui val triggerFrontendHitVec = csrio.exception.bits.trigger.frontendHit 1323f7af4c74Schengguanghui val triggerMemHitVec = csrio.exception.bits.trigger.backendHit 1324f7af4c74Schengguanghui val triggerHitVec = triggerFrontendHitVec | triggerMemHitVec // Todo: update mcontrol.hit 1325f7af4c74Schengguanghui val triggerCanFireVec = csrio.exception.bits.trigger.frontendCanFire | csrio.exception.bits.trigger.backendCanFire 1326f7af4c74Schengguanghui // More than one triggers can hit at the same time, but only fire one 1327f7af4c74Schengguanghui // We select the first hit trigger to fire 1328f7af4c74Schengguanghui val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 1329f7af4c74Schengguanghui val triggerFireAction = PriorityMux(triggerFireOH, tdata1WireVec.map(_.getTriggerAction)).asUInt 1330f7af4c74Schengguanghui 133184e47f35SLi Qianruo 133284e47f35SLi Qianruo XSDebug(hasSingleStep, "Debug Mode: single step exception\n") 1333f7af4c74Schengguanghui XSDebug(hasTriggerFire, p"Debug Mode: trigger fire, frontend hit vec ${Binary(csrio.exception.bits.trigger.frontendHit.asUInt)} " + 1334f7af4c74Schengguanghui p"backend hit vec ${Binary(csrio.exception.bits.trigger.backendHit.asUInt)}\n") 1335e9341afdSYinan Xu 1336f7af4c74Schengguanghui val hasExceptionVec = csrio.exception.bits.exceptionVec 1337f7af4c74Schengguanghui val regularExceptionNO = ExceptionNO.priorities.foldRight(0.U)((i: Int, sum: UInt) => Mux(hasExceptionVec(i), i.U, sum)) 1338f7af4c74Schengguanghui val exceptionNO = Mux(hasSingleStep || hasTriggerFire, 3.U, regularExceptionNO) 1339f7af4c74Schengguanghui val causeNO = (hasIntr << (XLEN - 1)).asUInt | Mux(hasIntr, intrNO, exceptionNO) 1340e9341afdSYinan Xu 1341f7af4c74Schengguanghui val hasExceptionIntr = csrio.exception.valid 1342d4aca96cSlqre 1343f7af4c74Schengguanghui val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode 1344f7af4c74Schengguanghui val hasDebugTriggerException = hasTriggerFire && triggerFireAction === TrigActionEnum.DEBUG_MODE 1345f7af4c74Schengguanghui val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep 1346f7af4c74Schengguanghui val hasDebugTrap = hasDebugException || hasDebugIntr 1347f7af4c74Schengguanghui val ebreakEnterParkLoop = debugMode && hasExceptionIntr 1348f7af4c74Schengguanghui 1349f7af4c74Schengguanghui XSDebug(hasExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 1350f7af4c74Schengguanghui dexceptionPC, intrNO, intrVec, exceptionNO, hasExceptionVec.asUInt 1351e9341afdSYinan Xu ) 1352f7af4c74Schengguanghui XSDebug(hasExceptionIntr, 1353e9341afdSYinan Xu "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 1354a4e57ea3SLi Qianruo dexceptionPC, 1355e9341afdSYinan Xu mstatus, 1356e9341afdSYinan Xu mideleg, 1357e9341afdSYinan Xu medeleg, 1358321934c7SKunlin You privilegeMode 1359e9341afdSYinan Xu ) 1360e9341afdSYinan Xu 1361e9341afdSYinan Xu // mtval write logic 13628a33de1fSYinan Xu // Due to timing reasons of memExceptionVAddr, we delay the write of mtval and stval 1363e9341afdSYinan Xu val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 1364d0de7e4aSpeixiaokun val memExceptionGPAddr = SignExt(csrio.memExceptionGPAddr, XLEN) 1365a4e57ea3SLi Qianruo val updateTval = VecInit(Seq( 1366a4e57ea3SLi Qianruo hasInstrPageFault, 1367a4e57ea3SLi Qianruo hasLoadPageFault, 1368a4e57ea3SLi Qianruo hasStorePageFault, 1369a4e57ea3SLi Qianruo hasInstrAccessFault, 1370a4e57ea3SLi Qianruo hasLoadAccessFault, 1371a4e57ea3SLi Qianruo hasStoreAccessFault, 1372f7af4c74Schengguanghui hasLoadAddrMisalign, 13735b0f0029SXuan Hu hasStoreAddrMisalign, 1374d0de7e4aSpeixiaokun hasInstGuestPageFault, 1375d0de7e4aSpeixiaokun hasLoadGuestPageFault, 13761797fef6SXuan Hu hasStoreGuestPageFault, 13771797fef6SXuan Hu hasBreakPoint, 1378d0de7e4aSpeixiaokun )).asUInt.orR 1379d0de7e4aSpeixiaokun val updateTval_h = VecInit(Seq( 1380d0de7e4aSpeixiaokun hasInstGuestPageFault, 1381d0de7e4aSpeixiaokun hasLoadGuestPageFault, 1382d0de7e4aSpeixiaokun hasStoreGuestPageFault 1383a4e57ea3SLi Qianruo )).asUInt.orR 1384a4e57ea3SLi Qianruo when (RegNext(RegNext(updateTval))) { 138595fbbc80SYinan Xu val tval = Mux( 13861797fef6SXuan Hu RegNext(RegNext(hasInstrPageFault || hasInstrAccessFault || hasInstGuestPageFault || hasBreakPoint)), 138795fbbc80SYinan Xu RegNext(RegNext(Mux( 13883b739f49SXuan Hu csrio.exception.bits.crossPageIPFFix, 13893b739f49SXuan Hu SignExt(csrio.exception.bits.pc + 2.U, XLEN), 1390a4e57ea3SLi Qianruo iexceptionPC 139195fbbc80SYinan Xu ))), 1392e9341afdSYinan Xu memExceptionAddr 139395fbbc80SYinan Xu ) 1394d0de7e4aSpeixiaokun // because we update tval two beats later, we can choose xtval according to the privilegeMode which has been updated 1395321934c7SKunlin You when (RegNext(privilegeMode === ModeM)) { 1396e9341afdSYinan Xu mtval := tval 1397e9341afdSYinan Xu }.otherwise { 1398d0de7e4aSpeixiaokun when (virtMode){ 1399d0de7e4aSpeixiaokun vstval := tval 1400d0de7e4aSpeixiaokun }.otherwise{ 1401e9341afdSYinan Xu stval := tval 1402e9341afdSYinan Xu } 1403e9341afdSYinan Xu } 1404d0de7e4aSpeixiaokun } 1405d0de7e4aSpeixiaokun 1406d0de7e4aSpeixiaokun when(RegNext(RegNext(updateTval_h))) { 1407d0de7e4aSpeixiaokun val tval_tmp = Mux( 1408d0de7e4aSpeixiaokun RegNext(RegNext(hasInstGuestPageFault)), 1409d0de7e4aSpeixiaokun RegNext(RegNext(Mux( 1410e25e4d90SXuan Hu csrio.exception.bits.crossPageIPFFix, 1411e25e4d90SXuan Hu SignExt(csrio.exception.bits.gpaddr + 2.U, XLEN), 1412d0de7e4aSpeixiaokun iexceptionGPAddr 1413d0de7e4aSpeixiaokun ))), 1414d0de7e4aSpeixiaokun memExceptionGPAddr 1415d0de7e4aSpeixiaokun ) 1416d0de7e4aSpeixiaokun val tval = tval_tmp >> 2 1417d0de7e4aSpeixiaokun when(RegNext(privilegeMode === ModeM)) { 1418d0de7e4aSpeixiaokun mtval2 := tval 1419d0de7e4aSpeixiaokun }.otherwise { 1420d0de7e4aSpeixiaokun htval := tval 1421d0de7e4aSpeixiaokun } 1422d0de7e4aSpeixiaokun } 1423e9341afdSYinan Xu 1424d4aca96cSlqre val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 1425f7af4c74Schengguanghui val deleg = Mux(hasIntr, mideleg , medeleg) 14261f518b57SXuan Hu val hdeleg = Mux(hasIntr, hideleg, hedeleg) 1427321934c7SKunlin You // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (privilegeMode < ModeM); 14285b0f0029SXuan Hu val delegS = deleg(causeNO(7,0)) && (privilegeMode < ModeM) 1429d0de7e4aSpeixiaokun val delegVS = virtMode && delegS && hdeleg(causeNO(7, 0)) && (privilegeMode < ModeM) 1430f7af4c74Schengguanghui val clearTval = !updateTval || hasIntr 143113096f7eSYinan Xu 14321f518b57SXuan Hu val clearTval_h = !updateTval_h || hasIntr 1433e25e4d90SXuan Hu val isHyperInst = csrio.exception.bits.isHls 143413096f7eSYinan Xu // ctrl block will use theses later for flush 143513096f7eSYinan Xu val isXRetFlag = RegInit(false.B) 14363b739f49SXuan Hu when (DelayN(io.flush.valid, 5)) { 143713096f7eSYinan Xu isXRetFlag := false.B 143813096f7eSYinan Xu }.elsewhen (isXRet) { 143913096f7eSYinan Xu isXRetFlag := true.B 144013096f7eSYinan Xu } 144113096f7eSYinan Xu csrio.isXRet := isXRetFlag 1442f7af4c74Schengguanghui private val retTargetReg = RegEnable(retTarget, isXRet && !illegalRetTarget) 1443d0de7e4aSpeixiaokun private val illegalXret = RegEnable(illegalMret || illegalSret || illegalSModeSret || illegalVSModeSret, isXRet) 1444a4e57ea3SLi Qianruo 1445e25e4d90SXuan Hu private val xtvec = Mux(delegS, Mux(delegVS, vstvec, stvec), mtvec) 1446f7af4c74Schengguanghui private val xtvecBase = xtvec(VAddrBits - 1, 2) 1447a4e57ea3SLi Qianruo // When MODE=Vectored, all synchronous exceptions into M/S mode 1448a4e57ea3SLi Qianruo // cause the pc to be set to the address in the BASE field, whereas 1449a4e57ea3SLi Qianruo // interrupts cause the pc to be set to the address in the BASE field 1450a4e57ea3SLi Qianruo // plus four times the interrupt cause number. 1451f7af4c74Schengguanghui private val pcFromXtvec = Cat(xtvecBase + Mux(xtvec(0) && hasIntr, causeNO(3, 0), 0.U), 0.U(2.W)) 1452e9341afdSYinan Xu 1453f7af4c74Schengguanghui // XRet sends redirect instead of Flush and isXRetFlag is true.B before redirect.valid. 1454f7af4c74Schengguanghui // ROB sends exception at T0 while CSR receives at T2. 1455f7af4c74Schengguanghui // We add a RegNext here and trapTarget is valid at T3. 1456f7af4c74Schengguanghui csrio.trapTarget := RegEnable( 1457f7af4c74Schengguanghui MuxCase(pcFromXtvec, Seq( 1458f7af4c74Schengguanghui (isXRetFlag && !illegalXret) -> retTargetReg, 1459f7af4c74Schengguanghui ((hasDebugTrap && !debugMode) || ebreakEnterParkLoop) -> debugTrapTarget 1460f7af4c74Schengguanghui )), 1461f7af4c74Schengguanghui isXRetFlag || csrio.exception.valid) 1462f7af4c74Schengguanghui 1463f7af4c74Schengguanghui when(hasExceptionIntr) { 1464c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1465c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1466d0de7e4aSpeixiaokun val hstatusOld = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1467d0de7e4aSpeixiaokun val hstatusNew = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1468d0de7e4aSpeixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1469d0de7e4aSpeixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1470d4aca96cSlqre val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1471d4aca96cSlqre val debugModeNew = WireInit(debugMode) 1472f7af4c74Schengguanghui when(hasDebugTrap && !debugMode) { 1473f7af4c74Schengguanghui import DcsrStruct._ 1474d4aca96cSlqre debugModeNew := true.B 14750ffeff0dSXuan Hu dcsrNew.prv := privilegeMode 14760ffeff0dSXuan Hu privilegeMode := ModeM 1477f7af4c74Schengguanghui when(hasDebugIntr) { 1478a4e57ea3SLi Qianruo dpc := iexceptionPC 1479f7af4c74Schengguanghui dcsrNew.cause := CAUSE_HALTREQ 1480f7af4c74Schengguanghui XSDebug(hasDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 1481f7af4c74Schengguanghui }.otherwise { // hasDebugException 1482f7af4c74Schengguanghui dpc := iexceptionPC // TODO: check it when hasSingleStep 1483f7af4c74Schengguanghui dcsrNew.cause := MuxCase(0.U, Seq( 1484f7af4c74Schengguanghui hasTriggerFire -> CAUSE_TRIGGER, 14855f28e666Schengguanghui raiseDebugException -> CAUSE_EBREAK, 1486f7af4c74Schengguanghui hasBreakPoint -> CAUSE_HALTREQ, 1487f7af4c74Schengguanghui hasSingleStep -> CAUSE_STEP 1488f7af4c74Schengguanghui )) 1489d4aca96cSlqre } 1490d4aca96cSlqre dcsr := dcsrNew.asUInt 1491d4aca96cSlqre debugIntrEnable := false.B 1492d7dd1af1SLi Qianruo }.elsewhen (debugMode) { 1493d7dd1af1SLi Qianruo //do nothing 1494d61cd5eeSpeixiaokun }.elsewhen (delegVS) { 149596544367Speixiaokun vscause := (hasIntr << (XLEN-1)).asUInt | Mux(hasIntr, intrNO - 1.U, exceptionNO) 1496d0de7e4aSpeixiaokun vsepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1497d0de7e4aSpeixiaokun vsstatusNew.spp := privilegeMode 1498d0de7e4aSpeixiaokun vsstatusNew.pie.s := vsstatusOld.ie.s 1499d0de7e4aSpeixiaokun vsstatusNew.ie.s := false.B 1500d0de7e4aSpeixiaokun when (clearTval) {vstval := 0.U} 1501d0de7e4aSpeixiaokun virtMode := true.B 1502d0de7e4aSpeixiaokun privilegeMode := ModeS 1503d4aca96cSlqre }.elsewhen (delegS) { 15040214776eSpeixiaokun val virt = Mux(mstatusOld.mprv.asBool, mstatusOld.mpv, virtMode) 1505d0de7e4aSpeixiaokun // to do hld st 1506d0de7e4aSpeixiaokun hstatusNew.gva := (hasInstGuestPageFault || hasLoadGuestPageFault || hasStoreGuestPageFault || 15071f518b57SXuan Hu ((virt.asBool || isHyperInst) && ((hasException && 0.U <= exceptionNO && exceptionNO <= 7.U && exceptionNO =/= 2.U) 1508d0de7e4aSpeixiaokun || hasInstrPageFault || hasLoadPageFault || hasStorePageFault))) 1509d0de7e4aSpeixiaokun hstatusNew.spv := virtMode 1510d0de7e4aSpeixiaokun when(virtMode){ 1511d0de7e4aSpeixiaokun hstatusNew.spvp := privilegeMode 1512d0de7e4aSpeixiaokun } 1513d0de7e4aSpeixiaokun virtMode := false.B 1514c84054caSLinJiawei scause := causeNO 1515a4e57ea3SLi Qianruo sepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1516321934c7SKunlin You mstatusNew.spp := privilegeMode 1517c84054caSLinJiawei mstatusNew.pie.s := mstatusOld.ie.s 1518c84054caSLinJiawei mstatusNew.ie.s := false.B 1519321934c7SKunlin You privilegeMode := ModeS 1520a4e57ea3SLi Qianruo when (clearTval) { stval := 0.U } 1521d0de7e4aSpeixiaokun when (clearTval_h) {htval := 0.U} 1522c84054caSLinJiawei }.otherwise { 15230214776eSpeixiaokun val virt = Mux(mstatusOld.mprv.asBool, mstatusOld.mpv, virtMode) 1524d0de7e4aSpeixiaokun // to do hld st 1525d0de7e4aSpeixiaokun mstatusNew.gva := (hasInstGuestPageFault || hasLoadGuestPageFault || hasStoreGuestPageFault || 15261f518b57SXuan Hu ((virt.asBool || isHyperInst) && ((hasException && 0.U <= exceptionNO && exceptionNO <= 7.U && exceptionNO =/= 2.U) 1527d0de7e4aSpeixiaokun || hasInstrPageFault || hasLoadPageFault || hasStorePageFault))) 1528d0de7e4aSpeixiaokun mstatusNew.mpv := virtMode 1529d0de7e4aSpeixiaokun virtMode := false.B 1530c84054caSLinJiawei mcause := causeNO 1531a4e57ea3SLi Qianruo mepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1532321934c7SKunlin You mstatusNew.mpp := privilegeMode 1533c84054caSLinJiawei mstatusNew.pie.m := mstatusOld.ie.m 1534c84054caSLinJiawei mstatusNew.ie.m := false.B 1535321934c7SKunlin You privilegeMode := ModeM 1536a4e57ea3SLi Qianruo when (clearTval) { mtval := 0.U } 1537d0de7e4aSpeixiaokun when (clearTval_h) {mtval2 := 0.U} 1538c84054caSLinJiawei } 1539c84054caSLinJiawei mstatus := mstatusNew.asUInt 1540d0de7e4aSpeixiaokun vsstatus := vsstatusNew.asUInt 1541d0de7e4aSpeixiaokun hstatus := hstatusNew.asUInt 1542d4aca96cSlqre debugMode := debugModeNew 1543c84054caSLinJiawei } 1544c84054caSLinJiawei 15459ef181f4SWilliam Wang // Cache error debug support 15469ef181f4SWilliam Wang if(HasCustomCSRCacheOp){ 15479ef181f4SWilliam Wang val cache_error_decoder = Module(new CSRCacheErrorDecoder) 15489ef181f4SWilliam Wang cache_error_decoder.io.encoded_cache_error := cacheopRegs("CACHE_ERROR") 15499ef181f4SWilliam Wang } 15509ef181f4SWilliam Wang 1551e30fd06aSYinan Xu // Implicit add reset values for mepc[0] and sepc[0] 1552e30fd06aSYinan Xu // TODO: rewrite mepc and sepc using a struct-like style with the LSB always being 0 155367ba96b4SYinan Xu when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 1554e30fd06aSYinan Xu mepc := Cat(mepc(XLEN - 1, 1), 0.U(1.W)) 1555e30fd06aSYinan Xu sepc := Cat(sepc(XLEN - 1, 1), 0.U(1.W)) 155621ae6bc4Speixiaokun vsepc := Cat(vsepc(XLEN - 1, 1), 0.U(1.W)) 1557e30fd06aSYinan Xu } 1558e30fd06aSYinan Xu 1559c84054caSLinJiawei def readWithScala(addr: Int): UInt = mapping(addr)._1 1560c84054caSLinJiawei 1561f7af4c74Schengguanghui val difftestIntrNO = Mux(hasIntr, causeNO, 0.U) 1562a165bd69Swangkaifan 1563cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1564cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 15657d45a146SYinan Xu val difftest = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 15667d45a146SYinan Xu difftest.coreid := csrio.hartId 15677d45a146SYinan Xu difftest.valid := csrio.exception.valid 1568f7af4c74Schengguanghui difftest.interrupt := Mux(hasIntr, causeNO, 0.U) 1569f7af4c74Schengguanghui difftest.exception := Mux(hasException, causeNO, 0.U) 15707d45a146SYinan Xu difftest.exceptionPC := dexceptionPC 1571a4e57ea3SLi Qianruo if (env.EnableDifftest) { 15724b0d80d8SXuan Hu difftest.exceptionInst := csrio.exception.bits.instr 1573a4e57ea3SLi Qianruo } 15742225d46eSJiawei Lin } 15752225d46eSJiawei Lin 1576cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1577cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 15787d45a146SYinan Xu val difftest = DifftestModule(new DiffCSRState) 15797d45a146SYinan Xu difftest.coreid := csrio.hartId 1580321934c7SKunlin You difftest.privilegeMode := privilegeMode 15817d45a146SYinan Xu difftest.mstatus := mstatus 15827d45a146SYinan Xu difftest.sstatus := mstatus & sstatusRmask 15837d45a146SYinan Xu difftest.mepc := mepc 15847d45a146SYinan Xu difftest.sepc := sepc 15857d45a146SYinan Xu difftest.mtval:= mtval 15867d45a146SYinan Xu difftest.stval:= stval 15877d45a146SYinan Xu difftest.mtvec := mtvec 15887d45a146SYinan Xu difftest.stvec := stvec 15897d45a146SYinan Xu difftest.mcause := mcause 15907d45a146SYinan Xu difftest.scause := scause 15917d45a146SYinan Xu difftest.satp := satp 15927d45a146SYinan Xu difftest.mip := mipReg 15937d45a146SYinan Xu difftest.mie := mie 15947d45a146SYinan Xu difftest.mscratch := mscratch 15957d45a146SYinan Xu difftest.sscratch := sscratch 15967d45a146SYinan Xu difftest.mideleg := mideleg 15977d45a146SYinan Xu difftest.medeleg := medeleg 1598a165bd69Swangkaifan } 1599a4e57ea3SLi Qianruo 1600a4e57ea3SLi Qianruo if (env.AlwaysBasicDiff || env.EnableDifftest) { 160187d0ba30Speixiaokun val difftest = DifftestModule(new DiffHCSRState) 160287d0ba30Speixiaokun difftest.coreid := csrio.hartId 160387d0ba30Speixiaokun difftest.virtMode := virtMode 160487d0ba30Speixiaokun difftest.mtval2 := mtval2 160587d0ba30Speixiaokun difftest.mtinst := mtinst 160687d0ba30Speixiaokun difftest.hstatus := hstatus 160787d0ba30Speixiaokun difftest.hideleg := hideleg 160887d0ba30Speixiaokun difftest.hedeleg := hedeleg 160987d0ba30Speixiaokun difftest.hcounteren := hcounteren 161087d0ba30Speixiaokun difftest.htval := htval 161187d0ba30Speixiaokun difftest.htinst := htinst 161287d0ba30Speixiaokun difftest.hgatp := hgatp 161387d0ba30Speixiaokun difftest.vsstatus := vsstatus 161487d0ba30Speixiaokun difftest.vstvec := vstvec 161587d0ba30Speixiaokun difftest.vsepc := vsepc 161687d0ba30Speixiaokun difftest.vscause := vscause 161787d0ba30Speixiaokun difftest.vstval := vstval 161887d0ba30Speixiaokun difftest.vsatp := vsatp 161987d0ba30Speixiaokun difftest.vsscratch := vsscratch 1620d0de7e4aSpeixiaokun } 1621d0de7e4aSpeixiaokun 1622d0de7e4aSpeixiaokun if(env.AlwaysBasicDiff || env.EnableDifftest) { 16237d45a146SYinan Xu val difftest = DifftestModule(new DiffDebugMode) 16247d45a146SYinan Xu difftest.coreid := csrio.hartId 16257d45a146SYinan Xu difftest.debugMode := debugMode 16267d45a146SYinan Xu difftest.dcsr := dcsr 16277d45a146SYinan Xu difftest.dpc := dpc 1628f7af4c74Schengguanghui difftest.dscratch0 := dscratch0 16297d45a146SYinan Xu difftest.dscratch1 := dscratch1 1630a4e57ea3SLi Qianruo } 163135d1557aSZiyue Zhang 163235d1557aSZiyue Zhang if (env.AlwaysBasicDiff || env.EnableDifftest) { 163383ba63b3SXuan Hu val difftest = DifftestModule(new DiffVecCSRState) 163483ba63b3SXuan Hu difftest.coreid := csrio.hartId 163583ba63b3SXuan Hu difftest.vstart := vstart 163683ba63b3SXuan Hu difftest.vxsat := vcsr.asTypeOf(new VcsrStruct).vxsat 163783ba63b3SXuan Hu difftest.vxrm := vcsr.asTypeOf(new VcsrStruct).vxrm 163883ba63b3SXuan Hu difftest.vcsr := vcsr 163983ba63b3SXuan Hu difftest.vl := vl 164083ba63b3SXuan Hu difftest.vtype := vtype 164183ba63b3SXuan Hu difftest.vlenb := vlenb 164235d1557aSZiyue Zhang } 1643c84054caSLinJiawei} 1644075d4937Sjunxiong-jiclass PFEvent(implicit p: Parameters) extends XSModule { 1645cd365d4cSrvcoresjw val io = IO(new Bundle { 1646cd365d4cSrvcoresjw val distribute_csr = Flipped(new DistributedCSRIO()) 1647cd365d4cSrvcoresjw val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1648cd365d4cSrvcoresjw }) 1649cd365d4cSrvcoresjw 1650cd365d4cSrvcoresjw val w = io.distribute_csr.w 1651cd365d4cSrvcoresjw 16525fd90906Srvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 16535fd90906Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 16545fd90906Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 16555fd90906Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 1656cd365d4cSrvcoresjw 165712c44ce5Srvcoresjw val perfEventMapping = (0 until 29).map(i => {Map( 1658075d4937Sjunxiong-ji MaskedRegMap(addr = CSRs.mhpmevent3 + i, 165912c44ce5Srvcoresjw reg = perfEvents(i), 166012c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)) 166112c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 1662cd365d4cSrvcoresjw 1663cd365d4cSrvcoresjw val rdata = Wire(UInt(XLEN.W)) 1664cd365d4cSrvcoresjw MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 16655fd90906Srvcoresjw for(i <- 0 until 29){ 16665fd90906Srvcoresjw io.hpmevent(i) := perfEvents(i) 16675fd90906Srvcoresjw } 1668cd365d4cSrvcoresjw} 1669a67fd0f5SGuanghui Cheng*/ 1670