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._ 31c84054caSLinJiawei 3272951335SLi Qianruo// Trigger Tdata1 bundles 3372951335SLi Qianruotrait HasTriggerConst { 3472951335SLi Qianruo def I_Trigger = 0.U 3572951335SLi Qianruo def S_Trigger = 1.U 3672951335SLi Qianruo def L_Trigger = 2.U 37bc63e578SLi Qianruo def GenESL(triggerType: UInt) = Cat((triggerType === I_Trigger), (triggerType === S_Trigger), (triggerType === L_Trigger)) 3872951335SLi Qianruo} 3972951335SLi Qianruo 4072951335SLi Qianruoclass TdataBundle extends Bundle { 41716f717fSLi Qianruo val ttype = UInt(4.W) 42716f717fSLi Qianruo val dmode = Bool() 43716f717fSLi Qianruo val maskmax = UInt(6.W) 44716f717fSLi Qianruo val zero1 = UInt(30.W) 45716f717fSLi Qianruo val sizehi = UInt(2.W) 46716f717fSLi Qianruo val hit = Bool() 4772951335SLi Qianruo val select = Bool() 4872951335SLi Qianruo val timing = Bool() 49716f717fSLi Qianruo val sizelo = UInt(2.W) 50716f717fSLi Qianruo val action = UInt(4.W) 5172951335SLi Qianruo val chain = Bool() 52716f717fSLi Qianruo val matchType = UInt(4.W) 5372951335SLi Qianruo val m = Bool() 54716f717fSLi Qianruo val zero2 = Bool() 5572951335SLi Qianruo val s = Bool() 5672951335SLi Qianruo val u = Bool() 57716f717fSLi Qianruo val execute = Bool() 58716f717fSLi Qianruo val store = Bool() 59716f717fSLi Qianruo val load = Bool() 6072951335SLi Qianruo} 6172951335SLi Qianruo 622225d46eSJiawei Linclass FpuCsrIO extends Bundle { 637f1506e3SLinJiawei val fflags = Output(Valid(UInt(5.W))) 64c84054caSLinJiawei val isIllegal = Output(Bool()) 65c84054caSLinJiawei val dirty_fs = Output(Bool()) 66c84054caSLinJiawei val frm = Input(UInt(3.W)) 67c84054caSLinJiawei} 68c84054caSLinJiawei 69b2e234ebSLinJiawei 702225d46eSJiawei Linclass PerfCounterIO(implicit p: Parameters) extends XSBundle { 711ca0e4f3SYinan Xu val perfEventsFrontend = Vec(numCSRPCntFrontend, new PerfEvent) 721ca0e4f3SYinan Xu val perfEventsCtrl = Vec(numCSRPCntCtrl, new PerfEvent) 731ca0e4f3SYinan Xu val perfEventsLsu = Vec(numCSRPCntLsu, new PerfEvent) 741ca0e4f3SYinan Xu val perfEventsHc = Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent) 75edd6ddbcSwakafa val retiredInstr = UInt(3.W) 76edd6ddbcSwakafa val frontendInfo = new Bundle { 77edd6ddbcSwakafa val ibufFull = Bool() 78e0d9a9f0SLingrui98 val bpuInfo = new Bundle { 79e0d9a9f0SLingrui98 val bpRight = UInt(XLEN.W) 80e0d9a9f0SLingrui98 val bpWrong = UInt(XLEN.W) 81e0d9a9f0SLingrui98 } 82edd6ddbcSwakafa } 83edd6ddbcSwakafa val ctrlInfo = new Bundle { 849aca92b9SYinan Xu val robFull = Bool() 85edd6ddbcSwakafa val intdqFull = Bool() 86edd6ddbcSwakafa val fpdqFull = Bool() 87edd6ddbcSwakafa val lsdqFull = Bool() 88edd6ddbcSwakafa } 89edd6ddbcSwakafa val memInfo = new Bundle { 90edd6ddbcSwakafa val sqFull = Bool() 91edd6ddbcSwakafa val lqFull = Bool() 92edd6ddbcSwakafa val dcacheMSHRFull = Bool() 93edd6ddbcSwakafa } 94e0d9a9f0SLingrui98 95edd6ddbcSwakafa val cacheInfo = new Bundle { 96edd6ddbcSwakafa val l2MSHRFull = Bool() 97edd6ddbcSwakafa val l3MSHRFull = Bool() 98edd6ddbcSwakafa val l2nAcquire = UInt(XLEN.W) 99edd6ddbcSwakafa val l2nAcquireMiss = UInt(XLEN.W) 100edd6ddbcSwakafa val l3nAcquire = UInt(XLEN.W) 101edd6ddbcSwakafa val l3nAcquireMiss = UInt(XLEN.W) 102edd6ddbcSwakafa } 10362ab1317SYinan Xu} 10462ab1317SYinan Xu 1052225d46eSJiawei Linclass CSRFileIO(implicit p: Parameters) extends XSBundle { 106f57f7f2aSYangyu Chen val hartId = Input(UInt(hartIdLen.W)) 107129a273eSYinan Xu // output (for func === CSROpType.jmp) 108edd6ddbcSwakafa val perf = Input(new PerfCounterIO) 1098635f18fSwangkaifan val isPerfCnt = Output(Bool()) 110129a273eSYinan Xu // to FPU 111129a273eSYinan Xu val fpu = Flipped(new FpuCsrIO) 112bf9968b2SYinan Xu // from rob 1133a474d38SYinan Xu val exception = Flipped(ValidIO(new ExceptionInfo)) 114129a273eSYinan Xu // to ROB 115ac5a5d53SLinJiawei val isXRet = Output(Bool()) 116129a273eSYinan Xu val trapTarget = Output(UInt(VAddrBits.W)) 117129a273eSYinan Xu val interrupt = Output(Bool()) 1185c95ea2eSYinan Xu val wfi_event = Output(Bool()) 119129a273eSYinan Xu // from LSQ 120129a273eSYinan Xu val memExceptionVAddr = Input(UInt(VAddrBits.W)) 121*d0de7e4aSpeixiaokun val memExceptionGPAddr = Input(UInt(GPAddrBits.W)) 122129a273eSYinan Xu // from outside cpu,externalInterrupt 123129a273eSYinan Xu val externalInterrupt = new ExternalInterruptIO 124129a273eSYinan Xu // TLB 125129a273eSYinan Xu val tlb = Output(new TlbCsrBundle) 126d4aca96cSlqre // Debug Mode 127d7dd1af1SLi Qianruo // val singleStep = Output(Bool()) 128d4aca96cSlqre val debugMode = Output(Bool()) 129e5adbe81SLemover // to Fence to disable sfence 130e5adbe81SLemover val disableSfence = Output(Bool()) 131*d0de7e4aSpeixiaokun // to Fence to disable hfence.gvma 132*d0de7e4aSpeixiaokun val disableHfenceg = Output(Bool()) 133*d0de7e4aSpeixiaokun // to Fence to disable hfence.vvma 134*d0de7e4aSpeixiaokun val disableHfencev = Output(Bool()) 135e377d77eSWilliam Wang // Custom microarchiture ctrl signal 136e377d77eSWilliam Wang val customCtrl = Output(new CustomCSRCtrlIO) 137e377d77eSWilliam Wang // distributed csr write 13870899835SWilliam Wang val distributedUpdate = Vec(2, Flipped(new DistributedCSRUpdateReq)) 13935a47a38SYinan Xu} 14035a47a38SYinan Xu 14172951335SLi Qianruoclass CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMPMethod with PMAMethod with HasTriggerConst 14235a47a38SYinan Xu{ 14335a47a38SYinan Xu val csrio = IO(new CSRFileIO) 144c84054caSLinJiawei 145e18c367fSLinJiawei val cfIn = io.in.bits.uop.cf 146e18c367fSLinJiawei val cfOut = Wire(new CtrlFlow) 147e18c367fSLinJiawei cfOut := cfIn 148e18c367fSLinJiawei val flushPipe = Wire(Bool()) 149c84054caSLinJiawei 150e18c367fSLinJiawei val (valid, src1, src2, func) = ( 151e18c367fSLinJiawei io.in.valid, 152e18c367fSLinJiawei io.in.bits.src(0), 153e18c367fSLinJiawei io.in.bits.uop.ctrl.imm, 154e18c367fSLinJiawei io.in.bits.uop.ctrl.fuOpType 155e18c367fSLinJiawei ) 156c84054caSLinJiawei 157c84054caSLinJiawei // CSR define 158*d0de7e4aSpeixiaokun val virtMode = RegInit(false.B) 159*d0de7e4aSpeixiaokun csrio.customCtrl.virtMode := virtMode 160c84054caSLinJiawei 161c84054caSLinJiawei class Priv extends Bundle { 162c84054caSLinJiawei val m = Output(Bool()) 163*d0de7e4aSpeixiaokun val h = Output(Bool()) // unused 164c84054caSLinJiawei val s = Output(Bool()) 165c84054caSLinJiawei val u = Output(Bool()) 166c84054caSLinJiawei } 167c84054caSLinJiawei 168c84054caSLinJiawei val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U) 169c84054caSLinJiawei 170d4aca96cSlqre class DcsrStruct extends Bundle { 1715b0f0029SXuan Hu val debugver = Output(UInt(4.W)) // 28 1725b0f0029SXuan Hu val pad1 = Output(UInt(10.W))// 18 1735b0f0029SXuan Hu val ebreakvs = Output(Bool()) // 17 reserved for Hypervisor debug 1745b0f0029SXuan Hu val ebreakvu = Output(Bool()) // 16 reserved for Hypervisor debug 1755b0f0029SXuan Hu val ebreakm = Output(Bool()) // 15 1765b0f0029SXuan Hu val pad0 = Output(Bool()) // 14 ebreakh has been removed 1775b0f0029SXuan Hu val ebreaks = Output(Bool()) // 13 1785b0f0029SXuan Hu val ebreaku = Output(Bool()) // 12 1795b0f0029SXuan Hu val stepie = Output(Bool()) // 11 1805b0f0029SXuan Hu val stopcount = Output(Bool()) // 10 1815b0f0029SXuan Hu val stoptime = Output(Bool()) // 9 1825b0f0029SXuan Hu val cause = Output(UInt(3.W)) // 6 1835b0f0029SXuan Hu val v = Output(Bool()) // 5 1845b0f0029SXuan Hu val mprven = Output(Bool()) // 4 1855b0f0029SXuan Hu val nmip = Output(Bool()) // 3 1865b0f0029SXuan Hu val step = Output(Bool()) // 2 1875b0f0029SXuan Hu val prv = Output(UInt(2.W)) // 0 188d4aca96cSlqre } 189d4aca96cSlqre 1905b0f0029SXuan Hu object DcsrStruct extends DcsrStruct { 1915b0f0029SXuan Hu private def debugver_offset = 28 1925b0f0029SXuan Hu private def stopcount_offset = 10 1935b0f0029SXuan Hu private def stoptime_offset = 9 1945b0f0029SXuan Hu private def mprven_offset = 5 1955b0f0029SXuan Hu private def prv_offset = 0 1965b0f0029SXuan Hu def init: UInt = ( 1975b0f0029SXuan Hu (4L << debugver_offset) | /* Debug implementation as it described in 0.13 draft */ 1985b0f0029SXuan Hu (0L << stopcount_offset) | /* Stop count updating has not been supported */ 1995b0f0029SXuan Hu (0L << stoptime_offset) | /* Stop time updating has not been supported */ 2005b0f0029SXuan Hu (0L << mprven_offset) | /* Whether use mstatus.perven mprven */ 2015b0f0029SXuan Hu (3L << prv_offset) /* Hart was operating in Privilege M when Debug Mode was entered */ 2025b0f0029SXuan Hu ).U 2035b0f0029SXuan Hu } 2045b0f0029SXuan Hu require(new DcsrStruct().getWidth == 32) 2055b0f0029SXuan Hu 206c84054caSLinJiawei class MstatusStruct extends Bundle { 207c84054caSLinJiawei val sd = Output(UInt(1.W)) 2088e7b11e5SWilliam Wang 209*d0de7e4aSpeixiaokun val pad1 = if (XLEN == 64 && HasHExtension) Output(UInt(23.W)) else if (XLEN == 64) Output(UInt(25.W)) else null 210*d0de7e4aSpeixiaokun val mpv = if (XLEN == 64 && HasHExtension) Output(UInt(1.W)) else null 211*d0de7e4aSpeixiaokun val gva = if (XLEN == 64 && HasHExtension) Output(UInt(1.W)) else null 2127d9edc86SLemover val mbe = if (XLEN == 64) Output(UInt(1.W)) else null 2137d9edc86SLemover val sbe = if (XLEN == 64) Output(UInt(1.W)) else null 2148e7b11e5SWilliam Wang val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 2158e7b11e5SWilliam Wang val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 2168e7b11e5SWilliam Wang val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 2178e7b11e5SWilliam Wang 218c84054caSLinJiawei val tsr = Output(UInt(1.W)) 219c84054caSLinJiawei val tw = Output(UInt(1.W)) 2208e7b11e5SWilliam Wang val tvm = Output(UInt(1.W)) 221c84054caSLinJiawei val mxr = Output(UInt(1.W)) 222c84054caSLinJiawei val sum = Output(UInt(1.W)) 223c84054caSLinJiawei val mprv = Output(UInt(1.W)) 224c84054caSLinJiawei val xs = Output(UInt(2.W)) 225c84054caSLinJiawei val fs = Output(UInt(2.W)) 226c84054caSLinJiawei val mpp = Output(UInt(2.W)) 227*d0de7e4aSpeixiaokun val vs = Output(UInt(2.W)) 228c84054caSLinJiawei val spp = Output(UInt(1.W)) 229c84054caSLinJiawei val pie = new Priv 230c84054caSLinJiawei val ie = new Priv 231c84054caSLinJiawei assert(this.getWidth == XLEN) 2327d9edc86SLemover 2337d9edc86SLemover def ube = pie.h // a little ugly 2347d9edc86SLemover def ube_(r: UInt): Unit = { 2357d9edc86SLemover pie.h := r(0) 2367d9edc86SLemover } 237c84054caSLinJiawei } 238c84054caSLinJiawei 239*d0de7e4aSpeixiaokun class HstatusStruct extends Bundle { 240*d0de7e4aSpeixiaokun val pad4 = if (HSXLEN == 64) Output(UInt(30.W)) else null 241*d0de7e4aSpeixiaokun val vsxl = if (HSXLEN == 64) Output(UInt(2.W)) else null 242*d0de7e4aSpeixiaokun val pad3 = Output(UInt(9.W)) 243*d0de7e4aSpeixiaokun val vtsr = Output(UInt(1.W)) 244*d0de7e4aSpeixiaokun val vtw = Output(UInt(1.W)) 245*d0de7e4aSpeixiaokun val vtvm = Output(UInt(1.W)) 246*d0de7e4aSpeixiaokun val pad2 = Output(UInt(2.W)) 247*d0de7e4aSpeixiaokun val vgein = Output(UInt(6.W)) 248*d0de7e4aSpeixiaokun val pad1 = Output(UInt(2.W)) 249*d0de7e4aSpeixiaokun val hu = Output(UInt(1.W)) 250*d0de7e4aSpeixiaokun val spvp = Output(UInt(1.W)) 251*d0de7e4aSpeixiaokun val spv = Output(UInt(1.W)) 252*d0de7e4aSpeixiaokun val gva = Output(UInt(1.W)) 253*d0de7e4aSpeixiaokun val vsbe = Output(UInt(1.W)) 254*d0de7e4aSpeixiaokun val pad0 = Output(UInt(5.W)) 255*d0de7e4aSpeixiaokun assert(this.getWidth == XLEN) 256*d0de7e4aSpeixiaokun } 257*d0de7e4aSpeixiaokun 258c84054caSLinJiawei class Interrupt extends Bundle { 259d4aca96cSlqre// val d = Output(Bool()) // Debug 260c84054caSLinJiawei val e = new Priv 261c84054caSLinJiawei val t = new Priv 262c84054caSLinJiawei val s = new Priv 263c84054caSLinJiawei } 264c84054caSLinJiawei 265d4aca96cSlqre // Debug CSRs 2665b0f0029SXuan Hu val dcsr = RegInit(UInt(32.W), DcsrStruct.init) 267d4aca96cSlqre val dpc = Reg(UInt(64.W)) 2685b0f0029SXuan Hu val dscratch0 = Reg(UInt(64.W)) 269d4aca96cSlqre val dscratch1 = Reg(UInt(64.W)) 270d4aca96cSlqre val debugMode = RegInit(false.B) 2715b0f0029SXuan Hu val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable 272d4aca96cSlqre csrio.debugMode := debugMode 273d4aca96cSlqre 274d4aca96cSlqre val dpcPrev = RegNext(dpc) 2751097f021SLi Qianruo XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x\n", dpc, dpcPrev) 276d4aca96cSlqre 277d4aca96cSlqre // dcsr value table 278d4aca96cSlqre // | debugver | 0100 279d4aca96cSlqre // | zero | 10 bits of 0 280d4aca96cSlqre // | ebreakvs | 0 281d4aca96cSlqre // | ebreakvu | 0 282d4aca96cSlqre // | ebreakm | 1 if ebreak enters debug 283d4aca96cSlqre // | zero | 0 284d4aca96cSlqre // | ebreaks | 285d4aca96cSlqre // | ebreaku | 286052ee9a1SLi Qianruo // | stepie | disable interrupts in singlestep 287d4aca96cSlqre // | stopcount| stop counter, 0 288d4aca96cSlqre // | stoptime | stop time, 0 289d4aca96cSlqre // | cause | 3 bits read only 290d4aca96cSlqre // | v | 0 291d4aca96cSlqre // | mprven | 1 292d4aca96cSlqre // | nmip | read only 293d4aca96cSlqre // | step | 294d4aca96cSlqre // | prv | 2 bits 295ad3ba452Szhanglinjuan 296d4aca96cSlqre val dcsrData = Wire(new DcsrStruct) 297d4aca96cSlqre dcsrData := dcsr.asTypeOf(new DcsrStruct) 298d7dd1af1SLi Qianruo val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(4) | GenMask(2, 0), XLEN)// Dcsr write mask 299d4aca96cSlqre def dcsrUpdateSideEffect(dcsr: UInt): UInt = { 300d4aca96cSlqre val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct)) 301d4aca96cSlqre val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11 302d4aca96cSlqre dcsrNew 303d4aca96cSlqre } 304d7dd1af1SLi Qianruo // csrio.singleStep := dcsrData.step 305d7dd1af1SLi Qianruo csrio.customCtrl.singlestep := dcsrData.step && !debugMode 306d4aca96cSlqre 30772951335SLi Qianruo // Trigger CSRs 30872951335SLi Qianruo 309716f717fSLi Qianruo val type_config = Array( 310716f717fSLi Qianruo 0.U -> I_Trigger, 1.U -> I_Trigger, 311716f717fSLi Qianruo 2.U -> S_Trigger, 3.U -> S_Trigger, 312716f717fSLi Qianruo 4.U -> L_Trigger, 5.U -> L_Trigger, // No.5 Load Trigger 313716f717fSLi Qianruo 6.U -> I_Trigger, 7.U -> S_Trigger, 314716f717fSLi Qianruo 8.U -> I_Trigger, 9.U -> L_Trigger 315716f717fSLi Qianruo ) 31645f43e6eSTang Haojin def TypeLookup(select: UInt) = MuxLookup(select, I_Trigger)(type_config) 317716f717fSLi Qianruo 318ddb65c47SLi Qianruo val tdata1Phy = RegInit(VecInit(List.fill(10) {(2L << 60L).U(64.W)})) // init ttype 2 31972951335SLi Qianruo val tdata2Phy = Reg(Vec(10, UInt(64.W))) 32072951335SLi Qianruo val tselectPhy = RegInit(0.U(4.W)) 321716f717fSLi Qianruo val tinfo = RegInit(2.U(64.W)) 32272951335SLi Qianruo val tControlPhy = RegInit(0.U(64.W)) 32384e47f35SLi Qianruo val triggerAction = RegInit(false.B) 324716f717fSLi Qianruo 325ba762693SYinan Xu def ReadTdata1(rdata: UInt) = rdata | Cat(triggerAction, 0.U(12.W)) // fix action 326ba762693SYinan Xu def WriteTdata1(wdata: UInt): UInt = { 327ba762693SYinan Xu val tdata1 = WireInit(tdata1Phy(tselectPhy).asTypeOf(new TdataBundle)) 328716f717fSLi Qianruo val wdata_wire = WireInit(wdata.asTypeOf(new TdataBundle)) 329716f717fSLi Qianruo val tdata1_new = WireInit(wdata.asTypeOf(new TdataBundle)) 330716f717fSLi Qianruo XSDebug(src2(11, 0) === Tdata1.U && valid && func =/= CSROpType.jmp, p"Debug Mode: tdata1(${tselectPhy})is written, the actual value is ${wdata}\n") 33184e47f35SLi Qianruo// tdata1_new.hit := wdata(20) 332ddb65c47SLi Qianruo tdata1_new.ttype := tdata1.ttype 333d7dd1af1SLi Qianruo tdata1_new.dmode := 0.U // Mux(debugMode, wdata_wire.dmode, tdata1.dmode) 334ddb65c47SLi Qianruo tdata1_new.maskmax := 0.U 335ddb65c47SLi Qianruo tdata1_new.hit := 0.U 336716f717fSLi Qianruo tdata1_new.select := (TypeLookup(tselectPhy) === I_Trigger) && wdata_wire.select 337716f717fSLi Qianruo when(wdata_wire.action <= 1.U){ 338716f717fSLi Qianruo triggerAction := tdata1_new.action(0) 339716f717fSLi Qianruo } .otherwise{ 340716f717fSLi Qianruo tdata1_new.action := tdata1.action 341716f717fSLi Qianruo } 342ddb65c47SLi Qianruo tdata1_new.timing := false.B // hardwire this because we have singlestep 343716f717fSLi Qianruo tdata1_new.zero1 := 0.U 344716f717fSLi Qianruo tdata1_new.zero2 := 0.U 345716f717fSLi Qianruo tdata1_new.chain := !tselectPhy(0) && wdata_wire.chain 346716f717fSLi Qianruo when(wdata_wire.matchType =/= 0.U && wdata_wire.matchType =/= 2.U && wdata_wire.matchType =/= 3.U) { 347716f717fSLi Qianruo tdata1_new.matchType := tdata1.matchType 348716f717fSLi Qianruo } 349ddb65c47SLi Qianruo tdata1_new.sizehi := Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 0.U, 1.U) 350ddb65c47SLi Qianruo tdata1_new.sizelo:= Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 3.U, 1.U) 351716f717fSLi Qianruo tdata1_new.execute := TypeLookup(tselectPhy) === I_Trigger 352716f717fSLi Qianruo tdata1_new.store := TypeLookup(tselectPhy) === S_Trigger 353716f717fSLi Qianruo tdata1_new.load := TypeLookup(tselectPhy) === L_Trigger 354ba762693SYinan Xu tdata1_new.asUInt 35572951335SLi Qianruo } 35672951335SLi Qianruo 35772951335SLi Qianruo def WriteTselect(wdata: UInt) = { 358716f717fSLi Qianruo Mux(wdata < 10.U, wdata(3, 0), tselectPhy) 35972951335SLi Qianruo } 36072951335SLi Qianruo 36172951335SLi Qianruo val tcontrolWriteMask = ZeroExt(GenMask(3) | GenMask(7), XLEN) 36272951335SLi Qianruo 36372951335SLi Qianruo 36472951335SLi Qianruo def GenTdataDistribute(tdata1: TdataBundle, tdata2: UInt): MatchTriggerIO = { 36572951335SLi Qianruo val res = Wire(new MatchTriggerIO) 36672951335SLi Qianruo res.matchType := tdata1.matchType 36772951335SLi Qianruo res.select := tdata1.select 36872951335SLi Qianruo res.timing := tdata1.timing 36984e47f35SLi Qianruo res.action := triggerAction 37072951335SLi Qianruo res.chain := tdata1.chain 37172951335SLi Qianruo res.tdata2 := tdata2 37272951335SLi Qianruo res 37372951335SLi Qianruo } 37472951335SLi Qianruo 37545f43e6eSTang Haojin csrio.customCtrl.frontend_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U)(Seq( 37672951335SLi Qianruo 0.U -> 0.U, 37772951335SLi Qianruo 1.U -> 1.U, 37872951335SLi Qianruo 6.U -> 2.U, 37972951335SLi Qianruo 8.U -> 3.U 38072951335SLi Qianruo )) 38145f43e6eSTang Haojin csrio.customCtrl.mem_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U)(Seq( 38272951335SLi Qianruo 2.U -> 0.U, 38372951335SLi Qianruo 3.U -> 1.U, 38472951335SLi Qianruo 4.U -> 2.U, 38572951335SLi Qianruo 5.U -> 3.U, 38672951335SLi Qianruo 7.U -> 4.U, 38772951335SLi Qianruo 9.U -> 5.U 38872951335SLi Qianruo )) 389716f717fSLi Qianruo csrio.customCtrl.frontend_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy).asTypeOf(new TdataBundle), tdata2Phy(tselectPhy)) 390716f717fSLi Qianruo csrio.customCtrl.mem_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy).asTypeOf(new TdataBundle), tdata2Phy(tselectPhy)) 39172951335SLi Qianruo 392c84054caSLinJiawei // Machine-Level CSRs 393a4e57ea3SLi Qianruo // mtvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 394a4e57ea3SLi Qianruo val mtvecMask = ~(0x2.U(XLEN.W)) 395c84054caSLinJiawei val mtvec = RegInit(UInt(XLEN.W), 0.U) 396c84054caSLinJiawei val mcounteren = RegInit(UInt(XLEN.W), 0.U) 397c84054caSLinJiawei val mcause = RegInit(UInt(XLEN.W), 0.U) 398c84054caSLinJiawei val mtval = RegInit(UInt(XLEN.W), 0.U) 399*d0de7e4aSpeixiaokun val mtval2 = RegInit(UInt(XLEN.W), 0.U) 400*d0de7e4aSpeixiaokun val mtinst = RegInit(UInt(XLEN.W), 0.U) 401*d0de7e4aSpeixiaokun val mepc = RegInit(UInt(XLEN.W), 0.U) 402e30fd06aSYinan Xu // Page 36 in riscv-priv: The low bit of mepc (mepc[0]) is always zero. 403e30fd06aSYinan Xu val mepcMask = ~(0x1.U(XLEN.W)) 404c84054caSLinJiawei 405c84054caSLinJiawei val mie = RegInit(0.U(XLEN.W)) 406c84054caSLinJiawei val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 4075dabf2dfSYinan Xu val mipReg = RegInit(0.U(XLEN.W)) 408*d0de7e4aSpeixiaokun val mipMask = ZeroExt(GenMask(9) | GenMask(5) | GenMask(1), XLEN) 409c84054caSLinJiawei val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 410c84054caSLinJiawei 411*d0de7e4aSpeixiaokun val mip_mie_WMask_H = if(HasHExtension){((1 << 2) | (1 << 6) | (1 << 10) | (1 << 12)).U(XLEN.W)}else{0.U(XLEN.W)} 412*d0de7e4aSpeixiaokun val vssip_Mask = (1 << 2).U(XLEN.W) 413*d0de7e4aSpeixiaokun 414*d0de7e4aSpeixiaokun val mipWMask = vssip_Mask | ((1 << 9) | (1 << 5) | (1 << 1)).U(XLEN.W) 415*d0de7e4aSpeixiaokun val mieWMask = mip_mie_WMask_H | ((1 << 11) | (1 << 9) | (1 << 7) | (1 << 5) | (1 << 3) | (1 << 1)).U(XLEN.W) 416*d0de7e4aSpeixiaokun 41767ba96b4SYinan Xu def getMisaMxl(mxl: BigInt): BigInt = mxl << (XLEN - 2) 41867ba96b4SYinan Xu def getMisaExt(ext: Char): Long = 1 << (ext.toInt - 'a'.toInt) 419c84054caSLinJiawei var extList = List('a', 's', 'i', 'u') 420c84054caSLinJiawei if (HasMExtension) { extList = extList :+ 'm' } 421c84054caSLinJiawei if (HasCExtension) { extList = extList :+ 'c' } 422*d0de7e4aSpeixiaokun if (HasHExtension) { extList = extList :+ 'h' } 423c84054caSLinJiawei if (HasFPU) { extList = extList ++ List('f', 'd') } 424*d0de7e4aSpeixiaokun val misaInitVal = getMisaMxl(2) | extList.foldLeft(0L)((sum, i) => sum | getMisaExt(i)) //"h8000000000141185".U 42567ba96b4SYinan Xu val misa = RegInit(UInt(XLEN.W), misaInitVal.U) 426bc5ff277Swangkaifan 427c84054caSLinJiawei // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 428c84054caSLinJiawei // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 429c84054caSLinJiawei 430c84054caSLinJiawei val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 431e1b773eaSLuo 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 432c84054caSLinJiawei val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 43367ba96b4SYinan Xu val mhartid = Reg(UInt(XLEN.W)) // the hardware thread running the code 43467ba96b4SYinan Xu when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 43567ba96b4SYinan Xu mhartid := csrio.hartId 43667ba96b4SYinan Xu } 4377d9edc86SLemover val mconfigptr = RegInit(UInt(XLEN.W), 0.U) // the read-only pointer pointing to the platform config structure, 0 for not supported. 43880dd83d8SYinan Xu val mstatus = RegInit("ha00002000".U(XLEN.W)) 439bc5ff277Swangkaifan 440c84054caSLinJiawei // mstatus Value Table 441c84054caSLinJiawei // | sd | 442c84054caSLinJiawei // | pad1 | 443c84054caSLinJiawei // | sxl | hardlinked to 10, use 00 to pass xv6 test 444e30fd06aSYinan Xu // | uxl | hardlinked to 10 445c84054caSLinJiawei // | pad0 | 446c84054caSLinJiawei // | tsr | 447c84054caSLinJiawei // | tw | 4488e7b11e5SWilliam Wang // | tvm | 449c84054caSLinJiawei // | mxr | 450c84054caSLinJiawei // | sum | 451c84054caSLinJiawei // | mprv | 452c84054caSLinJiawei // | xs | 00 | 45380dd83d8SYinan Xu // | fs | 01 | 454c84054caSLinJiawei // | mpp | 00 | 455c84054caSLinJiawei // | hpp | 00 | 456c84054caSLinJiawei // | spp | 0 | 4578e7b11e5SWilliam Wang // | pie | 0000 | pie.h is used as UBE 458c84054caSLinJiawei // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 459bc5ff277Swangkaifan 460c84054caSLinJiawei val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 461c84054caSLinJiawei def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 462c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 4638e7b11e5SWilliam Wang val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 464c84054caSLinJiawei mstatusNew 465c84054caSLinJiawei } 466c84054caSLinJiawei 467e30fd06aSYinan Xu val mstatusWMask = (~ZeroExt(( 468*d0de7e4aSpeixiaokun (if(HasHExtension) { 469*d0de7e4aSpeixiaokun GenMask(XLEN - 2, 40) | 470*d0de7e4aSpeixiaokun GenMask(37, 36) // MBE SBE 471*d0de7e4aSpeixiaokun } else 472*d0de7e4aSpeixiaokun GenMask(XLEN - 2, 36)) | // WPRI 473e30fd06aSYinan Xu GenMask(35, 32) | // SXL and UXL cannot be changed 474e30fd06aSYinan Xu GenMask(31, 23) | // WPRI 475705cbec3SLemover GenMask(16, 15) | // XS is read-only 476*d0de7e4aSpeixiaokun GenMask(10, 9) | // WPRI 477*d0de7e4aSpeixiaokun GenMask(6) | // WPRI 478*d0de7e4aSpeixiaokun GenMask(2) // WPRI 479*d0de7e4aSpeixiaokun ), 64)).asUInt 480*d0de7e4aSpeixiaokun val mstatusMask = (~ZeroExt(( 481*d0de7e4aSpeixiaokun (if (HasHExtension) { 482*d0de7e4aSpeixiaokun GenMask(XLEN - 2, 40) | 483*d0de7e4aSpeixiaokun GenMask(37, 36) // MBE SBE 484*d0de7e4aSpeixiaokun } else 485*d0de7e4aSpeixiaokun GenMask(XLEN - 2, 36)) | // WPRI 486*d0de7e4aSpeixiaokun GenMask(31, 23) | // WPRI 487*d0de7e4aSpeixiaokun GenMask(10, 9) | // WPRI 488*d0de7e4aSpeixiaokun GenMask(6) | // WPRI 489*d0de7e4aSpeixiaokun GenMask(2) // WPRI 4905d669833SYinan Xu ), 64)).asUInt 4918e7b11e5SWilliam Wang 492c84054caSLinJiawei val medeleg = RegInit(UInt(XLEN.W), 0.U) 493*d0de7e4aSpeixiaokun val midelegInit = if(HasHExtension){((1 << 12) | (1 << 10) | (1 << 6) | (1 << 2)).U}else{0.U} 494*d0de7e4aSpeixiaokun val medelegWMask = if(HasHExtension) { 495*d0de7e4aSpeixiaokun ((1 << 23) | (1 << 22) | (1 << 21) | (1 << 20) | (1 << 15) | (1 << 13) | (1 << 12) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 3) | (1 << 0)).U(XLEN.W) 496*d0de7e4aSpeixiaokun }else { 497*d0de7e4aSpeixiaokun "hb3ff".U(XLEN.W) 498*d0de7e4aSpeixiaokun } 499*d0de7e4aSpeixiaokun 500*d0de7e4aSpeixiaokun 501*d0de7e4aSpeixiaokun val mideleg = RegInit(UInt(XLEN.W), midelegInit) 502c84054caSLinJiawei val mscratch = RegInit(UInt(XLEN.W), 0.U) 503c84054caSLinJiawei 5046ade72d9Sxuzefan val menvcfg = RegInit(UInt(XLEN.W), 0.U) // !WARNING: there is no logic about this CSR. 5056ade72d9Sxuzefan 506*d0de7e4aSpeixiaokun val midelegWMask = "h222".U(XLEN.W) 507b6982e83SLemover // PMP Mapping 508ca2f90a6SLemover val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter 509ca2f90a6SLemover val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter 510ca2f90a6SLemover val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp) 511ca2f90a6SLemover val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma) 512672c4648Sceba // !WARNNING: pmp and pma CSRs are not checked in difftest. 513c84054caSLinJiawei 514*d0de7e4aSpeixiaokun // Supervisor-Level CSRs 515c84054caSLinJiawei 516c84054caSLinJiawei // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 5175dabf2dfSYinan Xu val sstatusWmask = "hc6122".U(XLEN.W) 518c84054caSLinJiawei // Sstatus Write Mask 519c84054caSLinJiawei // ------------------------------------------------------- 520c84054caSLinJiawei // 19 9 5 2 521c84054caSLinJiawei // 0 1100 0000 0001 0010 0010 522c84054caSLinJiawei // 0 c 0 1 2 2 523c84054caSLinJiawei // ------------------------------------------------------- 524c84054caSLinJiawei val sstatusRmask = sstatusWmask | "h8000000300018000".U 525c84054caSLinJiawei // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 526a4e57ea3SLi Qianruo // stvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 527a4e57ea3SLi Qianruo val stvecMask = ~(0x2.U(XLEN.W)) 528c84054caSLinJiawei val stvec = RegInit(UInt(XLEN.W), 0.U) 529c84054caSLinJiawei // val sie = RegInit(0.U(XLEN.W)) 530c84054caSLinJiawei val sieMask = "h222".U & mideleg 531c84054caSLinJiawei val sipMask = "h222".U & mideleg 5325dabf2dfSYinan Xu val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode 53334230194Sjinyue110 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 534df2b1479SZhangZifei // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 53545f497a4Shappy-lx // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0 53645f497a4Shappy-lx // TODO: use config to control the length of asid 53745f497a4Shappy-lx // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0 538705cbec3SLemover val satpMask = Cat("h8".U(Satp_Mode_len.W), satp_part_wmask(Satp_Asid_len, AsidLength), satp_part_wmask(Satp_Addr_len, PAddrBits-12)) 539c84054caSLinJiawei val sepc = RegInit(UInt(XLEN.W), 0.U) 540e30fd06aSYinan Xu // Page 60 in riscv-priv: The low bit of sepc (sepc[0]) is always zero. 541e30fd06aSYinan Xu val sepcMask = ~(0x1.U(XLEN.W)) 542c84054caSLinJiawei val scause = RegInit(UInt(XLEN.W), 0.U) 543*d0de7e4aSpeixiaokun val stval = RegInit(UInt(XLEN.W), 0.U) 544c84054caSLinJiawei val sscratch = RegInit(UInt(XLEN.W), 0.U) 545c84054caSLinJiawei val scounteren = RegInit(UInt(XLEN.W), 0.U) 5466ade72d9Sxuzefan val senvcfg = RegInit(UInt(XLEN.W), 0.U) // !WARNING: there is no logic about this CSR. 547fcff7e94SZhangZifei 548eedc2e58SSteve Gou // sbpctl 549eedc2e58SSteve Gou // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB} 550eedc2e58SSteve Gou val sbpctl = RegInit(UInt(XLEN.W), "h7f".U) 551eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0) 552eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.btb_enable := sbpctl(1) 553eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.bim_enable := sbpctl(2) 554eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3) 555eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.sc_enable := sbpctl(4) 556eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ras_enable := sbpctl(5) 557eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6) 5582b8b2e7aSWilliam Wang 559ecccf78fSJay // spfctl Bit 0: L1I Cache Prefetcher Enable 5602b8b2e7aSWilliam Wang // spfctl Bit 1: L2Cache Prefetcher Enable 56185de5caeSLinJiawei // spfctl Bit 2: L1D Cache Prefetcher Enable 56285de5caeSLinJiawei // spfctl Bit 3: L1D train prefetch on hit 56385de5caeSLinJiawei // spfctl Bit 4: L1D prefetch enable agt 56485de5caeSLinJiawei // spfctl Bit 5: L1D prefetch enable pht 565c65495a4SLinJiawei // spfctl Bit [9:6]: L1D prefetch active page threshold 566c65495a4SLinJiawei // spfctl Bit [15:10]: L1D prefetch active page stride 5675d13017eSLinJiawei // turn off L2 BOP, turn on L1 SMS by default 568c65495a4SLinJiawei val spfctl = RegInit(UInt(XLEN.W), Seq( 569edbf1204SLinJiawei 0 << 17, // L2 pf store only [17] init: false 570edbf1204SLinJiawei 1 << 16, // L1D pf enable stride [16] init: true 571f1d78cf7SLinJiawei 30 << 10, // L1D active page stride [15:10] init: 30 572f1d78cf7SLinJiawei 12 << 6, // L1D active page threshold [9:6] init: 12 573f1d78cf7SLinJiawei 1 << 5, // L1D enable pht [5] init: true 574f1d78cf7SLinJiawei 1 << 4, // L1D enable agt [4] init: true 575f1d78cf7SLinJiawei 0 << 3, // L1D train on hit [3] init: false 576f1d78cf7SLinJiawei 1 << 2, // L1D pf enable [2] init: true 577f1d78cf7SLinJiawei 1 << 1, // L2 pf enable [1] init: true 578f1d78cf7SLinJiawei 1 << 0, // L1I pf enable [0] init: true 579c65495a4SLinJiawei ).reduce(_|_).U(XLEN.W)) 580ecccf78fSJay csrio.customCtrl.l1I_pf_enable := spfctl(0) 58135a47a38SYinan Xu csrio.customCtrl.l2_pf_enable := spfctl(1) 58285de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable := spfctl(2) 58385de5caeSLinJiawei csrio.customCtrl.l1D_pf_train_on_hit := spfctl(3) 58485de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable_agt := spfctl(4) 58585de5caeSLinJiawei csrio.customCtrl.l1D_pf_enable_pht := spfctl(5) 5865d13017eSLinJiawei csrio.customCtrl.l1D_pf_active_threshold := spfctl(9, 6) 587c65495a4SLinJiawei csrio.customCtrl.l1D_pf_active_stride := spfctl(15, 10) 588edbf1204SLinJiawei csrio.customCtrl.l1D_pf_enable_stride := spfctl(16) 589edbf1204SLinJiawei csrio.customCtrl.l2_pf_store_only := spfctl(17) 5902b8b2e7aSWilliam Wang 591ecccf78fSJay // sfetchctl Bit 0: L1I Cache Parity check enable 592ecccf78fSJay val sfetchctl = RegInit(UInt(XLEN.W), "b0".U) 593ecccf78fSJay csrio.customCtrl.icache_parity_enable := sfetchctl(0) 594ecccf78fSJay 5952b8b2e7aSWilliam Wang // sdsid: Differentiated Services ID 5962b8b2e7aSWilliam Wang val sdsid = RegInit(UInt(XLEN.W), 0.U) 59735a47a38SYinan Xu csrio.customCtrl.dsid := sdsid 59835a47a38SYinan Xu 5992b8b2e7aSWilliam Wang // slvpredctl: load violation predict settings 6006ef4f6f6SYinan Xu // Default reset period: 2^16 6016ef4f6f6SYinan Xu // Why this number: reset more frequently while keeping the overhead low 6026ef4f6f6SYinan Xu // Overhead: extra two redirections in every 64K cycles => ~0.1% overhead 6036ef4f6f6SYinan Xu val slvpredctl = RegInit(UInt(XLEN.W), "h60".U) 6042b8b2e7aSWilliam Wang csrio.customCtrl.lvpred_disable := slvpredctl(0) 6052b8b2e7aSWilliam Wang csrio.customCtrl.no_spec_load := slvpredctl(1) 606c7160cd3SWilliam Wang csrio.customCtrl.storeset_wait_store := slvpredctl(2) 607c7160cd3SWilliam Wang csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3) 608c7160cd3SWilliam Wang csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4) 6092b8b2e7aSWilliam Wang 610f3f22d72SYinan Xu // smblockctl: memory block configurations 61137225120Ssfencevma // +------------------------------+---+----+----+-----+--------+ 61237225120Ssfencevma // |XLEN-1 8| 7 | 6 | 5 | 4 |3 0| 61337225120Ssfencevma // +------------------------------+---+----+----+-----+--------+ 61437225120Ssfencevma // | Reserved | O | CE | SP | LVC | Th | 61537225120Ssfencevma // +------------------------------+---+----+----+-----+--------+ 61637225120Ssfencevma // Description: 61737225120Ssfencevma // Bit 3-0 : Store buffer flush threshold (Th). 61837225120Ssfencevma // Bit 4 : Enable load violation check after reset (LVC). 61937225120Ssfencevma // Bit 5 : Enable soft-prefetch after reset (SP). 62037225120Ssfencevma // Bit 6 : Enable cache error after reset (CE). 62137225120Ssfencevma // Bit 7 : Enable uncache write outstanding (O). 62237225120Ssfencevma // Others : Reserved. 62337225120Ssfencevma 62467682d05SWilliam Wang val smblockctl_init_val = 62567ba96b4SYinan Xu (0xf & StoreBufferThreshold) | 62667ba96b4SYinan Xu (EnableLdVioCheckAfterReset.toInt << 4) | 62767ba96b4SYinan Xu (EnableSoftPrefetchAfterReset.toInt << 5) | 62867ba96b4SYinan Xu (EnableCacheErrorAfterReset.toInt << 6) 62967ba96b4SYinan Xu (EnableUncacheWriteOutstanding.toInt << 7) 63067ba96b4SYinan Xu val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val.U) 631f3f22d72SYinan Xu csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0) 63267682d05SWilliam Wang // bits 4: enable load load violation check 633a4e57ea3SLi Qianruo csrio.customCtrl.ldld_vio_check_enable := smblockctl(4) 634a4e57ea3SLi Qianruo csrio.customCtrl.soft_prefetch_enable := smblockctl(5) 635a4e57ea3SLi Qianruo csrio.customCtrl.cache_error_enable := smblockctl(6) 63637225120Ssfencevma csrio.customCtrl.uncache_write_outstanding_enable := smblockctl(7) 637a4e57ea3SLi Qianruo 638a4e57ea3SLi Qianruo println("CSR smblockctl init value:") 639a4e57ea3SLi Qianruo println(" Store buffer replace threshold: " + StoreBufferThreshold) 640a4e57ea3SLi Qianruo println(" Enable ld-ld vio check after reset: " + EnableLdVioCheckAfterReset) 641a4e57ea3SLi Qianruo println(" Enable soft prefetch after reset: " + EnableSoftPrefetchAfterReset) 642a4e57ea3SLi Qianruo println(" Enable cache error after reset: " + EnableCacheErrorAfterReset) 64337225120Ssfencevma println(" Enable uncache write outstanding: " + EnableUncacheWriteOutstanding) 644f3f22d72SYinan Xu 6455b47c58cSYinan Xu val srnctl = RegInit(UInt(XLEN.W), "h7".U) 6465b47c58cSYinan Xu csrio.customCtrl.fusion_enable := srnctl(0) 647af2f7849Shappy-lx csrio.customCtrl.svinval_enable := srnctl(1) 6485b47c58cSYinan Xu csrio.customCtrl.wfi_enable := srnctl(2) 649aac4464eSYinan Xu 650*d0de7e4aSpeixiaokun // Hypervisor CSRs 651*d0de7e4aSpeixiaokun val hstatusWMask = "h7003c0".U(XLEN.W) 652*d0de7e4aSpeixiaokun // hstatus: vtsr, vtw, vtvm, hu, spvp, spv, gva, 653*d0de7e4aSpeixiaokun val hstatus = RegInit("h200000000".U(XLEN.W)) 654*d0de7e4aSpeixiaokun val hstatusStruct = hstatus.asTypeOf(new HstatusStruct) 655*d0de7e4aSpeixiaokun val hedeleg = RegInit(UInt(XLEN.W), 0.U) 656*d0de7e4aSpeixiaokun val hideleg = RegInit(UInt(XLEN.W), 0.U) 657*d0de7e4aSpeixiaokun val hidelegRMask = mideleg 658*d0de7e4aSpeixiaokun val hidelegWMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 659*d0de7e4aSpeixiaokun val hgeie = RegInit(UInt(XLEN.W), 0.U) 660*d0de7e4aSpeixiaokun val htval = RegInit(UInt(XLEN.W), 0.U) 661*d0de7e4aSpeixiaokun // hvip hip hie is part of mip or mie 662*d0de7e4aSpeixiaokun val hvipMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 663*d0de7e4aSpeixiaokun val hipRMask = (((1 << 12).U | hvipMask) & mideleg) 664*d0de7e4aSpeixiaokun val hipWMask = ((1 << 2).U & mideleg)// vssip 665*d0de7e4aSpeixiaokun val hieMask = hipRMask 666*d0de7e4aSpeixiaokun val htinst = RegInit(UInt(XLEN.W), 0.U) 667*d0de7e4aSpeixiaokun val hgeip = RegInit(UInt(XLEN.W), 0.U) 668*d0de7e4aSpeixiaokun val henvcfg = RegInit(UInt(XLEN.W), 0.U) 669*d0de7e4aSpeixiaokun val hgatp = RegInit(UInt(XLEN.W), 0.U) 670*d0de7e4aSpeixiaokun val hgatpMask = Cat("h8".U(Hgatp_Mode_len.W), satp_part_wmask(Hgatp_Vmid_len, VmidLength), satp_part_wmask(Hgatp_Addr_len, PAddrBits-12)) 671*d0de7e4aSpeixiaokun val htimedelta = RegInit(UInt(XLEN.W), 0.U) 672*d0de7e4aSpeixiaokun val hcounteren = RegInit(UInt(XLEN.W), 0.U) 673*d0de7e4aSpeixiaokun 674*d0de7e4aSpeixiaokun val vsstatus = RegInit("ha00002000".U(XLEN.W)) 675*d0de7e4aSpeixiaokun val vsstatusStruct = vsstatus.asTypeOf(new MstatusStruct) 676*d0de7e4aSpeixiaokun //vsie vsip 677*d0de7e4aSpeixiaokun val vsMask = ((1 << 10) | (1 << 6) | (1 << 2)).U(XLEN.W) 678*d0de7e4aSpeixiaokun val vsip_ie_Mask = ZeroExt((hideleg & mideleg & vsMask), XLEN) 679*d0de7e4aSpeixiaokun val vsip_WMask = ZeroExt((hideleg & mideleg & vssip_Mask), XLEN) 680*d0de7e4aSpeixiaokun val vstvec = RegInit(UInt(XLEN.W), 0.U) 681*d0de7e4aSpeixiaokun val vsscratch = RegInit(UInt(XLEN.W), 0.U) 682*d0de7e4aSpeixiaokun val vsepc = RegInit(UInt(XLEN.W), 0.U) 683*d0de7e4aSpeixiaokun val vscause = RegInit(UInt(XLEN.W), 0.U) 684*d0de7e4aSpeixiaokun val vstval = RegInit(UInt(XLEN.W), 0.U) 685*d0de7e4aSpeixiaokun val vsatp = RegInit(UInt(XLEN.W), 0.U) 6862b8b2e7aSWilliam Wang val tlbBundle = Wire(new TlbCsrBundle) 68745f497a4Shappy-lx tlbBundle.satp.apply(satp) 688*d0de7e4aSpeixiaokun tlbBundle.vsatp.apply(vsatp) 689*d0de7e4aSpeixiaokun tlbBundle.hgatp.apply(hgatp) 6902b8b2e7aSWilliam Wang csrio.tlb := tlbBundle 6912b8b2e7aSWilliam Wang 692c84054caSLinJiawei // User-Level CSRs 693c84054caSLinJiawei val uepc = Reg(UInt(XLEN.W)) 694c84054caSLinJiawei 695c84054caSLinJiawei // fcsr 696c84054caSLinJiawei class FcsrStruct extends Bundle { 697c84054caSLinJiawei val reserved = UInt((XLEN-3-5).W) 698c84054caSLinJiawei val frm = UInt(3.W) 699c84054caSLinJiawei val fflags = UInt(5.W) 700c84054caSLinJiawei assert(this.getWidth == XLEN) 701c84054caSLinJiawei } 702c84054caSLinJiawei val fcsr = RegInit(0.U(XLEN.W)) 703c84054caSLinJiawei // set mstatus->sd and mstatus->fs when true 704c84054caSLinJiawei val csrw_dirty_fp_state = WireInit(false.B) 705c84054caSLinJiawei 706c84054caSLinJiawei def frm_wfn(wdata: UInt): UInt = { 707c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 708c84054caSLinJiawei csrw_dirty_fp_state := true.B 709c84054caSLinJiawei fcsrOld.frm := wdata(2,0) 7105d669833SYinan Xu fcsrOld.asUInt 711c84054caSLinJiawei } 712c84054caSLinJiawei def frm_rfn(rdata: UInt): UInt = rdata(7,5) 713c84054caSLinJiawei 7147132faa5SLinJiawei def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 7157132faa5SLinJiawei val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 7167132faa5SLinJiawei val fcsrNew = WireInit(fcsrOld) 717c84054caSLinJiawei csrw_dirty_fp_state := true.B 7187132faa5SLinJiawei if (update) { 7197132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 7207132faa5SLinJiawei } else { 7217132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) 7227132faa5SLinJiawei } 7235d669833SYinan Xu fcsrNew.asUInt 724c84054caSLinJiawei } 725c84054caSLinJiawei def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 726c84054caSLinJiawei 727c84054caSLinJiawei def fcsr_wfn(wdata: UInt): UInt = { 728c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 729c84054caSLinJiawei csrw_dirty_fp_state := true.B 730c84054caSLinJiawei Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 731c84054caSLinJiawei } 732c84054caSLinJiawei 733c84054caSLinJiawei val fcsrMapping = Map( 7347132faa5SLinJiawei MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 735c84054caSLinJiawei MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 736c84054caSLinJiawei MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 737c84054caSLinJiawei ) 738c84054caSLinJiawei 739321934c7SKunlin You // Hart Privilege Mode 740321934c7SKunlin You val privilegeMode = RegInit(UInt(2.W), ModeM) 741c84054caSLinJiawei 742cd365d4cSrvcoresjw //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool()))) 7438635f18fSwangkaifan // Perf Counter 7448635f18fSwangkaifan val nrPerfCnts = 29 // 3...31 745321934c7SKunlin You val privilegeModeOH = UIntToOH(privilegeMode) 746cd365d4cSrvcoresjw val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool()))) 7478635f18fSwangkaifan val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 7488c7b0b2fSrvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 74912c44ce5Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 75012c44ce5Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 75112c44ce5Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 752cd365d4cSrvcoresjw for (i <-0 until nrPerfCnts) { 753321934c7SKunlin You perfEventscounten(i) := (perfEvents(i)(63,60) & privilegeModeOH).orR 754cd365d4cSrvcoresjw } 755cd365d4cSrvcoresjw 7561ca0e4f3SYinan Xu val hpmEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 757cd365d4cSrvcoresjw for (i <- 0 until numPCntHc * coreParams.L2NBanks) { 7581ca0e4f3SYinan Xu hpmEvents(i) := csrio.perf.perfEventsHc(i) 759cd365d4cSrvcoresjw } 760cd365d4cSrvcoresjw 7619a128342SHaoyuan Feng // print perfEvents 7629a128342SHaoyuan Feng val allPerfEvents = hpmEvents.map(x => (s"Hc", x.value)) 7639a128342SHaoyuan Feng if (printEventCoding) { 7649a128342SHaoyuan Feng for (((name, inc), i) <- allPerfEvents.zipWithIndex) { 7659a128342SHaoyuan Feng println("CSR perfEvents Set", name, inc, i) 7669a128342SHaoyuan Feng } 7679a128342SHaoyuan Feng } 7689a128342SHaoyuan Feng 76912c44ce5Srvcoresjw val csrevents = perfEvents.slice(24, 29) 7701ca0e4f3SYinan Xu val hpm_hc = HPerfMonitor(csrevents, hpmEvents) 7718635f18fSwangkaifan val mcountinhibit = RegInit(0.U(XLEN.W)) 772b03ddc86Swangkaifan val mcycle = RegInit(0.U(XLEN.W)) 773b03ddc86Swangkaifan mcycle := mcycle + 1.U 774b03ddc86Swangkaifan val minstret = RegInit(0.U(XLEN.W)) 7751ca0e4f3SYinan Xu val perf_events = csrio.perf.perfEventsFrontend ++ 7761ca0e4f3SYinan Xu csrio.perf.perfEventsCtrl ++ 7771ca0e4f3SYinan Xu csrio.perf.perfEventsLsu ++ 7781ca0e4f3SYinan Xu hpm_hc.getPerf 779b03ddc86Swangkaifan minstret := minstret + RegNext(csrio.perf.retiredInstr) 7805fd90906Srvcoresjw for(i <- 0 until 29){ 7811ca0e4f3SYinan Xu perfCnts(i) := Mux(mcountinhibit(i+3) | !perfEventscounten(i), perfCnts(i), perfCnts(i) + perf_events(i).value) 7825fd90906Srvcoresjw } 7838635f18fSwangkaifan 784c84054caSLinJiawei // CSR reg map 78521fa8708Swangkaifan val basicPrivMapping = Map( 786c84054caSLinJiawei 78721fa8708Swangkaifan //--- User Trap Setup --- 788c84054caSLinJiawei // MaskedRegMap(Ustatus, ustatus), 789c84054caSLinJiawei // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 790c84054caSLinJiawei // MaskedRegMap(Utvec, utvec), 791c84054caSLinJiawei 79221fa8708Swangkaifan //--- User Trap Handling --- 793c84054caSLinJiawei // MaskedRegMap(Uscratch, uscratch), 794c84054caSLinJiawei // MaskedRegMap(Uepc, uepc), 795c84054caSLinJiawei // MaskedRegMap(Ucause, ucause), 796c84054caSLinJiawei // MaskedRegMap(Utval, utval), 797c84054caSLinJiawei // MaskedRegMap(Uip, uip), 798c84054caSLinJiawei 79921fa8708Swangkaifan //--- User Counter/Timers --- 800c84054caSLinJiawei // MaskedRegMap(Cycle, cycle), 801c84054caSLinJiawei // MaskedRegMap(Time, time), 802c84054caSLinJiawei // MaskedRegMap(Instret, instret), 803c84054caSLinJiawei 80421fa8708Swangkaifan //--- Supervisor Trap Setup --- 805c84054caSLinJiawei MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 806c84054caSLinJiawei // MaskedRegMap(Sedeleg, Sedeleg), 807c84054caSLinJiawei // MaskedRegMap(Sideleg, Sideleg), 808c84054caSLinJiawei MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 809a4e57ea3SLi Qianruo MaskedRegMap(Stvec, stvec, stvecMask, MaskedRegMap.NoSideEffect, stvecMask), 810c84054caSLinJiawei MaskedRegMap(Scounteren, scounteren), 811c84054caSLinJiawei 8126ade72d9Sxuzefan //--- Supervisor Configuration --- 8136ade72d9Sxuzefan MaskedRegMap(Senvcfg, senvcfg), 8146ade72d9Sxuzefan 81521fa8708Swangkaifan //--- Supervisor Trap Handling --- 816c84054caSLinJiawei MaskedRegMap(Sscratch, sscratch), 817e30fd06aSYinan Xu MaskedRegMap(Sepc, sepc, sepcMask, MaskedRegMap.NoSideEffect, sepcMask), 818c84054caSLinJiawei MaskedRegMap(Scause, scause), 819c84054caSLinJiawei MaskedRegMap(Stval, stval), 820*d0de7e4aSpeixiaokun MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask), 821c84054caSLinJiawei 82221fa8708Swangkaifan //--- Supervisor Protection and Translation --- 823c5334b11SZhangZifei MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 824c84054caSLinJiawei 82535a47a38SYinan Xu //--- Supervisor Custom Read/Write Registers 826eedc2e58SSteve Gou MaskedRegMap(Sbpctl, sbpctl), 82735a47a38SYinan Xu MaskedRegMap(Spfctl, spfctl), 828ecccf78fSJay MaskedRegMap(Sfetchctl, sfetchctl), 82935a47a38SYinan Xu MaskedRegMap(Sdsid, sdsid), 8302b8b2e7aSWilliam Wang MaskedRegMap(Slvpredctl, slvpredctl), 831f3f22d72SYinan Xu MaskedRegMap(Smblockctl, smblockctl), 832aac4464eSYinan Xu MaskedRegMap(Srnctl, srnctl), 83335a47a38SYinan Xu 83421fa8708Swangkaifan //--- Machine Information Registers --- 8355dabf2dfSYinan Xu MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8365dabf2dfSYinan Xu MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8375dabf2dfSYinan Xu MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8385dabf2dfSYinan Xu MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 8397d9edc86SLemover MaskedRegMap(Mconfigptr, mconfigptr, 0.U(XLEN.W), MaskedRegMap.Unwritable), 840c84054caSLinJiawei 84121fa8708Swangkaifan //--- Machine Trap Setup --- 842443741b9SYinan Xu MaskedRegMap(Mstatus, mstatus, mstatusWMask, mstatusUpdateSideEffect), 8435e4ec482SWilliam Wang MaskedRegMap(Misa, misa, 0.U, MaskedRegMap.Unwritable), // now whole misa is unchangeable 844*d0de7e4aSpeixiaokun MaskedRegMap(Medeleg, medeleg, medelegWMask), 845*d0de7e4aSpeixiaokun MaskedRegMap(Mideleg, mideleg, midelegWMask, MaskedRegMap.NoSideEffect), 846*d0de7e4aSpeixiaokun MaskedRegMap(Mie, mie, mieWMask, MaskedRegMap.NoSideEffect), 847a4e57ea3SLi Qianruo MaskedRegMap(Mtvec, mtvec, mtvecMask, MaskedRegMap.NoSideEffect, mtvecMask), 848c84054caSLinJiawei MaskedRegMap(Mcounteren, mcounteren), 849c84054caSLinJiawei 85021fa8708Swangkaifan //--- Machine Trap Handling --- 851c84054caSLinJiawei MaskedRegMap(Mscratch, mscratch), 852e30fd06aSYinan Xu MaskedRegMap(Mepc, mepc, mepcMask, MaskedRegMap.NoSideEffect, mepcMask), 853c84054caSLinJiawei MaskedRegMap(Mcause, mcause), 854c84054caSLinJiawei MaskedRegMap(Mtval, mtval), 855*d0de7e4aSpeixiaokun MaskedRegMap(Mip, mipReg.asUInt, mipWMask, MaskedRegMap.NoSideEffect, mipMask), 856d4aca96cSlqre 8576ade72d9Sxuzefan //--- Machine Configuration --- 8586ade72d9Sxuzefan MaskedRegMap(Menvcfg, menvcfg), 85972951335SLi Qianruo //--- Trigger --- 860716f717fSLi Qianruo MaskedRegMap(Tselect, tselectPhy, WritableMask, WriteTselect), 861ba762693SYinan Xu MaskedRegMap(Tdata1, tdata1Phy(tselectPhy), WritableMask, WriteTdata1, WritableMask, ReadTdata1), 862ba762693SYinan Xu MaskedRegMap(Tdata2, tdata2Phy(tselectPhy)), 863716f717fSLi Qianruo MaskedRegMap(Tinfo, tinfo, 0.U(XLEN.W), MaskedRegMap.Unwritable), 86472951335SLi Qianruo MaskedRegMap(Tcontrol, tControlPhy, tcontrolWriteMask), 86572951335SLi Qianruo 866d4aca96cSlqre //--- Debug Mode --- 867d4aca96cSlqre MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect), 868d4aca96cSlqre MaskedRegMap(Dpc, dpc), 8695b0f0029SXuan Hu MaskedRegMap(Dscratch0, dscratch0), 87012c44ce5Srvcoresjw MaskedRegMap(Dscratch1, dscratch1), 871b03ddc86Swangkaifan MaskedRegMap(Mcountinhibit, mcountinhibit), 872b03ddc86Swangkaifan MaskedRegMap(Mcycle, mcycle), 873b03ddc86Swangkaifan MaskedRegMap(Minstret, minstret), 874b03ddc86Swangkaifan ) 87512c44ce5Srvcoresjw 876*d0de7e4aSpeixiaokun // hypervisor csr map 877*d0de7e4aSpeixiaokun val hcsrMapping = Map( 878*d0de7e4aSpeixiaokun //--- Hypervisor Trap Setup --- 879*d0de7e4aSpeixiaokun MaskedRegMap(Hstatus, hstatus, hstatusWMask), 880*d0de7e4aSpeixiaokun MaskedRegMap(Hedeleg, hedeleg), 881*d0de7e4aSpeixiaokun MaskedRegMap(Hideleg, hideleg, hidelegWMask, MaskedRegMap.NoSideEffect, hidelegRMask), 882*d0de7e4aSpeixiaokun MaskedRegMap(Hie, mie, hieMask, MaskedRegMap.NoSideEffect, hieMask), 883*d0de7e4aSpeixiaokun MaskedRegMap(Hcounteren, hcounteren), 884*d0de7e4aSpeixiaokun MaskedRegMap(Hgeie, hgeie), 885*d0de7e4aSpeixiaokun 886*d0de7e4aSpeixiaokun //--- Hypervisor Trap Handling --- 887*d0de7e4aSpeixiaokun MaskedRegMap(Htval, htval), 888*d0de7e4aSpeixiaokun MaskedRegMap(Hip, mipReg.asUInt, hipWMask, MaskedRegMap.NoSideEffect, hipRMask), 889*d0de7e4aSpeixiaokun MaskedRegMap(Hvip, mipReg.asUInt, hvipMask, MaskedRegMap.NoSideEffect, hvipMask), 890*d0de7e4aSpeixiaokun MaskedRegMap(Htinst, htinst), 891*d0de7e4aSpeixiaokun MaskedRegMap(Hgeip, hgeip), 892*d0de7e4aSpeixiaokun 893*d0de7e4aSpeixiaokun //--- Hypervisor Configuration --- 894*d0de7e4aSpeixiaokun MaskedRegMap(Henvcfg, henvcfg), 895*d0de7e4aSpeixiaokun 896*d0de7e4aSpeixiaokun //--- Hypervisor Protection and Translation --- 897*d0de7e4aSpeixiaokun MaskedRegMap(Hgatp, hgatp), 898*d0de7e4aSpeixiaokun 899*d0de7e4aSpeixiaokun //--- Hypervisor Counter/Timer Virtualization Registers --- 900*d0de7e4aSpeixiaokun MaskedRegMap(Htimedelta, htimedelta), 901*d0de7e4aSpeixiaokun 902*d0de7e4aSpeixiaokun //--- Virtual Supervisor Registers --- 903*d0de7e4aSpeixiaokun MaskedRegMap(Vsstatus, vsstatus, rmask = sstatusRmask, wmask = sstatusWmask), 904*d0de7e4aSpeixiaokun MaskedRegMap(Vsie, mie, rmask = vsip_ie_Mask, wmask = vsip_ie_Mask), 905*d0de7e4aSpeixiaokun MaskedRegMap(Vstvec, vstvec), 906*d0de7e4aSpeixiaokun MaskedRegMap(Vsscratch, vsscratch), 907*d0de7e4aSpeixiaokun MaskedRegMap(Vsepc, vsepc), 908*d0de7e4aSpeixiaokun MaskedRegMap(Vscause, vscause), 909*d0de7e4aSpeixiaokun MaskedRegMap(Vstval, vstval), 910*d0de7e4aSpeixiaokun MaskedRegMap(Vsip, mipReg.asUInt, vsip_WMask, MaskedRegMap.NoSideEffect, vsip_ie_Mask), 911*d0de7e4aSpeixiaokun MaskedRegMap(Vsatp, vsatp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 912*d0de7e4aSpeixiaokun 913*d0de7e4aSpeixiaokun //--- Machine Registers --- 914*d0de7e4aSpeixiaokun MaskedRegMap(Mtval2, mtval2), 915*d0de7e4aSpeixiaokun MaskedRegMap(Mtinst, mtinst), 916*d0de7e4aSpeixiaokun ) 917*d0de7e4aSpeixiaokun 91812c44ce5Srvcoresjw val perfCntMapping = (0 until 29).map(i => {Map( 91912c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmevent3 +i, 92012c44ce5Srvcoresjw reg = perfEvents(i), 92112c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)), 92212c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmcounter3 +i, 92312c44ce5Srvcoresjw reg = perfCnts(i)) 92412c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 9256d96ebcdSwakafa // TODO: mechanism should be implemented later 9266d96ebcdSwakafa // val MhpmcounterStart = Mhpmcounter3 9276d96ebcdSwakafa // val MhpmeventStart = Mhpmevent3 9286d96ebcdSwakafa // for (i <- 0 until nrPerfCnts) { 9296d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 9306d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 9316d96ebcdSwakafa // } 9328635f18fSwangkaifan 933e19f7967SWilliam Wang val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 934e19f7967SWilliam Wang name -> RegInit(0.U(attribute("width").toInt.W)) 935e19f7967SWilliam Wang }} 936ad3ba452Szhanglinjuan val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 937ad3ba452Szhanglinjuan MaskedRegMap( 938ad3ba452Szhanglinjuan Scachebase + attribute("offset").toInt, 939e19f7967SWilliam Wang cacheopRegs(name) 940ad3ba452Szhanglinjuan ) 941ad3ba452Szhanglinjuan }} 942b6982e83SLemover 94321fa8708Swangkaifan val mapping = basicPrivMapping ++ 9448635f18fSwangkaifan perfCntMapping ++ 94521fa8708Swangkaifan pmpMapping ++ 946ca2f90a6SLemover pmaMapping ++ 947ad3ba452Szhanglinjuan (if (HasFPU) fcsrMapping else Nil) ++ 948*d0de7e4aSpeixiaokun (if (HasCustomCSRCacheOp) cacheopMapping else Nil) ++ 949*d0de7e4aSpeixiaokun (if (HasHExtension) hcsrMapping else Nil) 950c84054caSLinJiawei 951*d0de7e4aSpeixiaokun 952*d0de7e4aSpeixiaokun val vs_s_csr_map = Map( 953*d0de7e4aSpeixiaokun Sstatus.U -> Vsstatus.U, 954*d0de7e4aSpeixiaokun Sie.U -> Vsie.U, 955*d0de7e4aSpeixiaokun Stvec.U -> Vstvec.U, 956*d0de7e4aSpeixiaokun Sscratch.U -> Vsscratch.U, 957*d0de7e4aSpeixiaokun Sepc.U -> Vsepc.U, 958*d0de7e4aSpeixiaokun Scause.U -> Vscause.U, 959*d0de7e4aSpeixiaokun Stval.U -> Vstval.U, 960*d0de7e4aSpeixiaokun Sip.U -> Vsip.U, 961*d0de7e4aSpeixiaokun Satp.U -> Vsatp.U 962*d0de7e4aSpeixiaokun ) 963*d0de7e4aSpeixiaokun val addr = Wire(UInt(12.W)) 964*d0de7e4aSpeixiaokun val vscsr_addr = LookupTreeDefault(src2(11, 0), src2(11, 0), vs_s_csr_map) 965*d0de7e4aSpeixiaokun when(virtMode){ 966*d0de7e4aSpeixiaokun addr := vscsr_addr 967*d0de7e4aSpeixiaokun }.otherwise{ 968*d0de7e4aSpeixiaokun addr := src2(11, 0) 969*d0de7e4aSpeixiaokun } 970b1860798SZhangfw val csri = ZeroExt(src2(16, 12), XLEN) 971*d0de7e4aSpeixiaokun val rdata_tmp = Wire(UInt(XLEN.W)) 972*d0de7e4aSpeixiaokun val wdata_tmp = LookupTree(func, List( 973c84054caSLinJiawei CSROpType.wrt -> src1, 974c84054caSLinJiawei CSROpType.set -> (rdata | src1), 9755d669833SYinan Xu CSROpType.clr -> (rdata & (~src1).asUInt), 976b0ae3ac4SLinJiawei CSROpType.wrti -> csri, 977c84054caSLinJiawei CSROpType.seti -> (rdata | csri), 9785d669833SYinan Xu CSROpType.clri -> (rdata & (~csri).asUInt) 979c84054caSLinJiawei )) 980*d0de7e4aSpeixiaokun val is_vsip_ie = addr === Vsip.U || addr === Vsie.U 981*d0de7e4aSpeixiaokun val wdata = Mux(is_vsip_ie, ZeroExt(wdata_tmp << 1, XLEN), wdata_tmp) 982c84054caSLinJiawei 983e377d77eSWilliam Wang val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) || 9844d5d2702Swakafa (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U) || 9854d5d2702Swakafa addr === Mip.U 986e377d77eSWilliam Wang csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp 9878635f18fSwangkaifan 98847a386bfSZhangZifei // satp wen check 98947a386bfSZhangZifei val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 9902f5f05fdSWilliam Wang 991e5adbe81SLemover // csr access check, special case 992*d0de7e4aSpeixiaokun val tvmNotPermit = (privilegeMode === ModeS && !virtMode && mstatusStruct.tvm.asBool) 993e5adbe81SLemover val accessPermitted = !(addr === Satp.U && tvmNotPermit) 994*d0de7e4aSpeixiaokun val vtvmNotPermit = (privilegeMode === ModeS && virtMode && hstatusStruct.vtvm.asBool) 995*d0de7e4aSpeixiaokun val vaccessPermitted = !(addr === Vsatp.U && vtvmNotPermit) 996*d0de7e4aSpeixiaokun csrio.disableSfence := (tvmNotPermit || !virtMode && privilegeMode < ModeS) || (vtvmNotPermit || virtMode && privilegeMode < ModeS) 997*d0de7e4aSpeixiaokun csrio.disableHfenceg := !((!virtMode && privilegeMode === ModeS && !mstatusStruct.tvm.asBool) || (privilegeMode === ModeM)) // only valid in HS and mstatus.tvm == 0 or in M 998*d0de7e4aSpeixiaokun csrio.disableHfencev := !(privilegeMode === ModeM || (!virtMode && privilegeMode === ModeS)) 999e5adbe81SLemover 10002f5f05fdSWilliam Wang // general CSR wen check 1001*d0de7e4aSpeixiaokun val wen = valid && CSROpType.needAccess(func) && ((addr=/=Satp.U && addr =/= Vsatp.U) || satpLegalMode) 100272951335SLi Qianruo val dcsrPermitted = dcsrPermissionCheck(addr, false.B, debugMode) 100372951335SLi Qianruo val triggerPermitted = triggerPermissionCheck(addr, true.B, debugMode) // todo dmode 1004*d0de7e4aSpeixiaokun val HasH = (HasHExtension == true).asBool() 1005*d0de7e4aSpeixiaokun val csrAccess = csrAccessPermissionCheck(addr, false.B, privilegeMode, virtMode, HasH) 1006*d0de7e4aSpeixiaokun val modePermitted = csrAccess === 0.U && dcsrPermitted && triggerPermitted 1007321934c7SKunlin You val perfcntPermitted = perfcntPermissionCheck(addr, privilegeMode, mcounteren, scounteren) 1008*d0de7e4aSpeixiaokun val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && Mux(virtMode, vaccessPermitted, accessPermitted) 1009*d0de7e4aSpeixiaokun MaskedRegMap.generate(mapping, addr, rdata_tmp, wen && permitted, wdata) 1010*d0de7e4aSpeixiaokun rdata := Mux(is_vsip_ie, ZeroExt(rdata_tmp >> 1, XLEN), rdata_tmp) 1011ead41f51SLinJiawei io.out.bits.data := rdata 1012ead41f51SLinJiawei io.out.bits.uop := io.in.bits.uop 1013e18c367fSLinJiawei io.out.bits.uop.cf := cfOut 1014e18c367fSLinJiawei io.out.bits.uop.ctrl.flushPipe := flushPipe 1015c84054caSLinJiawei 1016b6982e83SLemover // send distribute csr a w signal 1017b6982e83SLemover csrio.customCtrl.distribute_csr.w.valid := wen && permitted 1018b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.data := wdata 1019b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.addr := addr 1020b6982e83SLemover 1021a4e57ea3SLi Qianruo when (RegNext(csrio.fpu.fflags.valid)) { 1022a4e57ea3SLi Qianruo fcsr := fflags_wfn(update = true)(RegNext(csrio.fpu.fflags.bits)) 1023c84054caSLinJiawei } 1024c84054caSLinJiawei // set fs and sd in mstatus 1025a4e57ea3SLi Qianruo when (csrw_dirty_fp_state || RegNext(csrio.fpu.dirty_fs)) { 1026c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1027c84054caSLinJiawei mstatusNew.fs := "b11".U 1028c84054caSLinJiawei mstatusNew.sd := true.B 10295d669833SYinan Xu mstatus := mstatusNew.asUInt 1030c84054caSLinJiawei } 1031129a273eSYinan Xu csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 1032c84054caSLinJiawei 103372951335SLi Qianruo 103472951335SLi Qianruo // Trigger Ctrl 1035716f717fSLi Qianruo csrio.customCtrl.trigger_enable := tdata1Phy.map{t => 1036716f717fSLi Qianruo def tdata1 = t.asTypeOf(new TdataBundle) 1037321934c7SKunlin You tdata1.m && privilegeMode === ModeM || 1038321934c7SKunlin You tdata1.s && privilegeMode === ModeS || tdata1.u && privilegeMode === ModeU 103972951335SLi Qianruo } 1040ddb65c47SLi Qianruo csrio.customCtrl.frontend_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) === I_Trigger) 1041ddb65c47SLi Qianruo csrio.customCtrl.mem_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) =/= I_Trigger) 10425d669833SYinan Xu XSDebug(csrio.customCtrl.trigger_enable.asUInt.orR, p"Debug Mode: At least 1 trigger is enabled," + 10435d669833SYinan Xu p"trigger enable is ${Binary(csrio.customCtrl.trigger_enable.asUInt)}\n") 104472951335SLi Qianruo 1045c84054caSLinJiawei // CSR inst decode 10468e7b11e5SWilliam Wang val isEbreak = addr === privEbreak && func === CSROpType.jmp 1047c84054caSLinJiawei val isEcall = addr === privEcall && func === CSROpType.jmp 1048c84054caSLinJiawei val isMret = addr === privMret && func === CSROpType.jmp 1049c84054caSLinJiawei val isSret = addr === privSret && func === CSROpType.jmp 1050c84054caSLinJiawei val isUret = addr === privUret && func === CSROpType.jmp 1051d4aca96cSlqre val isDret = addr === privDret && func === CSROpType.jmp 10525d669833SYinan Xu val isWFI = func === CSROpType.wfi 1053c84054caSLinJiawei 1054e18c367fSLinJiawei XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 1055321934c7SKunlin You XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, privilegeMode) 1056bf9968b2SYinan Xu 1057321934c7SKunlin You // Illegal privileged operation list 1058321934c7SKunlin You val illegalMret = valid && isMret && privilegeMode < ModeM 1059321934c7SKunlin You val illegalSret = valid && isSret && privilegeMode < ModeS 1060*d0de7e4aSpeixiaokun val illegalSModeSret = valid && isSret && privilegeMode === ModeS && virtMode === false.B && mstatusStruct.tsr.asBool 1061*d0de7e4aSpeixiaokun // when hstatus.vtsr == 1, if sret is executed in VS-mode, it will cause virtual instruction 1062*d0de7e4aSpeixiaokun val illegalVSModeSret = valid && isSret && privilegeMode === ModeS && virtMode && hstatusStruct.vtsr.asBool 10635d669833SYinan Xu // When TW=1, then if WFI is executed in any less-privileged mode, 10645d669833SYinan Xu // and it does not complete within an implementation-specific, bounded time limit, 10655d669833SYinan Xu // the WFI instruction causes an illegal instruction exception. 10665d669833SYinan Xu // The time limit may always be 0, in which case WFI always causes 10675d669833SYinan Xu // an illegal instruction exception in less-privileged modes when TW=1. 1068*d0de7e4aSpeixiaokun val illegalWFI = valid && isWFI && (privilegeMode < ModeM && mstatusStruct.tw === 1.U || privilegeMode === ModeU && !virtMode) 1069*d0de7e4aSpeixiaokun val illegalVWFI = valid && isWFI && ((virtMode && privilegeMode === ModeS && hstatusStruct.vtw === 1.U && mstatusStruct.tw === 0.U)|| 1070*d0de7e4aSpeixiaokun (virtMode && privilegeMode === ModeU && mstatusStruct.tw === 0.U)) 1071321934c7SKunlin You // Illegal privileged instruction check 10725d669833SYinan Xu val isIllegalAddr = valid && CSROpType.needAccess(func) && MaskedRegMap.isIllegalAddr(mapping, addr) 1073*d0de7e4aSpeixiaokun val isIllegalAccess = !virtMode && wen && !(Mux(addrInPerfCnt, perfcntPermitted, csrAccess === 0.U && dcsrPermitted && triggerPermitted) && accessPermitted) 10745d669833SYinan Xu val isIllegalPrivOp = illegalMret || illegalSret || illegalSModeSret || illegalWFI 1075c84054caSLinJiawei 1076*d0de7e4aSpeixiaokun val isIllegalVAccess = virtMode && wen && (csrAccess === 2.U || !vaccessPermitted) 1077*d0de7e4aSpeixiaokun val isIllegalVPrivOp = illegalVSModeSret || illegalVWFI 1078ad3ba452Szhanglinjuan // expose several csr bits for tlb 1079fcff7e94SZhangZifei tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 1080fcff7e94SZhangZifei tlbBundle.priv.sum := mstatusStruct.sum.asBool 1081*d0de7e4aSpeixiaokun tlbBundle.priv.vmxr := vsstatusStruct.mxr.asBool 1082*d0de7e4aSpeixiaokun tlbBundle.priv.vsum := vsstatusStruct.sum.asBool 1083*d0de7e4aSpeixiaokun tlbBundle.priv.spvp := hstatusStruct.spvp 1084*d0de7e4aSpeixiaokun tlbBundle.priv.virt := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpv & (mstatusStruct.mpp =/= ModeM), virtMode) 1085321934c7SKunlin You tlbBundle.priv.imode := privilegeMode 1086321934c7SKunlin You tlbBundle.priv.dmode := Mux(debugMode && dcsr.asTypeOf(new DcsrStruct).mprven, ModeM, Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, privilegeMode)) 1087c84054caSLinJiawei 1088e9341afdSYinan Xu // Branch control 10895b0f0029SXuan Hu val retTarget = WireInit(0.U) 10908e7b11e5SWilliam Wang val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 1091bc63e578SLi Qianruo flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall && !isEbreak) 1092c84054caSLinJiawei 10935b0f0029SXuan Hu private val illegalRetTarget = WireInit(false.B) 10945b0f0029SXuan Hu when(valid) { 10955b0f0029SXuan Hu when(isDret) { 10965b0f0029SXuan Hu retTarget := dpc(VAddrBits - 1, 0) 10975b0f0029SXuan Hu }.elsewhen(isMret && !illegalMret) { 10985b0f0029SXuan Hu retTarget := mepc(VAddrBits - 1, 0) 1099*d0de7e4aSpeixiaokun }.elsewhen(isSret && !illegalSret && !illegalSModeSret && !illegalVSModeSret) { 1100*d0de7e4aSpeixiaokun retTarget := Mux(virtMode, vsepc(VAddrBits - 1, 0), sepc(VAddrBits - 1, 0)) 11015b0f0029SXuan Hu }.elsewhen(isUret) { 11025b0f0029SXuan Hu retTarget := uepc(VAddrBits - 1, 0) 11035b0f0029SXuan Hu }.otherwise { 11045b0f0029SXuan Hu illegalRetTarget := true.B 11055b0f0029SXuan Hu } 11065b0f0029SXuan Hu }.otherwise { 11075b0f0029SXuan Hu illegalRetTarget := true.B // when illegalRetTarget setted, retTarget should never be used 11085b0f0029SXuan Hu } 1109c84054caSLinJiawei 1110d4aca96cSlqre when (valid && isDret) { 1111d4aca96cSlqre val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1112d4aca96cSlqre val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1113d4aca96cSlqre val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1114d4aca96cSlqre val debugModeNew = WireInit(debugMode) 1115d4aca96cSlqre when (dcsr.asTypeOf(new DcsrStruct).prv =/= ModeM) {mstatusNew.mprv := 0.U} //If the new privilege mode is less privileged than M-mode, MPRV in mstatus is cleared. 1116d4aca96cSlqre mstatus := mstatusNew.asUInt 1117321934c7SKunlin You privilegeMode := dcsrNew.prv 1118d4aca96cSlqre retTarget := dpc(VAddrBits-1, 0) 1119d4aca96cSlqre debugModeNew := false.B 1120d4aca96cSlqre debugIntrEnable := true.B 1121d4aca96cSlqre debugMode := debugModeNew 1122d4aca96cSlqre XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 1123d4aca96cSlqre } 1124d4aca96cSlqre 1125cb8f1780SWilliam Wang when (valid && isMret && !illegalMret) { 1126c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1127c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1128c84054caSLinJiawei mstatusNew.ie.m := mstatusOld.pie.m 1129321934c7SKunlin You privilegeMode := mstatusOld.mpp 1130*d0de7e4aSpeixiaokun if(HasHExtension) { 1131*d0de7e4aSpeixiaokun virtMode := mstatusOld.mpv 1132*d0de7e4aSpeixiaokun mstatusNew.mpv := 0.U 1133*d0de7e4aSpeixiaokun } 1134c84054caSLinJiawei mstatusNew.pie.m := true.B 1135c84054caSLinJiawei mstatusNew.mpp := ModeU 1136c266a93bSLemover when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U } 1137c84054caSLinJiawei mstatus := mstatusNew.asUInt 1138c84054caSLinJiawei } 1139c84054caSLinJiawei 1140*d0de7e4aSpeixiaokun when (valid && isSret && !illegalSret && !illegalSModeSret && !illegalVSModeSret) { 1141c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1142c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1143*d0de7e4aSpeixiaokun val hstatusOld = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1144*d0de7e4aSpeixiaokun val hstatusNew = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1145*d0de7e4aSpeixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1146*d0de7e4aSpeixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1147*d0de7e4aSpeixiaokun when (virtMode === 0.U) { 1148*d0de7e4aSpeixiaokun virtMode := hstatusOld.spv 1149*d0de7e4aSpeixiaokun hstatusNew.spv := 0.U 1150c84054caSLinJiawei mstatusNew.ie.s := mstatusOld.pie.s 1151321934c7SKunlin You privilegeMode := Cat(0.U(1.W), mstatusOld.spp) 1152c84054caSLinJiawei mstatusNew.pie.s := true.B 1153c84054caSLinJiawei mstatusNew.spp := ModeU 1154*d0de7e4aSpeixiaokun when(mstatusOld.spp =/= ModeM) { 1155*d0de7e4aSpeixiaokun mstatusNew.mprv := 0.U 1156*d0de7e4aSpeixiaokun } 1157c84054caSLinJiawei mstatus := mstatusNew.asUInt 1158*d0de7e4aSpeixiaokun hstatus := hstatusNew.asUInt 1159*d0de7e4aSpeixiaokun }.otherwise{ 1160*d0de7e4aSpeixiaokun privilegeMode := vsstatusOld.spp 1161*d0de7e4aSpeixiaokun vsstatusNew.spp := ModeU 1162*d0de7e4aSpeixiaokun vsstatusNew.ie.s := vsstatusOld.pie.s 1163*d0de7e4aSpeixiaokun vsstatusNew.pie.s := 1.U 1164*d0de7e4aSpeixiaokun vsstatus := vsstatusNew.asUInt 1165*d0de7e4aSpeixiaokun } 1166c84054caSLinJiawei } 1167c84054caSLinJiawei 1168c84054caSLinJiawei when (valid && isUret) { 1169c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1170c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1171c84054caSLinJiawei // mstatusNew.mpp.m := ModeU //TODO: add mode U 1172c84054caSLinJiawei mstatusNew.ie.u := mstatusOld.pie.u 1173321934c7SKunlin You privilegeMode := ModeU 1174c84054caSLinJiawei mstatusNew.pie.u := true.B 1175c84054caSLinJiawei mstatus := mstatusNew.asUInt 1176c84054caSLinJiawei } 1177c84054caSLinJiawei 1178e9341afdSYinan Xu io.in.ready := true.B 1179e9341afdSYinan Xu io.out.valid := valid 1180e9341afdSYinan Xu 11815b0f0029SXuan Hu // In this situation, hart will enter debug mode instead of handling a breakpoint exception simply. 11825b0f0029SXuan Hu // Ebreak block instructions backwards, so it's ok to not keep extra info to distinguish between breakpoint 11835b0f0029SXuan Hu // exception and enter-debug-mode exception. 11845b0f0029SXuan Hu val ebreakEnterDebugMode = 11855b0f0029SXuan Hu (privilegeMode === ModeM && dcsrData.ebreakm) || 11865b0f0029SXuan Hu (privilegeMode === ModeS && dcsrData.ebreaks) || 11875b0f0029SXuan Hu (privilegeMode === ModeU && dcsrData.ebreaku) 11885b0f0029SXuan Hu 11895b0f0029SXuan Hu // raise a debug exception waiting to enter debug mode, instead of a breakpoint exception 11905b0f0029SXuan Hu val raiseDebugException = !debugMode && isEbreak && ebreakEnterDebugMode 1191d4aca96cSlqre 1192baf8def6SYinan Xu val csrExceptionVec = WireInit(cfIn.exceptionVec) 1193*d0de7e4aSpeixiaokun csrExceptionVec(breakPoint) := io.in.valid && isEbreak && (ebreakCauseException || debugMode) 1194321934c7SKunlin You csrExceptionVec(ecallM) := privilegeMode === ModeM && io.in.valid && isEcall 1195*d0de7e4aSpeixiaokun csrExceptionVec(ecallVS) := privilegeMode === ModeS && virtMode && io.in.valid && isEcall 1196*d0de7e4aSpeixiaokun csrExceptionVec(ecallS) := privilegeMode === ModeS && !virtMode && io.in.valid && isEcall 1197321934c7SKunlin You csrExceptionVec(ecallU) := privilegeMode === ModeU && io.in.valid && isEcall 1198baf8def6SYinan Xu // Trigger an illegal instr exception when: 1199baf8def6SYinan Xu // * unimplemented csr is being read/written 1200baf8def6SYinan Xu // * csr access is illegal 12015d669833SYinan Xu csrExceptionVec(illegalInstr) := isIllegalAddr || isIllegalAccess || isIllegalPrivOp 1202*d0de7e4aSpeixiaokun csrExceptionVec(virtualInstr) := isIllegalVAccess || isIllegalVPrivOp 1203baf8def6SYinan Xu cfOut.exceptionVec := csrExceptionVec 1204baf8def6SYinan Xu 12055b0f0029SXuan Hu XSDebug(io.in.valid, s"Debug Mode: an Ebreak is executed, ebreak cause enter-debug-mode exception ? ${raiseDebugException}\n") 120684e47f35SLi Qianruo 1207e9341afdSYinan Xu /** 1208e9341afdSYinan Xu * Exception and Intr 1209e9341afdSYinan Xu */ 1210*d0de7e4aSpeixiaokun val idelegS = (mideleg & mip.asUInt) 1211*d0de7e4aSpeixiaokun val idelegVS = (hideleg & mideleg & mip.asUInt) 1212*d0de7e4aSpeixiaokun def privilegedEnableDetect(idelegS: Bool, idelegVS: Bool): Bool = Mux(idelegS, 1213*d0de7e4aSpeixiaokun Mux(idelegVS, (virtMode && privilegeMode === ModeS && vsstatusStruct.ie.s) || (virtMode && privilegeMode < ModeS), 1214*d0de7e4aSpeixiaokun ((privilegeMode === ModeS) && mstatusStruct.ie.s) || (privilegeMode < ModeS) || virtMode), 1215321934c7SKunlin You ((privilegeMode === ModeM) && mstatusStruct.ie.m) || (privilegeMode < ModeM)) 1216e9341afdSYinan Xu 1217d4aca96cSlqre val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 1218d4aca96cSlqre XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 12199aca92b9SYinan Xu // send interrupt information to ROB 1220*d0de7e4aSpeixiaokun val intrVecEnable = Wire(Vec(13, Bool())) 1221052ee9a1SLi Qianruo val disableInterrupt = debugMode || (dcsrData.step && !dcsrData.stepie) 1222*d0de7e4aSpeixiaokun intrVecEnable.zip(idelegS.asBools).zip(idelegVS.asBools).map{case((x,y),z) => x := privilegedEnableDetect(y, z) && !disableInterrupt} 1223d7dd1af1SLi Qianruo val intrVec = Cat(debugIntr && !debugMode, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 12245d669833SYinan Xu val intrBitSet = intrVec.orR 1225e9341afdSYinan Xu csrio.interrupt := intrBitSet 12265c95ea2eSYinan Xu // Page 45 in RISC-V Privileged Specification 12275c95ea2eSYinan Xu // The WFI instruction can also be executed when interrupts are disabled. The operation of WFI 12285c95ea2eSYinan Xu // must be unaffected by the global interrupt bits in mstatus (MIE and SIE) and the delegation 12295c95ea2eSYinan Xu // register mideleg, but should honor the individual interrupt enables (e.g, MTIE). 12304ede3fe2SLi Qianruo csrio.wfi_event := debugIntr || (mie(11, 0) & mip.asUInt).orR 1231e9341afdSYinan Xu mipWire.t.m := csrio.externalInterrupt.mtip 1232e9341afdSYinan Xu mipWire.s.m := csrio.externalInterrupt.msip 1233e9341afdSYinan Xu mipWire.e.m := csrio.externalInterrupt.meip 1234b3d79b37SYinan Xu mipWire.e.s := csrio.externalInterrupt.seip 1235e9341afdSYinan Xu 1236e9341afdSYinan Xu // interrupts 1237e9341afdSYinan Xu val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 12385b0f0029SXuan Hu val hasIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 1239a4e57ea3SLi Qianruo val ivmEnable = tlbBundle.priv.imode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 1240a4e57ea3SLi Qianruo val iexceptionPC = Mux(ivmEnable, SignExt(csrio.exception.bits.uop.cf.pc, XLEN), csrio.exception.bits.uop.cf.pc) 1241*d0de7e4aSpeixiaokun val iexceptionGPAddr = Mux(ivmEnable, SignExt(csrio.exception.bits.uop.cf.gpaddr, XLEN), csrio.exception.bits.uop.cf.gpaddr) 1242a4e57ea3SLi Qianruo val dvmEnable = tlbBundle.priv.dmode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 1243a4e57ea3SLi Qianruo val dexceptionPC = Mux(dvmEnable, SignExt(csrio.exception.bits.uop.cf.pc, XLEN), csrio.exception.bits.uop.cf.pc) 12445b0f0029SXuan Hu XSDebug(hasIntr, "interrupt: pc=0x%x, %d\n", dexceptionPC, intrNO) 12455b0f0029SXuan Hu val hasDebugIntr = intrNO === IRQ_DEBUG.U && hasIntr 1246e9341afdSYinan Xu 1247*d0de7e4aSpeixiaokun // exceptions 1248*d0de7e4aSpeixiaokun val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 1249*d0de7e4aSpeixiaokun val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 1250*d0de7e4aSpeixiaokun val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 1251*d0de7e4aSpeixiaokun val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 1252*d0de7e4aSpeixiaokun val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 1253*d0de7e4aSpeixiaokun val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 1254*d0de7e4aSpeixiaokun val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 1255*d0de7e4aSpeixiaokun val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 1256*d0de7e4aSpeixiaokun val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 1257*d0de7e4aSpeixiaokun val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException 1258*d0de7e4aSpeixiaokun val hasSingleStep = csrio.exception.bits.uop.ctrl.singleStep && raiseException 1259*d0de7e4aSpeixiaokun val hasTriggerHit = (csrio.exception.bits.uop.cf.trigger.hit) && raiseException 1260*d0de7e4aSpeixiaokun val hasInstGuestPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrGuestPageFault) && raiseException 1261*d0de7e4aSpeixiaokun val hasLoadGuestPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadGuestPageFault) && raiseException 1262*d0de7e4aSpeixiaokun val hasStoreGuestPageFault = csrio.exception.bits.uop.cf.exceptionVec(storeGuestPageFault) && raiseException 126384e47f35SLi Qianruo 126484e47f35SLi Qianruo XSDebug(hasSingleStep, "Debug Mode: single step exception\n") 1265ddb65c47SLi Qianruo XSDebug(hasTriggerHit, p"Debug Mode: trigger hit, is frontend? ${Binary(csrio.exception.bits.uop.cf.trigger.frontendHit.asUInt)} " + 1266068bf978SLi Qianruo p"backend hit vec ${Binary(csrio.exception.bits.uop.cf.trigger.backendHit.asUInt)}\n") 1267e9341afdSYinan Xu 12685b0f0029SXuan Hu val hasExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 12695b0f0029SXuan Hu val regularExceptionNO = ExceptionNO.priorities.foldRight(0.U)((i: Int, sum: UInt) => Mux(hasExceptionVec(i), i.U, sum)) 127072951335SLi Qianruo val exceptionNO = Mux(hasSingleStep || hasTriggerHit, 3.U, regularExceptionNO) 12715b0f0029SXuan Hu val causeNO = (hasIntr << (XLEN-1)).asUInt | Mux(hasIntr, intrNO, exceptionNO) 1272e9341afdSYinan Xu 12735b0f0029SXuan Hu val hasExceptionIntr = csrio.exception.valid 1274d4aca96cSlqre 12755b0f0029SXuan Hu val hasDebugException = hasBreakPoint && !debugMode && ebreakEnterDebugMode 12765b0f0029SXuan Hu val hasDebugExceptionIntr = !debugMode && (hasDebugException || hasDebugIntr || hasSingleStep || hasTriggerHit && triggerAction) // TODO 12775b0f0029SXuan Hu val ebreakEnterParkLoop = debugMode && hasExceptionIntr 1278d4aca96cSlqre 12795b0f0029SXuan Hu XSDebug(hasExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 12805b0f0029SXuan Hu dexceptionPC, intrNO, intrVec, exceptionNO, hasExceptionVec.asUInt 1281e9341afdSYinan Xu ) 12825b0f0029SXuan Hu XSDebug(hasExceptionIntr, 1283e9341afdSYinan Xu "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 1284a4e57ea3SLi Qianruo dexceptionPC, 1285e9341afdSYinan Xu mstatus, 1286e9341afdSYinan Xu mideleg, 1287e9341afdSYinan Xu medeleg, 1288321934c7SKunlin You privilegeMode 1289e9341afdSYinan Xu ) 1290e9341afdSYinan Xu 1291e9341afdSYinan Xu // mtval write logic 12928a33de1fSYinan Xu // Due to timing reasons of memExceptionVAddr, we delay the write of mtval and stval 1293e9341afdSYinan Xu val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 1294*d0de7e4aSpeixiaokun val memExceptionGPAddr = SignExt(csrio.memExceptionGPAddr, XLEN) 1295a4e57ea3SLi Qianruo val updateTval = VecInit(Seq( 1296a4e57ea3SLi Qianruo hasInstrPageFault, 1297a4e57ea3SLi Qianruo hasLoadPageFault, 1298a4e57ea3SLi Qianruo hasStorePageFault, 1299a4e57ea3SLi Qianruo hasInstrAccessFault, 1300a4e57ea3SLi Qianruo hasLoadAccessFault, 1301a4e57ea3SLi Qianruo hasStoreAccessFault, 1302*d0de7e4aSpeixiaokun hasLoadAddrMisaligned, 1303*d0de7e4aSpeixiaokun hasStoreAddrMisaligned, 1304*d0de7e4aSpeixiaokun hasInstGuestPageFault, 1305*d0de7e4aSpeixiaokun hasLoadGuestPageFault, 1306*d0de7e4aSpeixiaokun hasStoreGuestPageFault 1307*d0de7e4aSpeixiaokun )).asUInt.orR 1308*d0de7e4aSpeixiaokun val updateTval_h = VecInit(Seq( 1309*d0de7e4aSpeixiaokun hasInstGuestPageFault, 1310*d0de7e4aSpeixiaokun hasLoadGuestPageFault, 1311*d0de7e4aSpeixiaokun hasStoreGuestPageFault 1312a4e57ea3SLi Qianruo )).asUInt.orR 1313a4e57ea3SLi Qianruo when (RegNext(RegNext(updateTval))) { 131495fbbc80SYinan Xu val tval = Mux( 1315*d0de7e4aSpeixiaokun RegNext(RegNext(hasInstrPageFault || hasInstrAccessFault || hasInstGuestPageFault)), 131695fbbc80SYinan Xu RegNext(RegNext(Mux( 13172d7c7105SYinan Xu csrio.exception.bits.uop.cf.crossPageIPFFix, 13182d7c7105SYinan Xu SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 1319a4e57ea3SLi Qianruo iexceptionPC 132095fbbc80SYinan Xu ))), 1321e9341afdSYinan Xu memExceptionAddr 132295fbbc80SYinan Xu ) 1323*d0de7e4aSpeixiaokun // because we update tval two beats later, we can choose xtval according to the privilegeMode which has been updated 1324321934c7SKunlin You when (RegNext(privilegeMode === ModeM)) { 1325e9341afdSYinan Xu mtval := tval 1326e9341afdSYinan Xu }.otherwise { 1327*d0de7e4aSpeixiaokun when (virtMode){ 1328*d0de7e4aSpeixiaokun vstval := tval 1329*d0de7e4aSpeixiaokun }.otherwise{ 1330e9341afdSYinan Xu stval := tval 1331e9341afdSYinan Xu } 1332e9341afdSYinan Xu } 1333*d0de7e4aSpeixiaokun } 1334*d0de7e4aSpeixiaokun 1335*d0de7e4aSpeixiaokun when(RegNext(RegNext(updateTval_h))) { 1336*d0de7e4aSpeixiaokun val tval_tmp = Mux( 1337*d0de7e4aSpeixiaokun RegNext(RegNext(hasInstGuestPageFault)), 1338*d0de7e4aSpeixiaokun RegNext(RegNext(Mux( 1339*d0de7e4aSpeixiaokun csrio.exception.bits.uop.cf.crossPageIPFFix, 1340*d0de7e4aSpeixiaokun SignExt(csrio.exception.bits.uop.cf.gpaddr + 2.U, XLEN), 1341*d0de7e4aSpeixiaokun iexceptionGPAddr 1342*d0de7e4aSpeixiaokun ))), 1343*d0de7e4aSpeixiaokun memExceptionGPAddr 1344*d0de7e4aSpeixiaokun ) 1345*d0de7e4aSpeixiaokun val tval = tval_tmp >> 2 1346*d0de7e4aSpeixiaokun when(RegNext(privilegeMode === ModeM)) { 1347*d0de7e4aSpeixiaokun mtval2 := tval 1348*d0de7e4aSpeixiaokun }.otherwise { 1349*d0de7e4aSpeixiaokun htval := tval 1350*d0de7e4aSpeixiaokun } 1351*d0de7e4aSpeixiaokun } 1352e9341afdSYinan Xu 1353d4aca96cSlqre val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 1354*d0de7e4aSpeixiaokun val deleg = Mux(raiseIntr, mideleg , medeleg) 1355*d0de7e4aSpeixiaokun val hdeleg = Mux(raiseIntr, hideleg, hedeleg) 1356321934c7SKunlin You // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (privilegeMode < ModeM); 13575b0f0029SXuan Hu val delegS = deleg(causeNO(7,0)) && (privilegeMode < ModeM) 1358*d0de7e4aSpeixiaokun val delegVS = virtMode && delegS && hdeleg(causeNO(7, 0)) && (privilegeMode < ModeM) 1359*d0de7e4aSpeixiaokun val clearTval = !updateTval || raiseIntr 1360*d0de7e4aSpeixiaokun val clearTval_h = !updateTval_h || raiseIntr 1361d4aca96cSlqre val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak 1362*d0de7e4aSpeixiaokun val isHyperInst = csrio.exception.bits.uop.ctrl.isHyperInst 136313096f7eSYinan Xu // ctrl block will use theses later for flush 136413096f7eSYinan Xu val isXRetFlag = RegInit(false.B) 1365a4e57ea3SLi Qianruo when (DelayN(io.redirectIn.valid, 5)) { 136613096f7eSYinan Xu isXRetFlag := false.B 136713096f7eSYinan Xu }.elsewhen (isXRet) { 136813096f7eSYinan Xu isXRetFlag := true.B 136913096f7eSYinan Xu } 137013096f7eSYinan Xu csrio.isXRet := isXRetFlag 13715b0f0029SXuan Hu private val retTargetReg = RegEnable(retTarget, isXRet && !illegalRetTarget) 1372*d0de7e4aSpeixiaokun private val illegalXret = RegEnable(illegalMret || illegalSret || illegalSModeSret || illegalVSModeSret, isXRet) 1373*d0de7e4aSpeixiaokun val xtvec = Mux(delegS, Mux(delegVS, vstvec, stvec), mtvec) 13745b0f0029SXuan Hu val xtvecBase = xtvec(VAddrBits - 1, 2) 1375a4e57ea3SLi Qianruo // When MODE=Vectored, all synchronous exceptions into M/S mode 1376a4e57ea3SLi Qianruo // cause the pc to be set to the address in the BASE field, whereas 1377a4e57ea3SLi Qianruo // interrupts cause the pc to be set to the address in the BASE field 1378a4e57ea3SLi Qianruo // plus four times the interrupt cause number. 1379*d0de7e4aSpeixiaokun private val pcFromXtvec = Cat(xtvecBase + Mux(xtvec(0) && raiseIntr, causeNO(3, 0), 0.U), 0.U(2.W)) 13805b0f0029SXuan Hu // XRet sends redirect instead of Flush and isXRetFlag is true.B before redirect.valid. 13815b0f0029SXuan Hu // ROB sends exception at T0 while CSR receives at T2. 13825b0f0029SXuan Hu // We add a RegNext here and trapTarget is valid at T3. 13835b0f0029SXuan Hu csrio.trapTarget := RegEnable( 13845b0f0029SXuan Hu MuxCase(pcFromXtvec, Seq( 13855b0f0029SXuan Hu (isXRetFlag && !illegalXret) -> retTargetReg, 1386*d0de7e4aSpeixiaokun (raiseDebugExceptionIntr || ebreakEnterParkLoop) -> debugTrapTarget 13875b0f0029SXuan Hu )), 13885b0f0029SXuan Hu isXRetFlag || csrio.exception.valid) 1389e9341afdSYinan Xu 13905b0f0029SXuan Hu when (hasExceptionIntr) { 1391c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1392c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1393*d0de7e4aSpeixiaokun val hstatusOld = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1394*d0de7e4aSpeixiaokun val hstatusNew = WireInit(hstatus.asTypeOf(new HstatusStruct)) 1395*d0de7e4aSpeixiaokun val vsstatusOld = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1396*d0de7e4aSpeixiaokun val vsstatusNew = WireInit(vsstatus.asTypeOf(new MstatusStruct)) 1397d4aca96cSlqre val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1398d4aca96cSlqre val debugModeNew = WireInit(debugMode) 1399c84054caSLinJiawei 14005b0f0029SXuan Hu when (hasDebugExceptionIntr) { 14015b0f0029SXuan Hu when (hasDebugIntr) { 1402d4aca96cSlqre debugModeNew := true.B 1403a4e57ea3SLi Qianruo dpc := iexceptionPC 1404d7dd1af1SLi Qianruo dcsrNew.cause := 3.U 1405321934c7SKunlin You dcsrNew.prv := privilegeMode 1406321934c7SKunlin You privilegeMode := ModeM 14075b0f0029SXuan Hu XSDebug(hasDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 14085b0f0029SXuan Hu }.elsewhen ((hasBreakPoint || hasSingleStep || hasTriggerHit && triggerAction) && !debugMode) { 1409d4aca96cSlqre // ebreak or ss in running hart 1410d4aca96cSlqre debugModeNew := true.B 14115b0f0029SXuan Hu dpc := iexceptionPC // TODO: check it when hasSingleStep 14125b0f0029SXuan Hu dcsrNew.cause := Mux(hasTriggerHit, 2.U, Mux(hasBreakPoint, 1.U, 4.U)) 14135b0f0029SXuan Hu dcsrNew.prv := privilegeMode 1414321934c7SKunlin You privilegeMode := ModeM 1415d4aca96cSlqre } 1416d4aca96cSlqre dcsr := dcsrNew.asUInt 1417d4aca96cSlqre debugIntrEnable := false.B 1418d7dd1af1SLi Qianruo }.elsewhen (debugMode) { 1419d7dd1af1SLi Qianruo //do nothing 1420*d0de7e4aSpeixiaokun }}.elsewhen (delegVS) { 1421*d0de7e4aSpeixiaokun vscause := (raiseIntr << (XLEN-1)).asUInt | Mux(raiseIntr, intrNO >> 1.U, exceptionNO) 1422*d0de7e4aSpeixiaokun vsepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1423*d0de7e4aSpeixiaokun vsstatusNew.spp := privilegeMode 1424*d0de7e4aSpeixiaokun vsstatusNew.pie.s := vsstatusOld.ie.s 1425*d0de7e4aSpeixiaokun vsstatusNew.ie.s := false.B 1426*d0de7e4aSpeixiaokun when (clearTval) {vstval := 0.U} 1427*d0de7e4aSpeixiaokun virtMode := true.B 1428*d0de7e4aSpeixiaokun privilegeMode := ModeS 1429d4aca96cSlqre }.elsewhen (delegS) { 1430*d0de7e4aSpeixiaokun val virt = Mux(mstatusOld.mprv.asBool(), mstatusOld.mpv, virtMode) 1431*d0de7e4aSpeixiaokun // to do hld st 1432*d0de7e4aSpeixiaokun hstatusNew.gva := (hasInstGuestPageFault || hasLoadGuestPageFault || hasStoreGuestPageFault || 1433*d0de7e4aSpeixiaokun ((virt.asBool() || isHyperInst) && ((raiseException && 0.U <= exceptionNO && exceptionNO <= 7.U && exceptionNO =/= 2.U) 1434*d0de7e4aSpeixiaokun || hasInstrPageFault || hasLoadPageFault || hasStorePageFault))) 1435*d0de7e4aSpeixiaokun hstatusNew.spv := virtMode 1436*d0de7e4aSpeixiaokun when(virtMode){ 1437*d0de7e4aSpeixiaokun hstatusNew.spvp := privilegeMode 1438*d0de7e4aSpeixiaokun } 1439*d0de7e4aSpeixiaokun virtMode := false.B 1440c84054caSLinJiawei scause := causeNO 1441a4e57ea3SLi Qianruo sepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1442321934c7SKunlin You mstatusNew.spp := privilegeMode 1443c84054caSLinJiawei mstatusNew.pie.s := mstatusOld.ie.s 1444c84054caSLinJiawei mstatusNew.ie.s := false.B 1445321934c7SKunlin You privilegeMode := ModeS 1446a4e57ea3SLi Qianruo when (clearTval) { stval := 0.U } 1447*d0de7e4aSpeixiaokun when (clearTval_h) {htval := 0.U} 1448c84054caSLinJiawei }.otherwise { 1449*d0de7e4aSpeixiaokun val virt = Mux(mstatusOld.mprv.asBool(), mstatusOld.mpv, virtMode) 1450*d0de7e4aSpeixiaokun // to do hld st 1451*d0de7e4aSpeixiaokun mstatusNew.gva := (hasInstGuestPageFault || hasLoadGuestPageFault || hasStoreGuestPageFault || 1452*d0de7e4aSpeixiaokun ((virt.asBool() || isHyperInst) && ((raiseException && 0.U <= exceptionNO && exceptionNO <= 7.U && exceptionNO =/= 2.U) 1453*d0de7e4aSpeixiaokun || hasInstrPageFault || hasLoadPageFault || hasStorePageFault))) 1454*d0de7e4aSpeixiaokun mstatusNew.mpv := virtMode 1455*d0de7e4aSpeixiaokun virtMode := false.B 1456c84054caSLinJiawei mcause := causeNO 1457a4e57ea3SLi Qianruo mepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1458321934c7SKunlin You mstatusNew.mpp := privilegeMode 1459c84054caSLinJiawei mstatusNew.pie.m := mstatusOld.ie.m 1460c84054caSLinJiawei mstatusNew.ie.m := false.B 1461321934c7SKunlin You privilegeMode := ModeM 1462a4e57ea3SLi Qianruo when (clearTval) { mtval := 0.U } 1463*d0de7e4aSpeixiaokun when (clearTval_h) {mtval2 := 0.U} 1464c84054caSLinJiawei } 1465c84054caSLinJiawei mstatus := mstatusNew.asUInt 1466*d0de7e4aSpeixiaokun vsstatus := vsstatusNew.asUInt 1467*d0de7e4aSpeixiaokun hstatus := hstatusNew.asUInt 1468d4aca96cSlqre debugMode := debugModeNew 1469c84054caSLinJiawei } 1470c84054caSLinJiawei 14715b0f0029SXuan Hu XSDebug(hasExceptionIntr && delegS, "sepc is written!!! pc:%x\n", cfIn.pc) 1472bf9968b2SYinan Xu 1473e19f7967SWilliam Wang // Distributed CSR update req 1474e19f7967SWilliam Wang // 1475e19f7967SWilliam Wang // For now we use it to implement customized cache op 147670899835SWilliam Wang // It can be delayed if necessary 1477e19f7967SWilliam Wang 147870899835SWilliam Wang val delayedUpdate0 = DelayN(csrio.distributedUpdate(0), 2) 147970899835SWilliam Wang val delayedUpdate1 = DelayN(csrio.distributedUpdate(1), 2) 148070899835SWilliam Wang val distributedUpdateValid = delayedUpdate0.w.valid || delayedUpdate1.w.valid 148170899835SWilliam Wang val distributedUpdateAddr = Mux(delayedUpdate0.w.valid, 148270899835SWilliam Wang delayedUpdate0.w.bits.addr, 148370899835SWilliam Wang delayedUpdate1.w.bits.addr 148470899835SWilliam Wang ) 148570899835SWilliam Wang val distributedUpdateData = Mux(delayedUpdate0.w.valid, 148670899835SWilliam Wang delayedUpdate0.w.bits.data, 148770899835SWilliam Wang delayedUpdate1.w.bits.data 148870899835SWilliam Wang ) 148970899835SWilliam Wang 149070899835SWilliam Wang assert(!(delayedUpdate0.w.valid && delayedUpdate1.w.valid)) 149170899835SWilliam Wang 149270899835SWilliam Wang when(distributedUpdateValid){ 1493e19f7967SWilliam Wang // cacheopRegs can be distributed updated 1494e19f7967SWilliam Wang CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 149570899835SWilliam Wang when((Scachebase + attribute("offset").toInt).U === distributedUpdateAddr){ 149670899835SWilliam Wang cacheopRegs(name) := distributedUpdateData 1497e19f7967SWilliam Wang } 1498e19f7967SWilliam Wang }} 1499e19f7967SWilliam Wang } 1500e19f7967SWilliam Wang 15019ef181f4SWilliam Wang // Cache error debug support 15029ef181f4SWilliam Wang if(HasCustomCSRCacheOp){ 15039ef181f4SWilliam Wang val cache_error_decoder = Module(new CSRCacheErrorDecoder) 15049ef181f4SWilliam Wang cache_error_decoder.io.encoded_cache_error := cacheopRegs("CACHE_ERROR") 15059ef181f4SWilliam Wang } 15069ef181f4SWilliam Wang 1507e30fd06aSYinan Xu // Implicit add reset values for mepc[0] and sepc[0] 1508e30fd06aSYinan Xu // TODO: rewrite mepc and sepc using a struct-like style with the LSB always being 0 150967ba96b4SYinan Xu when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 1510e30fd06aSYinan Xu mepc := Cat(mepc(XLEN - 1, 1), 0.U(1.W)) 1511e30fd06aSYinan Xu sepc := Cat(sepc(XLEN - 1, 1), 0.U(1.W)) 1512e30fd06aSYinan Xu } 1513e30fd06aSYinan Xu 1514c84054caSLinJiawei def readWithScala(addr: Int): UInt = mapping(addr)._1 1515c84054caSLinJiawei 15165b0f0029SXuan Hu val difftestIntrNO = Mux(hasIntr, causeNO, 0.U) 1517a165bd69Swangkaifan 1518cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1519cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 15207d45a146SYinan Xu val difftest = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 15217d45a146SYinan Xu difftest.coreid := csrio.hartId 15227d45a146SYinan Xu difftest.valid := csrio.exception.valid 15235b0f0029SXuan Hu difftest.interrupt := Mux(hasIntr, causeNO, 0.U) 15245b0f0029SXuan Hu difftest.exception := Mux(hasException, causeNO, 0.U) 15257d45a146SYinan Xu difftest.exceptionPC := dexceptionPC 1526a4e57ea3SLi Qianruo if (env.EnableDifftest) { 15277d45a146SYinan Xu difftest.exceptionInst := csrio.exception.bits.uop.cf.instr 1528a4e57ea3SLi Qianruo } 15292225d46eSJiawei Lin } 15302225d46eSJiawei Lin 1531cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1532cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 15337d45a146SYinan Xu val difftest = DifftestModule(new DiffCSRState) 15347d45a146SYinan Xu difftest.coreid := csrio.hartId 1535321934c7SKunlin You difftest.privilegeMode := privilegeMode 15367d45a146SYinan Xu difftest.mstatus := mstatus 15377d45a146SYinan Xu difftest.sstatus := mstatus & sstatusRmask 15387d45a146SYinan Xu difftest.mepc := mepc 15397d45a146SYinan Xu difftest.sepc := sepc 15407d45a146SYinan Xu difftest.mtval:= mtval 15417d45a146SYinan Xu difftest.stval:= stval 15427d45a146SYinan Xu difftest.mtvec := mtvec 15437d45a146SYinan Xu difftest.stvec := stvec 15447d45a146SYinan Xu difftest.mcause := mcause 15457d45a146SYinan Xu difftest.scause := scause 15467d45a146SYinan Xu difftest.satp := satp 15477d45a146SYinan Xu difftest.mip := mipReg 15487d45a146SYinan Xu difftest.mie := mie 15497d45a146SYinan Xu difftest.mscratch := mscratch 15507d45a146SYinan Xu difftest.sscratch := sscratch 15517d45a146SYinan Xu difftest.mideleg := mideleg 15527d45a146SYinan Xu difftest.medeleg := medeleg 1553a165bd69Swangkaifan } 1554a4e57ea3SLi Qianruo 1555a4e57ea3SLi Qianruo if (env.AlwaysBasicDiff || env.EnableDifftest) { 1556*d0de7e4aSpeixiaokun val difftest = Module(new DifftestHCSRState) 1557*d0de7e4aSpeixiaokun difftest.io.clock := clock 1558*d0de7e4aSpeixiaokun difftest.io.coreid := csrio.hartId 1559*d0de7e4aSpeixiaokun difftest.io.virtMode := virtMode 1560*d0de7e4aSpeixiaokun difftest.io.mtval2 := mtval2 1561*d0de7e4aSpeixiaokun difftest.io.mtinst := mtinst 1562*d0de7e4aSpeixiaokun difftest.io.hstatus := hstatus 1563*d0de7e4aSpeixiaokun difftest.io.hideleg := hideleg 1564*d0de7e4aSpeixiaokun difftest.io.hedeleg := hedeleg 1565*d0de7e4aSpeixiaokun difftest.io.hcounteren := hcounteren 1566*d0de7e4aSpeixiaokun difftest.io.htval := htval 1567*d0de7e4aSpeixiaokun difftest.io.htinst := htinst 1568*d0de7e4aSpeixiaokun difftest.io.hgatp := hgatp 1569*d0de7e4aSpeixiaokun difftest.io.vsstatus := vsstatus 1570*d0de7e4aSpeixiaokun difftest.io.vstvec := vstvec 1571*d0de7e4aSpeixiaokun difftest.io.vsepc := vsepc 1572*d0de7e4aSpeixiaokun difftest.io.vscause := vscause 1573*d0de7e4aSpeixiaokun difftest.io.vstval := vstval 1574*d0de7e4aSpeixiaokun difftest.io.vsatp := vsatp 1575*d0de7e4aSpeixiaokun difftest.io.vsscratch := vsscratch 1576*d0de7e4aSpeixiaokun } 1577*d0de7e4aSpeixiaokun 1578*d0de7e4aSpeixiaokun if(env.AlwaysBasicDiff || env.EnableDifftest) { 15797d45a146SYinan Xu val difftest = DifftestModule(new DiffDebugMode) 15807d45a146SYinan Xu difftest.coreid := csrio.hartId 15817d45a146SYinan Xu difftest.debugMode := debugMode 15827d45a146SYinan Xu difftest.dcsr := dcsr 15837d45a146SYinan Xu difftest.dpc := dpc 15845b0f0029SXuan Hu difftest.dscratch0 := dscratch0 15857d45a146SYinan Xu difftest.dscratch1 := dscratch1 1586a4e57ea3SLi Qianruo } 1587c84054caSLinJiawei} 15881545277aSYinan Xu 1589cd365d4cSrvcoresjwclass PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst { 1590cd365d4cSrvcoresjw val io = IO(new Bundle { 1591cd365d4cSrvcoresjw val distribute_csr = Flipped(new DistributedCSRIO()) 1592cd365d4cSrvcoresjw val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1593cd365d4cSrvcoresjw }) 1594cd365d4cSrvcoresjw 1595cd365d4cSrvcoresjw val w = io.distribute_csr.w 1596cd365d4cSrvcoresjw 15975fd90906Srvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 15985fd90906Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 15995fd90906Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 16005fd90906Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 1601cd365d4cSrvcoresjw 160212c44ce5Srvcoresjw val perfEventMapping = (0 until 29).map(i => {Map( 160312c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmevent3 +i, 160412c44ce5Srvcoresjw reg = perfEvents(i), 160512c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)) 160612c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 1607cd365d4cSrvcoresjw 1608cd365d4cSrvcoresjw val rdata = Wire(UInt(XLEN.W)) 1609cd365d4cSrvcoresjw MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 16105fd90906Srvcoresjw for(i <- 0 until 29){ 16115fd90906Srvcoresjw io.hpmevent(i) := perfEvents(i) 16125fd90906Srvcoresjw } 1613cd365d4cSrvcoresjw} 1614