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 192225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters 20c84054caSLinJiaweiimport chisel3._ 21c84054caSLinJiaweiimport chisel3.util._ 226ab6918fSYinan Xuimport difftest._ 23b6982e83SLemoverimport freechips.rocketchip.util._ 24b6982e83SLemoverimport utils.MaskedRegMap.WritableMask 25c84054caSLinJiaweiimport utils._ 266ab6918fSYinan Xuimport xiangshan.ExceptionNO._ 27c84054caSLinJiaweiimport xiangshan._ 28db988794Swangkaifanimport xiangshan.backend.fu.util._ 296ab6918fSYinan Xuimport xiangshan.cache._ 30c84054caSLinJiawei 3172951335SLi Qianruo// Trigger Tdata1 bundles 3272951335SLi Qianruotrait HasTriggerConst { 3372951335SLi Qianruo def I_Trigger = 0.U 3472951335SLi Qianruo def S_Trigger = 1.U 3572951335SLi Qianruo def L_Trigger = 2.U 36bc63e578SLi Qianruo def GenESL(triggerType: UInt) = Cat((triggerType === I_Trigger), (triggerType === S_Trigger), (triggerType === L_Trigger)) 3772951335SLi Qianruo} 3872951335SLi Qianruo 3972951335SLi Qianruoclass TdataBundle extends Bundle { 40716f717fSLi Qianruo val ttype = UInt(4.W) 41716f717fSLi Qianruo val dmode = Bool() 42716f717fSLi Qianruo val maskmax = UInt(6.W) 43716f717fSLi Qianruo val zero1 = UInt(30.W) 44716f717fSLi Qianruo val sizehi = UInt(2.W) 45716f717fSLi Qianruo val hit = Bool() 4672951335SLi Qianruo val select = Bool() 4772951335SLi Qianruo val timing = Bool() 48716f717fSLi Qianruo val sizelo = UInt(2.W) 49716f717fSLi Qianruo val action = UInt(4.W) 5072951335SLi Qianruo val chain = Bool() 51716f717fSLi Qianruo val matchType = UInt(4.W) 5272951335SLi Qianruo val m = Bool() 53716f717fSLi Qianruo val zero2 = Bool() 5472951335SLi Qianruo val s = Bool() 5572951335SLi Qianruo val u = Bool() 56716f717fSLi Qianruo val execute = Bool() 57716f717fSLi Qianruo val store = Bool() 58716f717fSLi Qianruo val load = Bool() 5972951335SLi Qianruo} 6072951335SLi Qianruo 612225d46eSJiawei Linclass FpuCsrIO extends Bundle { 627f1506e3SLinJiawei val fflags = Output(Valid(UInt(5.W))) 63c84054caSLinJiawei val isIllegal = Output(Bool()) 64c84054caSLinJiawei val dirty_fs = Output(Bool()) 65c84054caSLinJiawei val frm = Input(UInt(3.W)) 66c84054caSLinJiawei} 67c84054caSLinJiawei 68b2e234ebSLinJiawei 692225d46eSJiawei Linclass PerfCounterIO(implicit p: Parameters) extends XSBundle { 701ca0e4f3SYinan Xu val perfEventsFrontend = Vec(numCSRPCntFrontend, new PerfEvent) 711ca0e4f3SYinan Xu val perfEventsCtrl = Vec(numCSRPCntCtrl, new PerfEvent) 721ca0e4f3SYinan Xu val perfEventsLsu = Vec(numCSRPCntLsu, new PerfEvent) 731ca0e4f3SYinan Xu val perfEventsHc = Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent) 74edd6ddbcSwakafa val retiredInstr = UInt(3.W) 75edd6ddbcSwakafa val frontendInfo = new Bundle { 76edd6ddbcSwakafa val ibufFull = Bool() 77e0d9a9f0SLingrui98 val bpuInfo = new Bundle { 78e0d9a9f0SLingrui98 val bpRight = UInt(XLEN.W) 79e0d9a9f0SLingrui98 val bpWrong = UInt(XLEN.W) 80e0d9a9f0SLingrui98 } 81edd6ddbcSwakafa } 82edd6ddbcSwakafa val ctrlInfo = new Bundle { 839aca92b9SYinan Xu val robFull = Bool() 84edd6ddbcSwakafa val intdqFull = Bool() 85edd6ddbcSwakafa val fpdqFull = Bool() 86edd6ddbcSwakafa val lsdqFull = Bool() 87edd6ddbcSwakafa } 88edd6ddbcSwakafa val memInfo = new Bundle { 89edd6ddbcSwakafa val sqFull = Bool() 90edd6ddbcSwakafa val lqFull = Bool() 91edd6ddbcSwakafa val dcacheMSHRFull = Bool() 92edd6ddbcSwakafa } 93e0d9a9f0SLingrui98 94edd6ddbcSwakafa val cacheInfo = new Bundle { 95edd6ddbcSwakafa val l2MSHRFull = Bool() 96edd6ddbcSwakafa val l3MSHRFull = Bool() 97edd6ddbcSwakafa val l2nAcquire = UInt(XLEN.W) 98edd6ddbcSwakafa val l2nAcquireMiss = UInt(XLEN.W) 99edd6ddbcSwakafa val l3nAcquire = UInt(XLEN.W) 100edd6ddbcSwakafa val l3nAcquireMiss = UInt(XLEN.W) 101edd6ddbcSwakafa } 10262ab1317SYinan Xu} 10362ab1317SYinan Xu 1042225d46eSJiawei Linclass CSRFileIO(implicit p: Parameters) extends XSBundle { 1055668a921SJiawei Lin val hartId = Input(UInt(8.W)) 106129a273eSYinan Xu // output (for func === CSROpType.jmp) 107edd6ddbcSwakafa val perf = Input(new PerfCounterIO) 1088635f18fSwangkaifan val isPerfCnt = Output(Bool()) 109129a273eSYinan Xu // to FPU 110129a273eSYinan Xu val fpu = Flipped(new FpuCsrIO) 111bf9968b2SYinan Xu // from rob 1123a474d38SYinan Xu val exception = Flipped(ValidIO(new ExceptionInfo)) 113129a273eSYinan Xu // to ROB 114ac5a5d53SLinJiawei val isXRet = Output(Bool()) 115129a273eSYinan Xu val trapTarget = Output(UInt(VAddrBits.W)) 116129a273eSYinan Xu val interrupt = Output(Bool()) 117129a273eSYinan Xu // from LSQ 118129a273eSYinan Xu val memExceptionVAddr = Input(UInt(VAddrBits.W)) 119129a273eSYinan Xu // from outside cpu,externalInterrupt 120129a273eSYinan Xu val externalInterrupt = new ExternalInterruptIO 121129a273eSYinan Xu // TLB 122129a273eSYinan Xu val tlb = Output(new TlbCsrBundle) 123d4aca96cSlqre // Debug Mode 124d4aca96cSlqre val singleStep = Output(Bool()) 125d4aca96cSlqre val debugMode = Output(Bool()) 126e5adbe81SLemover // to Fence to disable sfence 127e5adbe81SLemover val disableSfence = Output(Bool()) 128e377d77eSWilliam Wang // Custom microarchiture ctrl signal 129e377d77eSWilliam Wang val customCtrl = Output(new CustomCSRCtrlIO) 130e377d77eSWilliam Wang // distributed csr write 13170899835SWilliam Wang val distributedUpdate = Vec(2, Flipped(new DistributedCSRUpdateReq)) 13235a47a38SYinan Xu} 13335a47a38SYinan Xu 13472951335SLi Qianruoclass CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMPMethod with PMAMethod with HasTriggerConst 13535a47a38SYinan Xu{ 13635a47a38SYinan Xu val csrio = IO(new CSRFileIO) 137c84054caSLinJiawei 138e18c367fSLinJiawei val cfIn = io.in.bits.uop.cf 139e18c367fSLinJiawei val cfOut = Wire(new CtrlFlow) 140e18c367fSLinJiawei cfOut := cfIn 141e18c367fSLinJiawei val flushPipe = Wire(Bool()) 142c84054caSLinJiawei 143e18c367fSLinJiawei val (valid, src1, src2, func) = ( 144e18c367fSLinJiawei io.in.valid, 145e18c367fSLinJiawei io.in.bits.src(0), 146e18c367fSLinJiawei io.in.bits.uop.ctrl.imm, 147e18c367fSLinJiawei io.in.bits.uop.ctrl.fuOpType 148e18c367fSLinJiawei ) 149c84054caSLinJiawei 150c84054caSLinJiawei // CSR define 151c84054caSLinJiawei 152c84054caSLinJiawei class Priv extends Bundle { 153c84054caSLinJiawei val m = Output(Bool()) 154c84054caSLinJiawei val h = Output(Bool()) 155c84054caSLinJiawei val s = Output(Bool()) 156c84054caSLinJiawei val u = Output(Bool()) 157c84054caSLinJiawei } 158c84054caSLinJiawei 159c84054caSLinJiawei val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U) 160c84054caSLinJiawei 161d4aca96cSlqre class DcsrStruct extends Bundle { 162d4aca96cSlqre val xdebugver = Output(UInt(2.W)) 163d4aca96cSlqre val zero4 = Output(UInt(2.W)) 164d4aca96cSlqre val zero3 = Output(UInt(12.W)) 165d4aca96cSlqre val ebreakm = Output(Bool()) 166d4aca96cSlqre val ebreakh = Output(Bool()) 167d4aca96cSlqre val ebreaks = Output(Bool()) 168d4aca96cSlqre val ebreaku = Output(Bool()) 169d4aca96cSlqre val zero2 = Output(Bool()) 170d4aca96cSlqre val stopcycle = Output(Bool()) 171d4aca96cSlqre val stoptime = Output(Bool()) 172d4aca96cSlqre val cause = Output(UInt(3.W)) 173d4aca96cSlqre val zero1 = Output(UInt(3.W)) 174d4aca96cSlqre val step = Output(Bool()) 175d4aca96cSlqre val prv = Output(UInt(2.W)) 176d4aca96cSlqre } 177d4aca96cSlqre 178c84054caSLinJiawei class MstatusStruct extends Bundle { 179c84054caSLinJiawei val sd = Output(UInt(1.W)) 1808e7b11e5SWilliam Wang 1817d9edc86SLemover val pad1 = if (XLEN == 64) Output(UInt(25.W)) else null 1827d9edc86SLemover val mbe = if (XLEN == 64) Output(UInt(1.W)) else null 1837d9edc86SLemover val sbe = if (XLEN == 64) Output(UInt(1.W)) else null 1848e7b11e5SWilliam Wang val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 1858e7b11e5SWilliam Wang val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 1868e7b11e5SWilliam Wang val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 1878e7b11e5SWilliam Wang 188c84054caSLinJiawei val tsr = Output(UInt(1.W)) 189c84054caSLinJiawei val tw = Output(UInt(1.W)) 1908e7b11e5SWilliam Wang val tvm = Output(UInt(1.W)) 191c84054caSLinJiawei val mxr = Output(UInt(1.W)) 192c84054caSLinJiawei val sum = Output(UInt(1.W)) 193c84054caSLinJiawei val mprv = Output(UInt(1.W)) 194c84054caSLinJiawei val xs = Output(UInt(2.W)) 195c84054caSLinJiawei val fs = Output(UInt(2.W)) 196c84054caSLinJiawei val mpp = Output(UInt(2.W)) 197c84054caSLinJiawei val hpp = Output(UInt(2.W)) 198c84054caSLinJiawei val spp = Output(UInt(1.W)) 199c84054caSLinJiawei val pie = new Priv 200c84054caSLinJiawei val ie = new Priv 201c84054caSLinJiawei assert(this.getWidth == XLEN) 2027d9edc86SLemover 2037d9edc86SLemover def ube = pie.h // a little ugly 2047d9edc86SLemover def ube_(r: UInt): Unit = { 2057d9edc86SLemover pie.h := r(0) 2067d9edc86SLemover } 207c84054caSLinJiawei } 208c84054caSLinJiawei 209c84054caSLinJiawei class Interrupt extends Bundle { 210d4aca96cSlqre// val d = Output(Bool()) // Debug 211c84054caSLinJiawei val e = new Priv 212c84054caSLinJiawei val t = new Priv 213c84054caSLinJiawei val s = new Priv 214c84054caSLinJiawei } 215c84054caSLinJiawei 216d4aca96cSlqre // Debug CSRs 217d4aca96cSlqre val dcsr = RegInit(UInt(32.W), 0x4000b010.U) 218d4aca96cSlqre val dpc = Reg(UInt(64.W)) 219d4aca96cSlqre val dscratch = Reg(UInt(64.W)) 220d4aca96cSlqre val dscratch1 = Reg(UInt(64.W)) 221d4aca96cSlqre val debugMode = RegInit(false.B) 222d4aca96cSlqre val debugIntrEnable = RegInit(true.B) 223d4aca96cSlqre csrio.debugMode := debugMode 224d4aca96cSlqre 225d4aca96cSlqre val dpcPrev = RegNext(dpc) 2261097f021SLi Qianruo XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x\n", dpc, dpcPrev) 227d4aca96cSlqre 228d4aca96cSlqre // dcsr value table 229d4aca96cSlqre // | debugver | 0100 230d4aca96cSlqre // | zero | 10 bits of 0 231d4aca96cSlqre // | ebreakvs | 0 232d4aca96cSlqre // | ebreakvu | 0 233d4aca96cSlqre // | ebreakm | 1 if ebreak enters debug 234d4aca96cSlqre // | zero | 0 235d4aca96cSlqre // | ebreaks | 236d4aca96cSlqre // | ebreaku | 237d4aca96cSlqre // | stepie | 0 disable interrupts in singlestep 238d4aca96cSlqre // | stopcount| stop counter, 0 239d4aca96cSlqre // | stoptime | stop time, 0 240d4aca96cSlqre // | cause | 3 bits read only 241d4aca96cSlqre // | v | 0 242d4aca96cSlqre // | mprven | 1 243d4aca96cSlqre // | nmip | read only 244d4aca96cSlqre // | step | 245d4aca96cSlqre // | prv | 2 bits 246ad3ba452Szhanglinjuan 247d4aca96cSlqre val dcsrData = Wire(new DcsrStruct) 248d4aca96cSlqre dcsrData := dcsr.asTypeOf(new DcsrStruct) 2495dabf2dfSYinan Xu val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(2, 0), XLEN)// Dcsr write mask 250d4aca96cSlqre def dcsrUpdateSideEffect(dcsr: UInt): UInt = { 251d4aca96cSlqre val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct)) 252d4aca96cSlqre val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11 253d4aca96cSlqre dcsrNew 254d4aca96cSlqre } 255d4aca96cSlqre csrio.singleStep := dcsrData.step 256ddb65c47SLi Qianruo csrio.customCtrl.singlestep := dcsrData.step 257d4aca96cSlqre 25872951335SLi Qianruo // Trigger CSRs 25972951335SLi Qianruo 260716f717fSLi Qianruo val type_config = Array( 261716f717fSLi Qianruo 0.U -> I_Trigger, 1.U -> I_Trigger, 262716f717fSLi Qianruo 2.U -> S_Trigger, 3.U -> S_Trigger, 263716f717fSLi Qianruo 4.U -> L_Trigger, 5.U -> L_Trigger, // No.5 Load Trigger 264716f717fSLi Qianruo 6.U -> I_Trigger, 7.U -> S_Trigger, 265716f717fSLi Qianruo 8.U -> I_Trigger, 9.U -> L_Trigger 266716f717fSLi Qianruo ) 267716f717fSLi Qianruo def TypeLookup(select: UInt) = MuxLookup(select, I_Trigger, type_config) 268716f717fSLi Qianruo 269ddb65c47SLi Qianruo val tdata1Phy = RegInit(VecInit(List.fill(10) {(2L << 60L).U(64.W)})) // init ttype 2 27072951335SLi Qianruo val tdata2Phy = Reg(Vec(10, UInt(64.W))) 27172951335SLi Qianruo val tselectPhy = RegInit(0.U(4.W)) 272ddb65c47SLi Qianruo val tDummy1 = WireInit(0.U(64.W)) 273ddb65c47SLi Qianruo val tDummy2 = WireInit(0.U(64.W)) 274716f717fSLi Qianruo val tdata1Wire = Wire(UInt(64.W)) 275716f717fSLi Qianruo val tdata2Wire = Wire(UInt(64.W)) 276716f717fSLi Qianruo val tinfo = RegInit(2.U(64.W)) 27772951335SLi Qianruo val tControlPhy = RegInit(0.U(64.W)) 27884e47f35SLi Qianruo val triggerAction = RegInit(false.B) 279716f717fSLi Qianruo tdata1Wire := tdata1Phy(tselectPhy) 280716f717fSLi Qianruo tdata2Wire := tdata2Phy(tselectPhy) 281ddb65c47SLi Qianruo tDummy1 := tdata1Phy(tselectPhy) 282ddb65c47SLi Qianruo tDummy2 := tdata2Phy(tselectPhy) 283716f717fSLi Qianruo 28472951335SLi Qianruo def ReadTdata1(rdata: UInt) = { 285716f717fSLi Qianruo val tdata1 = WireInit(tdata1Wire) 286716f717fSLi Qianruo val read_data = tdata1Wire 287716f717fSLi Qianruo XSDebug(src2(11, 0) === Tdata1.U && valid, p"\nDebug Mode: tdata1(${tselectPhy})is read, the actual value is ${Binary(tdata1)}\n") 288ddb65c47SLi Qianruo read_data | (triggerAction << 12) // fix action 28972951335SLi Qianruo } 29072951335SLi Qianruo def WriteTdata1(wdata: UInt) = { 291716f717fSLi Qianruo val tdata1 = WireInit(tdata1Wire.asTypeOf(new TdataBundle)) 292716f717fSLi Qianruo val wdata_wire = WireInit(wdata.asTypeOf(new TdataBundle)) 293716f717fSLi Qianruo val tdata1_new = WireInit(wdata.asTypeOf(new TdataBundle)) 294716f717fSLi Qianruo XSDebug(src2(11, 0) === Tdata1.U && valid && func =/= CSROpType.jmp, p"Debug Mode: tdata1(${tselectPhy})is written, the actual value is ${wdata}\n") 29584e47f35SLi Qianruo// tdata1_new.hit := wdata(20) 296ddb65c47SLi Qianruo tdata1_new.ttype := tdata1.ttype 297ddb65c47SLi Qianruo tdata1_new.dmode := Mux(debugMode, wdata_wire.dmode, tdata1.dmode) 298ddb65c47SLi Qianruo tdata1_new.maskmax := 0.U 299ddb65c47SLi Qianruo tdata1_new.hit := 0.U 300716f717fSLi Qianruo tdata1_new.select := (TypeLookup(tselectPhy) === I_Trigger) && wdata_wire.select 301716f717fSLi Qianruo when(wdata_wire.action <= 1.U){ 302716f717fSLi Qianruo triggerAction := tdata1_new.action(0) 303716f717fSLi Qianruo } .otherwise{ 304716f717fSLi Qianruo tdata1_new.action := tdata1.action 305716f717fSLi Qianruo } 306ddb65c47SLi Qianruo tdata1_new.timing := false.B // hardwire this because we have singlestep 307716f717fSLi Qianruo tdata1_new.zero1 := 0.U 308716f717fSLi Qianruo tdata1_new.zero2 := 0.U 309716f717fSLi Qianruo tdata1_new.chain := !tselectPhy(0) && wdata_wire.chain 310716f717fSLi Qianruo when(wdata_wire.matchType =/= 0.U && wdata_wire.matchType =/= 2.U && wdata_wire.matchType =/= 3.U) { 311716f717fSLi Qianruo tdata1_new.matchType := tdata1.matchType 312716f717fSLi Qianruo } 313ddb65c47SLi Qianruo tdata1_new.sizehi := Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 0.U, 1.U) 314ddb65c47SLi Qianruo tdata1_new.sizelo:= Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 3.U, 1.U) 315716f717fSLi Qianruo tdata1_new.execute := TypeLookup(tselectPhy) === I_Trigger 316716f717fSLi Qianruo tdata1_new.store := TypeLookup(tselectPhy) === S_Trigger 317716f717fSLi Qianruo tdata1_new.load := TypeLookup(tselectPhy) === L_Trigger 318716f717fSLi Qianruo when(valid && func =/= CSROpType.jmp && addr === Tdata1.U) { 319716f717fSLi Qianruo tdata1Phy(tselectPhy) := tdata1_new.asUInt() 320716f717fSLi Qianruo } 32172951335SLi Qianruo 0.U 32272951335SLi Qianruo } 32372951335SLi Qianruo 32472951335SLi Qianruo def WriteTselect(wdata: UInt) = { 325716f717fSLi Qianruo Mux(wdata < 10.U, wdata(3, 0), tselectPhy) 32672951335SLi Qianruo } 32772951335SLi Qianruo 32872951335SLi Qianruo def ReadTdata2(tdata: UInt) = tdata2Phy(tselectPhy) 32972951335SLi Qianruo def WriteTdata2(wdata: UInt) = { 330716f717fSLi Qianruo when(valid && func =/= CSROpType.jmp && addr === Tdata2.U) { 33172951335SLi Qianruo tdata2Phy(tselectPhy) := wdata 332716f717fSLi Qianruo } 33372951335SLi Qianruo 0.U 33472951335SLi Qianruo } 33572951335SLi Qianruo 33672951335SLi Qianruo 33772951335SLi Qianruo val tcontrolWriteMask = ZeroExt(GenMask(3) | GenMask(7), XLEN) 33872951335SLi Qianruo 33972951335SLi Qianruo 34072951335SLi Qianruo def GenTdataDistribute(tdata1: TdataBundle, tdata2: UInt): MatchTriggerIO = { 34172951335SLi Qianruo val res = Wire(new MatchTriggerIO) 34272951335SLi Qianruo res.matchType := tdata1.matchType 34372951335SLi Qianruo res.select := tdata1.select 34472951335SLi Qianruo res.timing := tdata1.timing 34584e47f35SLi Qianruo res.action := triggerAction 34672951335SLi Qianruo res.chain := tdata1.chain 34772951335SLi Qianruo res.tdata2 := tdata2 34872951335SLi Qianruo res 34972951335SLi Qianruo } 35072951335SLi Qianruo 35172951335SLi Qianruo csrio.customCtrl.frontend_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U, Seq( 35272951335SLi Qianruo 0.U -> 0.U, 35372951335SLi Qianruo 1.U -> 1.U, 35472951335SLi Qianruo 6.U -> 2.U, 35572951335SLi Qianruo 8.U -> 3.U 35672951335SLi Qianruo )) 35772951335SLi Qianruo csrio.customCtrl.mem_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U, Seq( 35872951335SLi Qianruo 2.U -> 0.U, 35972951335SLi Qianruo 3.U -> 1.U, 36072951335SLi Qianruo 4.U -> 2.U, 36172951335SLi Qianruo 5.U -> 3.U, 36272951335SLi Qianruo 7.U -> 4.U, 36372951335SLi Qianruo 9.U -> 5.U 36472951335SLi Qianruo )) 365716f717fSLi Qianruo csrio.customCtrl.frontend_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy).asTypeOf(new TdataBundle), tdata2Phy(tselectPhy)) 366716f717fSLi Qianruo csrio.customCtrl.mem_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy).asTypeOf(new TdataBundle), tdata2Phy(tselectPhy)) 36772951335SLi Qianruo 368c84054caSLinJiawei // Machine-Level CSRs 369*a4e57ea3SLi Qianruo // mtvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 370*a4e57ea3SLi Qianruo val mtvecMask = ~(0x2.U(XLEN.W)) 371c84054caSLinJiawei val mtvec = RegInit(UInt(XLEN.W), 0.U) 372c84054caSLinJiawei val mcounteren = RegInit(UInt(XLEN.W), 0.U) 373c84054caSLinJiawei val mcause = RegInit(UInt(XLEN.W), 0.U) 374c84054caSLinJiawei val mtval = RegInit(UInt(XLEN.W), 0.U) 375c84054caSLinJiawei val mepc = Reg(UInt(XLEN.W)) 376e30fd06aSYinan Xu // Page 36 in riscv-priv: The low bit of mepc (mepc[0]) is always zero. 377e30fd06aSYinan Xu val mepcMask = ~(0x1.U(XLEN.W)) 378c84054caSLinJiawei 379c84054caSLinJiawei val mie = RegInit(0.U(XLEN.W)) 380c84054caSLinJiawei val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 3815dabf2dfSYinan Xu val mipReg = RegInit(0.U(XLEN.W)) 3825dabf2dfSYinan Xu val mipFixMask = ZeroExt(GenMask(9) | GenMask(5) | GenMask(1), XLEN) 383c84054caSLinJiawei val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 384c84054caSLinJiawei 385b2e234ebSLinJiawei def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt() 386b2e234ebSLinJiawei def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt() 387c84054caSLinJiawei var extList = List('a', 's', 'i', 'u') 388c84054caSLinJiawei if (HasMExtension) { extList = extList :+ 'm' } 389c84054caSLinJiawei if (HasCExtension) { extList = extList :+ 'c' } 390c84054caSLinJiawei if (HasFPU) { extList = extList ++ List('f', 'd') } 391c84054caSLinJiawei val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U 392c84054caSLinJiawei val misa = RegInit(UInt(XLEN.W), misaInitVal) 393bc5ff277Swangkaifan 394c84054caSLinJiawei // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 395c84054caSLinJiawei // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 396c84054caSLinJiawei 397c84054caSLinJiawei val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 398c84054caSLinJiawei val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented 399c84054caSLinJiawei val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 4007a77cff2SYinan Xu val mhartid = RegInit(UInt(XLEN.W), csrio.hartId) // the hardware thread running the code 4017d9edc86SLemover val mconfigptr = RegInit(UInt(XLEN.W), 0.U) // the read-only pointer pointing to the platform config structure, 0 for not supported. 402e30fd06aSYinan Xu val mstatus = RegInit("ha00000000".U(XLEN.W)) 403bc5ff277Swangkaifan 404c84054caSLinJiawei // mstatus Value Table 405c84054caSLinJiawei // | sd | 406c84054caSLinJiawei // | pad1 | 407c84054caSLinJiawei // | sxl | hardlinked to 10, use 00 to pass xv6 test 408e30fd06aSYinan Xu // | uxl | hardlinked to 10 409c84054caSLinJiawei // | pad0 | 410c84054caSLinJiawei // | tsr | 411c84054caSLinJiawei // | tw | 4128e7b11e5SWilliam Wang // | tvm | 413c84054caSLinJiawei // | mxr | 414c84054caSLinJiawei // | sum | 415c84054caSLinJiawei // | mprv | 416c84054caSLinJiawei // | xs | 00 | 4178e7b11e5SWilliam Wang // | fs | 00 | 418c84054caSLinJiawei // | mpp | 00 | 419c84054caSLinJiawei // | hpp | 00 | 420c84054caSLinJiawei // | spp | 0 | 4218e7b11e5SWilliam Wang // | pie | 0000 | pie.h is used as UBE 422c84054caSLinJiawei // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 423bc5ff277Swangkaifan 424c84054caSLinJiawei val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 425c84054caSLinJiawei def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 426c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 4278e7b11e5SWilliam Wang val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 428c84054caSLinJiawei mstatusNew 429c84054caSLinJiawei } 430c84054caSLinJiawei 431e30fd06aSYinan Xu val mstatusWMask = (~ZeroExt(( 432e30fd06aSYinan Xu GenMask(XLEN - 2, 36) | // WPRI 433e30fd06aSYinan Xu GenMask(35, 32) | // SXL and UXL cannot be changed 434e30fd06aSYinan Xu GenMask(31, 23) | // WPRI 435705cbec3SLemover GenMask(16, 15) | // XS is read-only 436e30fd06aSYinan Xu GenMask(10, 9) | // WPRI 437e30fd06aSYinan Xu GenMask(6) | // WPRI 438e30fd06aSYinan Xu GenMask(2) // WPRI 439e30fd06aSYinan Xu ), 64)).asUInt() 440b2e234ebSLinJiawei val mstatusMask = (~ZeroExt(( 441e30fd06aSYinan Xu GenMask(XLEN - 2, 36) | // WPRI 442e30fd06aSYinan Xu GenMask(31, 23) | // WPRI 443e30fd06aSYinan Xu GenMask(10, 9) | // WPRI 444e30fd06aSYinan Xu GenMask(6) | // WPRI 445e30fd06aSYinan Xu GenMask(2) // WPRI 446b2e234ebSLinJiawei ), 64)).asUInt() 4478e7b11e5SWilliam Wang 448c84054caSLinJiawei val medeleg = RegInit(UInt(XLEN.W), 0.U) 449c84054caSLinJiawei val mideleg = RegInit(UInt(XLEN.W), 0.U) 450c84054caSLinJiawei val mscratch = RegInit(UInt(XLEN.W), 0.U) 451c84054caSLinJiawei 452b6982e83SLemover // PMP Mapping 453ca2f90a6SLemover val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter 454ca2f90a6SLemover val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter 455ca2f90a6SLemover val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp) 456ca2f90a6SLemover val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma) 457c84054caSLinJiawei 458c84054caSLinJiawei // Superviser-Level CSRs 459c84054caSLinJiawei 460c84054caSLinJiawei // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 4615dabf2dfSYinan Xu val sstatusWmask = "hc6122".U(XLEN.W) 462c84054caSLinJiawei // Sstatus Write Mask 463c84054caSLinJiawei // ------------------------------------------------------- 464c84054caSLinJiawei // 19 9 5 2 465c84054caSLinJiawei // 0 1100 0000 0001 0010 0010 466c84054caSLinJiawei // 0 c 0 1 2 2 467c84054caSLinJiawei // ------------------------------------------------------- 468c84054caSLinJiawei val sstatusRmask = sstatusWmask | "h8000000300018000".U 469c84054caSLinJiawei // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 470*a4e57ea3SLi Qianruo // stvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1 471*a4e57ea3SLi Qianruo val stvecMask = ~(0x2.U(XLEN.W)) 472c84054caSLinJiawei val stvec = RegInit(UInt(XLEN.W), 0.U) 473c84054caSLinJiawei // val sie = RegInit(0.U(XLEN.W)) 474c84054caSLinJiawei val sieMask = "h222".U & mideleg 475c84054caSLinJiawei val sipMask = "h222".U & mideleg 4765dabf2dfSYinan Xu val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode 47734230194Sjinyue110 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 478df2b1479SZhangZifei // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 47945f497a4Shappy-lx // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0 48045f497a4Shappy-lx // TODO: use config to control the length of asid 48145f497a4Shappy-lx // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0 482705cbec3SLemover val satpMask = Cat("h8".U(Satp_Mode_len.W), satp_part_wmask(Satp_Asid_len, AsidLength), satp_part_wmask(Satp_Addr_len, PAddrBits-12)) 483c84054caSLinJiawei val sepc = RegInit(UInt(XLEN.W), 0.U) 484e30fd06aSYinan Xu // Page 60 in riscv-priv: The low bit of sepc (sepc[0]) is always zero. 485e30fd06aSYinan Xu val sepcMask = ~(0x1.U(XLEN.W)) 486c84054caSLinJiawei val scause = RegInit(UInt(XLEN.W), 0.U) 487c84054caSLinJiawei val stval = Reg(UInt(XLEN.W)) 488c84054caSLinJiawei val sscratch = RegInit(UInt(XLEN.W), 0.U) 489c84054caSLinJiawei val scounteren = RegInit(UInt(XLEN.W), 0.U) 490fcff7e94SZhangZifei 491eedc2e58SSteve Gou // sbpctl 492eedc2e58SSteve Gou // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB} 493eedc2e58SSteve Gou val sbpctl = RegInit(UInt(XLEN.W), "h7f".U) 494eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0) 495eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.btb_enable := sbpctl(1) 496eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.bim_enable := sbpctl(2) 497eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3) 498eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.sc_enable := sbpctl(4) 499eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.ras_enable := sbpctl(5) 500eedc2e58SSteve Gou csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6) 5012b8b2e7aSWilliam Wang 5022b8b2e7aSWilliam Wang // spfctl Bit 0: L1plusCache Prefetcher Enable 5032b8b2e7aSWilliam Wang // spfctl Bit 1: L2Cache Prefetcher Enable 5042b8b2e7aSWilliam Wang val spfctl = RegInit(UInt(XLEN.W), "h3".U) 50535a47a38SYinan Xu csrio.customCtrl.l1plus_pf_enable := spfctl(0) 50635a47a38SYinan Xu csrio.customCtrl.l2_pf_enable := spfctl(1) 5072b8b2e7aSWilliam Wang 5082b8b2e7aSWilliam Wang // sdsid: Differentiated Services ID 5092b8b2e7aSWilliam Wang val sdsid = RegInit(UInt(XLEN.W), 0.U) 51035a47a38SYinan Xu csrio.customCtrl.dsid := sdsid 51135a47a38SYinan Xu 5122b8b2e7aSWilliam Wang // slvpredctl: load violation predict settings 5132b8b2e7aSWilliam Wang val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17 5142b8b2e7aSWilliam Wang csrio.customCtrl.lvpred_disable := slvpredctl(0) 5152b8b2e7aSWilliam Wang csrio.customCtrl.no_spec_load := slvpredctl(1) 516c7160cd3SWilliam Wang csrio.customCtrl.storeset_wait_store := slvpredctl(2) 517c7160cd3SWilliam Wang csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3) 518c7160cd3SWilliam Wang csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4) 5192b8b2e7aSWilliam Wang 520f3f22d72SYinan Xu // smblockctl: memory block configurations 521f3f22d72SYinan Xu // bits 0-3: store buffer flush threshold (default: 8 entries) 52267682d05SWilliam Wang val smblockctl_init_val = 52367682d05SWilliam Wang ("hf".U & StoreBufferThreshold.U) | 524*a4e57ea3SLi Qianruo (EnableLdVioCheckAfterReset.B.asUInt << 4) | 525*a4e57ea3SLi Qianruo (EnableSoftPrefetchAfterReset.B.asUInt << 5) | 526*a4e57ea3SLi Qianruo (EnableCacheErrorAfterReset.B.asUInt << 6) 52767682d05SWilliam Wang val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val) 528f3f22d72SYinan Xu csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0) 52967682d05SWilliam Wang // bits 4: enable load load violation check 530*a4e57ea3SLi Qianruo csrio.customCtrl.ldld_vio_check_enable := smblockctl(4) 531*a4e57ea3SLi Qianruo csrio.customCtrl.soft_prefetch_enable := smblockctl(5) 532*a4e57ea3SLi Qianruo csrio.customCtrl.cache_error_enable := smblockctl(6) 533*a4e57ea3SLi Qianruo 534*a4e57ea3SLi Qianruo println("CSR smblockctl init value:") 535*a4e57ea3SLi Qianruo println(" Store buffer replace threshold: " + StoreBufferThreshold) 536*a4e57ea3SLi Qianruo println(" Enable ld-ld vio check after reset: " + EnableLdVioCheckAfterReset) 537*a4e57ea3SLi Qianruo println(" Enable soft prefetch after reset: " + EnableSoftPrefetchAfterReset) 538*a4e57ea3SLi Qianruo println(" Enable cache error after reset: " + EnableCacheErrorAfterReset) 539f3f22d72SYinan Xu 540af2f7849Shappy-lx val srnctl = RegInit(UInt(XLEN.W), "h3".U) 541aac4464eSYinan Xu csrio.customCtrl.move_elim_enable := srnctl(0) 542af2f7849Shappy-lx csrio.customCtrl.svinval_enable := srnctl(1) 543aac4464eSYinan Xu 5442b8b2e7aSWilliam Wang val tlbBundle = Wire(new TlbCsrBundle) 54545f497a4Shappy-lx tlbBundle.satp.apply(satp) 546b6982e83SLemover 5472b8b2e7aSWilliam Wang csrio.tlb := tlbBundle 5482b8b2e7aSWilliam Wang 549c84054caSLinJiawei // User-Level CSRs 550c84054caSLinJiawei val uepc = Reg(UInt(XLEN.W)) 551c84054caSLinJiawei 552c84054caSLinJiawei // fcsr 553c84054caSLinJiawei class FcsrStruct extends Bundle { 554c84054caSLinJiawei val reserved = UInt((XLEN-3-5).W) 555c84054caSLinJiawei val frm = UInt(3.W) 556c84054caSLinJiawei val fflags = UInt(5.W) 557c84054caSLinJiawei assert(this.getWidth == XLEN) 558c84054caSLinJiawei } 559c84054caSLinJiawei val fcsr = RegInit(0.U(XLEN.W)) 560c84054caSLinJiawei // set mstatus->sd and mstatus->fs when true 561c84054caSLinJiawei val csrw_dirty_fp_state = WireInit(false.B) 562c84054caSLinJiawei 563c84054caSLinJiawei def frm_wfn(wdata: UInt): UInt = { 564c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 565c84054caSLinJiawei csrw_dirty_fp_state := true.B 566c84054caSLinJiawei fcsrOld.frm := wdata(2,0) 567c84054caSLinJiawei fcsrOld.asUInt() 568c84054caSLinJiawei } 569c84054caSLinJiawei def frm_rfn(rdata: UInt): UInt = rdata(7,5) 570c84054caSLinJiawei 5717132faa5SLinJiawei def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 5727132faa5SLinJiawei val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 5737132faa5SLinJiawei val fcsrNew = WireInit(fcsrOld) 574c84054caSLinJiawei csrw_dirty_fp_state := true.B 5757132faa5SLinJiawei if (update) { 5767132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 5777132faa5SLinJiawei } else { 5787132faa5SLinJiawei fcsrNew.fflags := wdata(4,0) 5797132faa5SLinJiawei } 5807132faa5SLinJiawei fcsrNew.asUInt() 581c84054caSLinJiawei } 582c84054caSLinJiawei def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 583c84054caSLinJiawei 584c84054caSLinJiawei def fcsr_wfn(wdata: UInt): UInt = { 585c84054caSLinJiawei val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 586c84054caSLinJiawei csrw_dirty_fp_state := true.B 587c84054caSLinJiawei Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 588c84054caSLinJiawei } 589c84054caSLinJiawei 590c84054caSLinJiawei val fcsrMapping = Map( 5917132faa5SLinJiawei MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 592c84054caSLinJiawei MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 593c84054caSLinJiawei MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 594c84054caSLinJiawei ) 595c84054caSLinJiawei 596c84054caSLinJiawei // Hart Priviledge Mode 597c84054caSLinJiawei val priviledgeMode = RegInit(UInt(2.W), ModeM) 598c84054caSLinJiawei 599cd365d4cSrvcoresjw //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool()))) 6008635f18fSwangkaifan // Perf Counter 6018635f18fSwangkaifan val nrPerfCnts = 29 // 3...31 602cd365d4cSrvcoresjw val priviledgeModeOH = UIntToOH(priviledgeMode) 603cd365d4cSrvcoresjw val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool()))) 6048635f18fSwangkaifan val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 6058c7b0b2fSrvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 60612c44ce5Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 60712c44ce5Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 60812c44ce5Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 609cd365d4cSrvcoresjw for (i <-0 until nrPerfCnts) { 610cd365d4cSrvcoresjw perfEventscounten(i) := (Cat(perfEvents(i)(62),perfEvents(i)(61),(perfEvents(i)(61,60))) & priviledgeModeOH).orR 611cd365d4cSrvcoresjw } 612cd365d4cSrvcoresjw 6131ca0e4f3SYinan Xu val hpmEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 614cd365d4cSrvcoresjw for (i <- 0 until numPCntHc * coreParams.L2NBanks) { 6151ca0e4f3SYinan Xu hpmEvents(i) := csrio.perf.perfEventsHc(i) 616cd365d4cSrvcoresjw } 617cd365d4cSrvcoresjw 61812c44ce5Srvcoresjw val csrevents = perfEvents.slice(24, 29) 6191ca0e4f3SYinan Xu val hpm_hc = HPerfMonitor(csrevents, hpmEvents) 6208635f18fSwangkaifan val mcountinhibit = RegInit(0.U(XLEN.W)) 621b03ddc86Swangkaifan val mcycle = RegInit(0.U(XLEN.W)) 622b03ddc86Swangkaifan mcycle := mcycle + 1.U 623b03ddc86Swangkaifan val minstret = RegInit(0.U(XLEN.W)) 6241ca0e4f3SYinan Xu val perf_events = csrio.perf.perfEventsFrontend ++ 6251ca0e4f3SYinan Xu csrio.perf.perfEventsCtrl ++ 6261ca0e4f3SYinan Xu csrio.perf.perfEventsLsu ++ 6271ca0e4f3SYinan Xu hpm_hc.getPerf 628b03ddc86Swangkaifan minstret := minstret + RegNext(csrio.perf.retiredInstr) 6295fd90906Srvcoresjw for(i <- 0 until 29){ 6301ca0e4f3SYinan Xu perfCnts(i) := Mux(mcountinhibit(i+3) | !perfEventscounten(i), perfCnts(i), perfCnts(i) + perf_events(i).value) 6315fd90906Srvcoresjw } 6328635f18fSwangkaifan 633c84054caSLinJiawei // CSR reg map 63421fa8708Swangkaifan val basicPrivMapping = Map( 635c84054caSLinJiawei 63621fa8708Swangkaifan //--- User Trap Setup --- 637c84054caSLinJiawei // MaskedRegMap(Ustatus, ustatus), 638c84054caSLinJiawei // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 639c84054caSLinJiawei // MaskedRegMap(Utvec, utvec), 640c84054caSLinJiawei 64121fa8708Swangkaifan //--- User Trap Handling --- 642c84054caSLinJiawei // MaskedRegMap(Uscratch, uscratch), 643c84054caSLinJiawei // MaskedRegMap(Uepc, uepc), 644c84054caSLinJiawei // MaskedRegMap(Ucause, ucause), 645c84054caSLinJiawei // MaskedRegMap(Utval, utval), 646c84054caSLinJiawei // MaskedRegMap(Uip, uip), 647c84054caSLinJiawei 64821fa8708Swangkaifan //--- User Counter/Timers --- 649c84054caSLinJiawei // MaskedRegMap(Cycle, cycle), 650c84054caSLinJiawei // MaskedRegMap(Time, time), 651c84054caSLinJiawei // MaskedRegMap(Instret, instret), 652c84054caSLinJiawei 65321fa8708Swangkaifan //--- Supervisor Trap Setup --- 654c84054caSLinJiawei MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 655c84054caSLinJiawei // MaskedRegMap(Sedeleg, Sedeleg), 656c84054caSLinJiawei // MaskedRegMap(Sideleg, Sideleg), 657c84054caSLinJiawei MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 658*a4e57ea3SLi Qianruo MaskedRegMap(Stvec, stvec, stvecMask, MaskedRegMap.NoSideEffect, stvecMask), 659c84054caSLinJiawei MaskedRegMap(Scounteren, scounteren), 660c84054caSLinJiawei 66121fa8708Swangkaifan //--- Supervisor Trap Handling --- 662c84054caSLinJiawei MaskedRegMap(Sscratch, sscratch), 663e30fd06aSYinan Xu MaskedRegMap(Sepc, sepc, sepcMask, MaskedRegMap.NoSideEffect, sepcMask), 664c84054caSLinJiawei MaskedRegMap(Scause, scause), 665c84054caSLinJiawei MaskedRegMap(Stval, stval), 666ab2d1905SWilliam Wang MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask), 667c84054caSLinJiawei 66821fa8708Swangkaifan //--- Supervisor Protection and Translation --- 669c5334b11SZhangZifei MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 670c84054caSLinJiawei 67135a47a38SYinan Xu //--- Supervisor Custom Read/Write Registers 672eedc2e58SSteve Gou MaskedRegMap(Sbpctl, sbpctl), 67335a47a38SYinan Xu MaskedRegMap(Spfctl, spfctl), 67435a47a38SYinan Xu MaskedRegMap(Sdsid, sdsid), 6752b8b2e7aSWilliam Wang MaskedRegMap(Slvpredctl, slvpredctl), 676f3f22d72SYinan Xu MaskedRegMap(Smblockctl, smblockctl), 677aac4464eSYinan Xu MaskedRegMap(Srnctl, srnctl), 67835a47a38SYinan Xu 67921fa8708Swangkaifan //--- Machine Information Registers --- 6805dabf2dfSYinan Xu MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 6815dabf2dfSYinan Xu MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 6825dabf2dfSYinan Xu MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 6835dabf2dfSYinan Xu MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 6847d9edc86SLemover MaskedRegMap(Mconfigptr, mconfigptr, 0.U(XLEN.W), MaskedRegMap.Unwritable), 685c84054caSLinJiawei 68621fa8708Swangkaifan //--- Machine Trap Setup --- 687e30fd06aSYinan Xu MaskedRegMap(Mstatus, mstatus, mstatusWMask, mstatusUpdateSideEffect, mstatusMask), 688c84054caSLinJiawei MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 6895dabf2dfSYinan Xu MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)), 6905dabf2dfSYinan Xu MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)), 691c84054caSLinJiawei MaskedRegMap(Mie, mie), 692*a4e57ea3SLi Qianruo MaskedRegMap(Mtvec, mtvec, mtvecMask, MaskedRegMap.NoSideEffect, mtvecMask), 693c84054caSLinJiawei MaskedRegMap(Mcounteren, mcounteren), 694c84054caSLinJiawei 69521fa8708Swangkaifan //--- Machine Trap Handling --- 696c84054caSLinJiawei MaskedRegMap(Mscratch, mscratch), 697e30fd06aSYinan Xu MaskedRegMap(Mepc, mepc, mepcMask, MaskedRegMap.NoSideEffect, mepcMask), 698c84054caSLinJiawei MaskedRegMap(Mcause, mcause), 699c84054caSLinJiawei MaskedRegMap(Mtval, mtval), 7005dabf2dfSYinan Xu MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable), 701d4aca96cSlqre 70272951335SLi Qianruo //--- Trigger --- 703716f717fSLi Qianruo MaskedRegMap(Tselect, tselectPhy, WritableMask, WriteTselect), 704ddb65c47SLi Qianruo MaskedRegMap(Tdata1, tDummy1, WritableMask, WriteTdata1, WritableMask, ReadTdata1), 705ddb65c47SLi Qianruo MaskedRegMap(Tdata2, tDummy2, WritableMask, WriteTdata2, WritableMask, ReadTdata2), 706716f717fSLi Qianruo MaskedRegMap(Tinfo, tinfo, 0.U(XLEN.W), MaskedRegMap.Unwritable), 70772951335SLi Qianruo MaskedRegMap(Tcontrol, tControlPhy, tcontrolWriteMask), 70872951335SLi Qianruo 709d4aca96cSlqre //--- Debug Mode --- 710d4aca96cSlqre MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect), 711d4aca96cSlqre MaskedRegMap(Dpc, dpc), 712d4aca96cSlqre MaskedRegMap(Dscratch, dscratch), 71312c44ce5Srvcoresjw MaskedRegMap(Dscratch1, dscratch1), 714b03ddc86Swangkaifan MaskedRegMap(Mcountinhibit, mcountinhibit), 715b03ddc86Swangkaifan MaskedRegMap(Mcycle, mcycle), 716b03ddc86Swangkaifan MaskedRegMap(Minstret, minstret), 717b03ddc86Swangkaifan ) 71812c44ce5Srvcoresjw 71912c44ce5Srvcoresjw val perfCntMapping = (0 until 29).map(i => {Map( 72012c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmevent3 +i, 72112c44ce5Srvcoresjw reg = perfEvents(i), 72212c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)), 72312c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmcounter3 +i, 72412c44ce5Srvcoresjw reg = perfCnts(i)) 72512c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 7266d96ebcdSwakafa // TODO: mechanism should be implemented later 7276d96ebcdSwakafa // val MhpmcounterStart = Mhpmcounter3 7286d96ebcdSwakafa // val MhpmeventStart = Mhpmevent3 7296d96ebcdSwakafa // for (i <- 0 until nrPerfCnts) { 7306d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 7316d96ebcdSwakafa // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 7326d96ebcdSwakafa // } 7338635f18fSwangkaifan 734e19f7967SWilliam Wang val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 735e19f7967SWilliam Wang name -> RegInit(0.U(attribute("width").toInt.W)) 736e19f7967SWilliam Wang }} 737ad3ba452Szhanglinjuan val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 738ad3ba452Szhanglinjuan MaskedRegMap( 739ad3ba452Szhanglinjuan Scachebase + attribute("offset").toInt, 740e19f7967SWilliam Wang cacheopRegs(name) 741ad3ba452Szhanglinjuan ) 742ad3ba452Szhanglinjuan }} 743b6982e83SLemover 74421fa8708Swangkaifan val mapping = basicPrivMapping ++ 7458635f18fSwangkaifan perfCntMapping ++ 74621fa8708Swangkaifan pmpMapping ++ 747ca2f90a6SLemover pmaMapping ++ 748ad3ba452Szhanglinjuan (if (HasFPU) fcsrMapping else Nil) ++ 749ad3ba452Szhanglinjuan (if (HasCustomCSRCacheOp) cacheopMapping else Nil) 750c84054caSLinJiawei 751c84054caSLinJiawei val addr = src2(11, 0) 752b1860798SZhangfw val csri = ZeroExt(src2(16, 12), XLEN) 753c84054caSLinJiawei val rdata = Wire(UInt(XLEN.W)) 754c84054caSLinJiawei val wdata = LookupTree(func, List( 755c84054caSLinJiawei CSROpType.wrt -> src1, 756c84054caSLinJiawei CSROpType.set -> (rdata | src1), 757c84054caSLinJiawei CSROpType.clr -> (rdata & (~src1).asUInt()), 758b0ae3ac4SLinJiawei CSROpType.wrti -> csri, 759c84054caSLinJiawei CSROpType.seti -> (rdata | csri), 760c84054caSLinJiawei CSROpType.clri -> (rdata & (~csri).asUInt()) 761c84054caSLinJiawei )) 762c84054caSLinJiawei 763e377d77eSWilliam Wang val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) || 764e377d77eSWilliam Wang (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U) 765e377d77eSWilliam Wang csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp 7668635f18fSwangkaifan 76747a386bfSZhangZifei // satp wen check 76847a386bfSZhangZifei val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 7692f5f05fdSWilliam Wang 770e5adbe81SLemover // csr access check, special case 771e5adbe81SLemover val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool) 772e5adbe81SLemover val accessPermitted = !(addr === Satp.U && tvmNotPermit) 773e5adbe81SLemover csrio.disableSfence := tvmNotPermit 774e5adbe81SLemover 7752f5f05fdSWilliam Wang // general CSR wen check 7762f5f05fdSWilliam Wang val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 77772951335SLi Qianruo val dcsrPermitted = dcsrPermissionCheck(addr, false.B, debugMode) 77872951335SLi Qianruo val triggerPermitted = triggerPermissionCheck(addr, true.B, debugMode) // todo dmode 77972951335SLi Qianruo val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) && dcsrPermitted && triggerPermitted 78087acdd8eSwangkaifan val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 781e5adbe81SLemover val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted 782e5adbe81SLemover 7838e7b11e5SWilliam Wang MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 784ead41f51SLinJiawei io.out.bits.data := rdata 785ead41f51SLinJiawei io.out.bits.uop := io.in.bits.uop 786e18c367fSLinJiawei io.out.bits.uop.cf := cfOut 787e18c367fSLinJiawei io.out.bits.uop.ctrl.flushPipe := flushPipe 788c84054caSLinJiawei 789b6982e83SLemover // send distribute csr a w signal 790b6982e83SLemover csrio.customCtrl.distribute_csr.w.valid := wen && permitted 791b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.data := wdata 792b6982e83SLemover csrio.customCtrl.distribute_csr.w.bits.addr := addr 793b6982e83SLemover 794c84054caSLinJiawei // Fix Mip/Sip write 795c84054caSLinJiawei val fixMapping = Map( 796c84054caSLinJiawei MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 797ab2d1905SWilliam Wang MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask) 798c84054caSLinJiawei ) 799ab2d1905SWilliam Wang val rdataFix = Wire(UInt(XLEN.W)) 800ab2d1905SWilliam Wang val wdataFix = LookupTree(func, List( 801ab2d1905SWilliam Wang CSROpType.wrt -> src1, 802ab2d1905SWilliam Wang CSROpType.set -> (rdataFix | src1), 803ab2d1905SWilliam Wang CSROpType.clr -> (rdataFix & (~src1).asUInt()), 804ab2d1905SWilliam Wang CSROpType.wrti -> csri, 805ab2d1905SWilliam Wang CSROpType.seti -> (rdataFix | csri), 806ab2d1905SWilliam Wang CSROpType.clri -> (rdataFix & (~csri).asUInt()) 807ab2d1905SWilliam Wang )) 808ab2d1905SWilliam Wang MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix) 809c84054caSLinJiawei 810*a4e57ea3SLi Qianruo when (RegNext(csrio.fpu.fflags.valid)) { 811*a4e57ea3SLi Qianruo fcsr := fflags_wfn(update = true)(RegNext(csrio.fpu.fflags.bits)) 812c84054caSLinJiawei } 813c84054caSLinJiawei // set fs and sd in mstatus 814*a4e57ea3SLi Qianruo when (csrw_dirty_fp_state || RegNext(csrio.fpu.dirty_fs)) { 815c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 816c84054caSLinJiawei mstatusNew.fs := "b11".U 817c84054caSLinJiawei mstatusNew.sd := true.B 818c84054caSLinJiawei mstatus := mstatusNew.asUInt() 819c84054caSLinJiawei } 820129a273eSYinan Xu csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 821c84054caSLinJiawei 82272951335SLi Qianruo 82372951335SLi Qianruo // Trigger Ctrl 824716f717fSLi Qianruo csrio.customCtrl.trigger_enable := tdata1Phy.map{t => 825716f717fSLi Qianruo def tdata1 = t.asTypeOf(new TdataBundle) 826716f717fSLi Qianruo tdata1.m && priviledgeMode === ModeM || 82772951335SLi Qianruo tdata1.s && priviledgeMode === ModeS || tdata1.u && priviledgeMode === ModeU 82872951335SLi Qianruo } 829ddb65c47SLi Qianruo csrio.customCtrl.frontend_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) === I_Trigger) 830ddb65c47SLi Qianruo csrio.customCtrl.mem_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) =/= I_Trigger) 831068bf978SLi Qianruo XSDebug(csrio.customCtrl.trigger_enable.asUInt.orR(), p"Debug Mode: At least 1 trigger is enabled, trigger enable is ${Binary(csrio.customCtrl.trigger_enable.asUInt())}\n") 83272951335SLi Qianruo 833c84054caSLinJiawei // CSR inst decode 8348e7b11e5SWilliam Wang val isEbreak = addr === privEbreak && func === CSROpType.jmp 835c84054caSLinJiawei val isEcall = addr === privEcall && func === CSROpType.jmp 836c84054caSLinJiawei val isMret = addr === privMret && func === CSROpType.jmp 837c84054caSLinJiawei val isSret = addr === privSret && func === CSROpType.jmp 838c84054caSLinJiawei val isUret = addr === privUret && func === CSROpType.jmp 839d4aca96cSlqre val isDret = addr === privDret && func === CSROpType.jmp 840c84054caSLinJiawei 841e18c367fSLinJiawei XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 842e18c367fSLinJiawei XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 843bf9968b2SYinan Xu 8448e7b11e5SWilliam Wang // Illegal priviledged operation list 8458e7b11e5SWilliam Wang val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 846c84054caSLinJiawei 8478e7b11e5SWilliam Wang // Illegal priviledged instruction check 8488e7b11e5SWilliam Wang val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 8498e7b11e5SWilliam Wang val isIllegalAccess = !permitted 8508e7b11e5SWilliam Wang val isIllegalPrivOp = illegalSModeSret 851c84054caSLinJiawei 852ad3ba452Szhanglinjuan // expose several csr bits for tlb 853fcff7e94SZhangZifei tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 854fcff7e94SZhangZifei tlbBundle.priv.sum := mstatusStruct.sum.asBool 855fcff7e94SZhangZifei tlbBundle.priv.imode := priviledgeMode 856fcff7e94SZhangZifei tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 857c84054caSLinJiawei 858e9341afdSYinan Xu // Branch control 859c84054caSLinJiawei val retTarget = Wire(UInt(VAddrBits.W)) 8608e7b11e5SWilliam Wang val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 861bc63e578SLi Qianruo flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall && !isEbreak) 862c84054caSLinJiawei 863c84054caSLinJiawei retTarget := DontCare 864c84054caSLinJiawei // val illegalEret = TODO 865c84054caSLinJiawei 866d4aca96cSlqre when (valid && isDret) { 867d4aca96cSlqre val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 868d4aca96cSlqre val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 869d4aca96cSlqre val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 870d4aca96cSlqre val debugModeNew = WireInit(debugMode) 871d4aca96cSlqre 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. 872d4aca96cSlqre mstatus := mstatusNew.asUInt 873d4aca96cSlqre priviledgeMode := dcsrNew.prv 874d4aca96cSlqre retTarget := dpc(VAddrBits-1, 0) 875d4aca96cSlqre debugModeNew := false.B 876d4aca96cSlqre debugIntrEnable := true.B 877d4aca96cSlqre debugMode := debugModeNew 878d4aca96cSlqre XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 879d4aca96cSlqre } 880d4aca96cSlqre 881c84054caSLinJiawei when (valid && isMret) { 882c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 883c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 884c84054caSLinJiawei mstatusNew.ie.m := mstatusOld.pie.m 885c84054caSLinJiawei priviledgeMode := mstatusOld.mpp 886c84054caSLinJiawei mstatusNew.pie.m := true.B 887c84054caSLinJiawei mstatusNew.mpp := ModeU 888c266a93bSLemover when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U } 889c84054caSLinJiawei mstatus := mstatusNew.asUInt 890c84054caSLinJiawei // lr := false.B 891c84054caSLinJiawei retTarget := mepc(VAddrBits-1, 0) 892c84054caSLinJiawei } 893c84054caSLinJiawei 8948e7b11e5SWilliam Wang when (valid && isSret && !illegalSModeSret) { 895c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 896c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 897c84054caSLinJiawei mstatusNew.ie.s := mstatusOld.pie.s 898c84054caSLinJiawei priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 899c84054caSLinJiawei mstatusNew.pie.s := true.B 900c84054caSLinJiawei mstatusNew.spp := ModeU 901c84054caSLinJiawei mstatus := mstatusNew.asUInt 9027d9edc86SLemover when (mstatusOld.spp =/= ModeM) { mstatusNew.mprv := 0.U } 903c84054caSLinJiawei // lr := false.B 904c84054caSLinJiawei retTarget := sepc(VAddrBits-1, 0) 905c84054caSLinJiawei } 906c84054caSLinJiawei 907c84054caSLinJiawei when (valid && isUret) { 908c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 909c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 910c84054caSLinJiawei // mstatusNew.mpp.m := ModeU //TODO: add mode U 911c84054caSLinJiawei mstatusNew.ie.u := mstatusOld.pie.u 912c84054caSLinJiawei priviledgeMode := ModeU 913c84054caSLinJiawei mstatusNew.pie.u := true.B 914c84054caSLinJiawei mstatus := mstatusNew.asUInt 915c84054caSLinJiawei retTarget := uepc(VAddrBits-1, 0) 916c84054caSLinJiawei } 917c84054caSLinJiawei 918e9341afdSYinan Xu io.in.ready := true.B 919e9341afdSYinan Xu io.out.valid := valid 920e9341afdSYinan Xu 921d4aca96cSlqre val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku) 922d4aca96cSlqre 923baf8def6SYinan Xu val csrExceptionVec = WireInit(cfIn.exceptionVec) 924d4aca96cSlqre csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException 925baf8def6SYinan Xu csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 926baf8def6SYinan Xu csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 927baf8def6SYinan Xu csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 928baf8def6SYinan Xu // Trigger an illegal instr exception when: 929baf8def6SYinan Xu // * unimplemented csr is being read/written 930baf8def6SYinan Xu // * csr access is illegal 931baf8def6SYinan Xu csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 932baf8def6SYinan Xu cfOut.exceptionVec := csrExceptionVec 933baf8def6SYinan Xu 93484e47f35SLi Qianruo XSDebug(io.in.valid && isEbreak, s"Debug Mode: an Ebreak is executed, ebreak cause exception ? ${ebreakCauseException}\n") 93584e47f35SLi Qianruo 936e9341afdSYinan Xu /** 937e9341afdSYinan Xu * Exception and Intr 938e9341afdSYinan Xu */ 939e9341afdSYinan Xu val ideleg = (mideleg & mip.asUInt) 940e9341afdSYinan Xu def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 941e9341afdSYinan Xu ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 942e9341afdSYinan Xu 943d4aca96cSlqre val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 944d4aca96cSlqre XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 9459aca92b9SYinan Xu // send interrupt information to ROB 946e9341afdSYinan Xu val intrVecEnable = Wire(Vec(12, Bool())) 947e9341afdSYinan Xu intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 948d4aca96cSlqre val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 949e9341afdSYinan Xu val intrBitSet = intrVec.orR() 950e9341afdSYinan Xu csrio.interrupt := intrBitSet 951e9341afdSYinan Xu mipWire.t.m := csrio.externalInterrupt.mtip 952e9341afdSYinan Xu mipWire.s.m := csrio.externalInterrupt.msip 953e9341afdSYinan Xu mipWire.e.m := csrio.externalInterrupt.meip 954b3d79b37SYinan Xu mipWire.e.s := csrio.externalInterrupt.seip 955e9341afdSYinan Xu 956e9341afdSYinan Xu // interrupts 957e9341afdSYinan Xu val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 9582d7c7105SYinan Xu val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 959*a4e57ea3SLi Qianruo val ivmEnable = tlbBundle.priv.imode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 960*a4e57ea3SLi Qianruo val iexceptionPC = Mux(ivmEnable, SignExt(csrio.exception.bits.uop.cf.pc, XLEN), csrio.exception.bits.uop.cf.pc) 961*a4e57ea3SLi Qianruo val dvmEnable = tlbBundle.priv.dmode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U 962*a4e57ea3SLi Qianruo val dexceptionPC = Mux(dvmEnable, SignExt(csrio.exception.bits.uop.cf.pc, XLEN), csrio.exception.bits.uop.cf.pc) 963*a4e57ea3SLi Qianruo XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", dexceptionPC, intrNO) 964d4aca96cSlqre val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr 965e9341afdSYinan Xu 966e9341afdSYinan Xu // exceptions 9672d7c7105SYinan Xu val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 9682d7c7105SYinan Xu val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 9692d7c7105SYinan Xu val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 9702d7c7105SYinan Xu val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 9712d7c7105SYinan Xu val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 9722d7c7105SYinan Xu val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 9732d7c7105SYinan Xu val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 9742d7c7105SYinan Xu val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 9752d7c7105SYinan Xu val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 976d4aca96cSlqre val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException 97772951335SLi Qianruo val hasSingleStep = csrio.exception.bits.uop.ctrl.singleStep && raiseException 978ddb65c47SLi Qianruo val hasTriggerHit = (csrio.exception.bits.uop.cf.trigger.hit) && raiseException 97984e47f35SLi Qianruo 98084e47f35SLi Qianruo XSDebug(hasSingleStep, "Debug Mode: single step exception\n") 981ddb65c47SLi Qianruo XSDebug(hasTriggerHit, p"Debug Mode: trigger hit, is frontend? ${Binary(csrio.exception.bits.uop.cf.trigger.frontendHit.asUInt)} " + 982068bf978SLi Qianruo p"backend hit vec ${Binary(csrio.exception.bits.uop.cf.trigger.backendHit.asUInt)}\n") 983e9341afdSYinan Xu 9842d7c7105SYinan Xu val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 9856ab6918fSYinan Xu val regularExceptionNO = ExceptionNO.priorities.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 98672951335SLi Qianruo val exceptionNO = Mux(hasSingleStep || hasTriggerHit, 3.U, regularExceptionNO) 987e9341afdSYinan Xu val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 988e9341afdSYinan Xu 989e9341afdSYinan Xu val raiseExceptionIntr = csrio.exception.valid 990d4aca96cSlqre 99184e47f35SLi Qianruo val raiseDebugExceptionIntr = !debugMode && (hasbreakPoint || raiseDebugIntr || hasSingleStep || hasTriggerHit && triggerAction) // TODO 9921097f021SLi Qianruo val ebreakEnterParkLoop = debugMode && raiseExceptionIntr 993d4aca96cSlqre 994e9341afdSYinan Xu XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 995*a4e57ea3SLi Qianruo dexceptionPC, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 996e9341afdSYinan Xu ) 997e9341afdSYinan Xu XSDebug(raiseExceptionIntr, 998e9341afdSYinan Xu "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 999*a4e57ea3SLi Qianruo dexceptionPC, 1000e9341afdSYinan Xu mstatus, 1001e9341afdSYinan Xu mideleg, 1002e9341afdSYinan Xu medeleg, 1003e9341afdSYinan Xu priviledgeMode 1004e9341afdSYinan Xu ) 1005e9341afdSYinan Xu 1006e9341afdSYinan Xu // mtval write logic 10078a33de1fSYinan Xu // Due to timing reasons of memExceptionVAddr, we delay the write of mtval and stval 1008e9341afdSYinan Xu val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 1009*a4e57ea3SLi Qianruo val updateTval = VecInit(Seq( 1010*a4e57ea3SLi Qianruo hasInstrPageFault, 1011*a4e57ea3SLi Qianruo hasLoadPageFault, 1012*a4e57ea3SLi Qianruo hasStorePageFault, 1013*a4e57ea3SLi Qianruo hasInstrAccessFault, 1014*a4e57ea3SLi Qianruo hasLoadAccessFault, 1015*a4e57ea3SLi Qianruo hasStoreAccessFault, 1016*a4e57ea3SLi Qianruo hasLoadAddrMisaligned, 1017*a4e57ea3SLi Qianruo hasStoreAddrMisaligned 1018*a4e57ea3SLi Qianruo )).asUInt.orR 1019*a4e57ea3SLi Qianruo when (RegNext(RegNext(updateTval))) { 10208a33de1fSYinan Xu val tval = RegNext(Mux( 1021*a4e57ea3SLi Qianruo RegNext(hasInstrPageFault || hasInstrAccessFault), 10228a33de1fSYinan Xu RegNext(Mux( 10232d7c7105SYinan Xu csrio.exception.bits.uop.cf.crossPageIPFFix, 10242d7c7105SYinan Xu SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 1025*a4e57ea3SLi Qianruo iexceptionPC 10268a33de1fSYinan Xu )), 1027e9341afdSYinan Xu memExceptionAddr 10288a33de1fSYinan Xu )) 1029*a4e57ea3SLi Qianruo when (RegNext(priviledgeMode === ModeM)) { 1030e9341afdSYinan Xu mtval := tval 1031e9341afdSYinan Xu }.otherwise { 1032e9341afdSYinan Xu stval := tval 1033e9341afdSYinan Xu } 1034e9341afdSYinan Xu } 1035e9341afdSYinan Xu 1036d4aca96cSlqre val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 1037e9341afdSYinan Xu val deleg = Mux(raiseIntr, mideleg , medeleg) 1038e9341afdSYinan Xu // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 1039ac5a5d53SLinJiawei val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 1040*a4e57ea3SLi Qianruo val clearTval = !updateTval || raiseIntr 1041d4aca96cSlqre val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak 104213096f7eSYinan Xu 104313096f7eSYinan Xu // ctrl block will use theses later for flush 104413096f7eSYinan Xu val isXRetFlag = RegInit(false.B) 1045*a4e57ea3SLi Qianruo when (DelayN(io.redirectIn.valid, 5)) { 104613096f7eSYinan Xu isXRetFlag := false.B 104713096f7eSYinan Xu }.elsewhen (isXRet) { 104813096f7eSYinan Xu isXRetFlag := true.B 104913096f7eSYinan Xu } 105013096f7eSYinan Xu csrio.isXRet := isXRetFlag 1051*a4e57ea3SLi Qianruo val retTargetReg = RegEnable(retTarget, isXRet) 1052*a4e57ea3SLi Qianruo 1053*a4e57ea3SLi Qianruo val tvec = Mux(delegS, stvec, mtvec) 1054*a4e57ea3SLi Qianruo val tvecBase = tvec(VAddrBits - 1, 2) 1055*a4e57ea3SLi Qianruo // XRet sends redirect instead of Flush and isXRetFlag is true.B before redirect.valid. 1056*a4e57ea3SLi Qianruo // ROB sends exception at T0 while CSR receives at T2. 1057*a4e57ea3SLi Qianruo // We add a RegNext here and trapTarget is valid at T3. 1058*a4e57ea3SLi Qianruo csrio.trapTarget := RegEnable(Mux(isXRetFlag, 105913096f7eSYinan Xu retTargetReg, 1060d4aca96cSlqre Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget, 1061*a4e57ea3SLi Qianruo // When MODE=Vectored, all synchronous exceptions into M/S mode 1062*a4e57ea3SLi Qianruo // cause the pc to be set to the address in the BASE field, whereas 1063*a4e57ea3SLi Qianruo // interrupts cause the pc to be set to the address in the BASE field 1064*a4e57ea3SLi Qianruo // plus four times the interrupt cause number. 1065*a4e57ea3SLi Qianruo Cat(tvecBase + Mux(tvec(0) && raiseIntr, causeNO(3, 0), 0.U), 0.U(2.W)) 1066*a4e57ea3SLi Qianruo )), isXRetFlag || csrio.exception.valid) 1067e9341afdSYinan Xu 1068c84054caSLinJiawei when (raiseExceptionIntr) { 1069c84054caSLinJiawei val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1070c84054caSLinJiawei val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1071d4aca96cSlqre val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1072d4aca96cSlqre val debugModeNew = WireInit(debugMode) 1073c84054caSLinJiawei 1074d4aca96cSlqre when (raiseDebugExceptionIntr) { 1075d4aca96cSlqre when (raiseDebugIntr) { 1076d4aca96cSlqre debugModeNew := true.B 1077d4aca96cSlqre mstatusNew.mprv := false.B 1078*a4e57ea3SLi Qianruo dpc := iexceptionPC 1079d4aca96cSlqre dcsrNew.cause := 1.U 1080d4aca96cSlqre dcsrNew.prv := priviledgeMode 1081d4aca96cSlqre priviledgeMode := ModeM 1082d4aca96cSlqre XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 1083d4aca96cSlqre }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) { 1084d4aca96cSlqre // ebreak or ss in running hart 1085d4aca96cSlqre debugModeNew := true.B 1086*a4e57ea3SLi Qianruo dpc := iexceptionPC 1087d4aca96cSlqre dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U) 1088d4aca96cSlqre dcsrNew.prv := priviledgeMode // TODO 1089d4aca96cSlqre priviledgeMode := ModeM 1090d4aca96cSlqre mstatusNew.mprv := false.B 1091d4aca96cSlqre } 1092d4aca96cSlqre dcsr := dcsrNew.asUInt 1093d4aca96cSlqre debugIntrEnable := false.B 1094d4aca96cSlqre }.elsewhen (delegS) { 1095c84054caSLinJiawei scause := causeNO 1096*a4e57ea3SLi Qianruo sepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1097c84054caSLinJiawei mstatusNew.spp := priviledgeMode 1098c84054caSLinJiawei mstatusNew.pie.s := mstatusOld.ie.s 1099c84054caSLinJiawei mstatusNew.ie.s := false.B 1100c84054caSLinJiawei priviledgeMode := ModeS 1101*a4e57ea3SLi Qianruo when (clearTval) { stval := 0.U } 1102c84054caSLinJiawei }.otherwise { 1103c84054caSLinJiawei mcause := causeNO 1104*a4e57ea3SLi Qianruo mepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC) 1105c84054caSLinJiawei mstatusNew.mpp := priviledgeMode 1106c84054caSLinJiawei mstatusNew.pie.m := mstatusOld.ie.m 1107c84054caSLinJiawei mstatusNew.ie.m := false.B 1108c84054caSLinJiawei priviledgeMode := ModeM 1109*a4e57ea3SLi Qianruo when (clearTval) { mtval := 0.U } 1110c84054caSLinJiawei } 1111c84054caSLinJiawei mstatus := mstatusNew.asUInt 1112d4aca96cSlqre debugMode := debugModeNew 1113c84054caSLinJiawei } 1114c84054caSLinJiawei 1115e18c367fSLinJiawei XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 1116bf9968b2SYinan Xu 1117e19f7967SWilliam Wang // Distributed CSR update req 1118e19f7967SWilliam Wang // 1119e19f7967SWilliam Wang // For now we use it to implement customized cache op 112070899835SWilliam Wang // It can be delayed if necessary 1121e19f7967SWilliam Wang 112270899835SWilliam Wang val delayedUpdate0 = DelayN(csrio.distributedUpdate(0), 2) 112370899835SWilliam Wang val delayedUpdate1 = DelayN(csrio.distributedUpdate(1), 2) 112470899835SWilliam Wang val distributedUpdateValid = delayedUpdate0.w.valid || delayedUpdate1.w.valid 112570899835SWilliam Wang val distributedUpdateAddr = Mux(delayedUpdate0.w.valid, 112670899835SWilliam Wang delayedUpdate0.w.bits.addr, 112770899835SWilliam Wang delayedUpdate1.w.bits.addr 112870899835SWilliam Wang ) 112970899835SWilliam Wang val distributedUpdateData = Mux(delayedUpdate0.w.valid, 113070899835SWilliam Wang delayedUpdate0.w.bits.data, 113170899835SWilliam Wang delayedUpdate1.w.bits.data 113270899835SWilliam Wang ) 113370899835SWilliam Wang 113470899835SWilliam Wang assert(!(delayedUpdate0.w.valid && delayedUpdate1.w.valid)) 113570899835SWilliam Wang 113670899835SWilliam Wang when(distributedUpdateValid){ 1137e19f7967SWilliam Wang // cacheopRegs can be distributed updated 1138e19f7967SWilliam Wang CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 113970899835SWilliam Wang when((Scachebase + attribute("offset").toInt).U === distributedUpdateAddr){ 114070899835SWilliam Wang cacheopRegs(name) := distributedUpdateData 1141e19f7967SWilliam Wang } 1142e19f7967SWilliam Wang }} 1143e19f7967SWilliam Wang } 1144e19f7967SWilliam Wang 1145e30fd06aSYinan Xu // Implicit add reset values for mepc[0] and sepc[0] 1146e30fd06aSYinan Xu // TODO: rewrite mepc and sepc using a struct-like style with the LSB always being 0 1147e30fd06aSYinan Xu when (reset.asBool) { 1148e30fd06aSYinan Xu mepc := Cat(mepc(XLEN - 1, 1), 0.U(1.W)) 1149e30fd06aSYinan Xu sepc := Cat(sepc(XLEN - 1, 1), 0.U(1.W)) 1150e30fd06aSYinan Xu } 1151e30fd06aSYinan Xu 1152c84054caSLinJiawei def readWithScala(addr: Int): UInt = mapping(addr)._1 1153c84054caSLinJiawei 1154a165bd69Swangkaifan val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 1155a165bd69Swangkaifan 1156cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1157cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 11582225d46eSJiawei Lin val difftest = Module(new DifftestArchEvent) 11592225d46eSJiawei Lin difftest.io.clock := clock 11605668a921SJiawei Lin difftest.io.coreid := csrio.hartId 11618a33de1fSYinan Xu difftest.io.intrNO := RegNext(RegNext(RegNext(difftestIntrNO))) 11628a33de1fSYinan Xu difftest.io.cause := RegNext(RegNext(RegNext(Mux(csrio.exception.valid, causeNO, 0.U)))) 1163*a4e57ea3SLi Qianruo difftest.io.exceptionPC := RegNext(RegNext(RegNext(dexceptionPC))) 1164*a4e57ea3SLi Qianruo if (env.EnableDifftest) { 1165*a4e57ea3SLi Qianruo difftest.io.exceptionInst := RegNext(RegNext(RegNext(csrio.exception.bits.uop.cf.instr))) 1166*a4e57ea3SLi Qianruo } 11672225d46eSJiawei Lin } 11682225d46eSJiawei Lin 1169cbe9a847SYinan Xu // Always instantiate basic difftest modules. 1170cbe9a847SYinan Xu if (env.AlwaysBasicDiff || env.EnableDifftest) { 11712225d46eSJiawei Lin val difftest = Module(new DifftestCSRState) 11722225d46eSJiawei Lin difftest.io.clock := clock 11735668a921SJiawei Lin difftest.io.coreid := csrio.hartId 11742225d46eSJiawei Lin difftest.io.priviledgeMode := priviledgeMode 11752225d46eSJiawei Lin difftest.io.mstatus := mstatus 11762225d46eSJiawei Lin difftest.io.sstatus := mstatus & sstatusRmask 11772225d46eSJiawei Lin difftest.io.mepc := mepc 11782225d46eSJiawei Lin difftest.io.sepc := sepc 11792225d46eSJiawei Lin difftest.io.mtval:= mtval 11802225d46eSJiawei Lin difftest.io.stval:= stval 11812225d46eSJiawei Lin difftest.io.mtvec := mtvec 11822225d46eSJiawei Lin difftest.io.stvec := stvec 11832225d46eSJiawei Lin difftest.io.mcause := mcause 11842225d46eSJiawei Lin difftest.io.scause := scause 11852225d46eSJiawei Lin difftest.io.satp := satp 11862225d46eSJiawei Lin difftest.io.mip := mipReg 11872225d46eSJiawei Lin difftest.io.mie := mie 11882225d46eSJiawei Lin difftest.io.mscratch := mscratch 11892225d46eSJiawei Lin difftest.io.sscratch := sscratch 11902225d46eSJiawei Lin difftest.io.mideleg := mideleg 11912225d46eSJiawei Lin difftest.io.medeleg := medeleg 1192a165bd69Swangkaifan } 1193*a4e57ea3SLi Qianruo 1194*a4e57ea3SLi Qianruo if(env.AlwaysBasicDiff || env.EnableDifftest) { 1195*a4e57ea3SLi Qianruo val difftest = Module(new DifftestDebugMode) 1196*a4e57ea3SLi Qianruo difftest.io.clock := clock 1197*a4e57ea3SLi Qianruo difftest.io.coreid := csrio.hartId 1198*a4e57ea3SLi Qianruo difftest.io.debugMode := debugMode 1199*a4e57ea3SLi Qianruo difftest.io.dcsr := dcsr 1200*a4e57ea3SLi Qianruo difftest.io.dpc := dpc 1201*a4e57ea3SLi Qianruo difftest.io.dscratch0 := dscratch 1202*a4e57ea3SLi Qianruo difftest.io.dscratch1 := dscratch1 1203*a4e57ea3SLi Qianruo } 1204c84054caSLinJiawei} 12051545277aSYinan Xu 1206cd365d4cSrvcoresjwclass PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst { 1207cd365d4cSrvcoresjw val io = IO(new Bundle { 1208cd365d4cSrvcoresjw val distribute_csr = Flipped(new DistributedCSRIO()) 1209cd365d4cSrvcoresjw val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1210cd365d4cSrvcoresjw }) 1211cd365d4cSrvcoresjw 1212cd365d4cSrvcoresjw val w = io.distribute_csr.w 1213cd365d4cSrvcoresjw 12145fd90906Srvcoresjw val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 12155fd90906Srvcoresjw List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 12165fd90906Srvcoresjw List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 12175fd90906Srvcoresjw List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 1218cd365d4cSrvcoresjw 121912c44ce5Srvcoresjw val perfEventMapping = (0 until 29).map(i => {Map( 122012c44ce5Srvcoresjw MaskedRegMap(addr = Mhpmevent3 +i, 122112c44ce5Srvcoresjw reg = perfEvents(i), 122212c44ce5Srvcoresjw wmask = "hf87fff3fcff3fcff".U(XLEN.W)) 122312c44ce5Srvcoresjw )}).fold(Map())((a,b) => a ++ b) 1224cd365d4cSrvcoresjw 1225cd365d4cSrvcoresjw val rdata = Wire(UInt(XLEN.W)) 1226cd365d4cSrvcoresjw MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 12275fd90906Srvcoresjw for(i <- 0 until 29){ 12285fd90906Srvcoresjw io.hpmevent(i) := perfEvents(i) 12295fd90906Srvcoresjw } 1230cd365d4cSrvcoresjw} 1231cd365d4cSrvcoresjw 1232