1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.backend.fu 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import freechips.rocketchip.util._ 23import utils.MaskedRegMap.WritableMask 24import utils._ 25import xiangshan._ 26import xiangshan.backend._ 27import xiangshan.cache._ 28import xiangshan.frontend.BPUCtrl 29import xiangshan.backend.fu.util._ 30import difftest._ 31 32trait HasExceptionNO { 33 def instrAddrMisaligned = 0 34 def instrAccessFault = 1 35 def illegalInstr = 2 36 def breakPoint = 3 37 def loadAddrMisaligned = 4 38 def loadAccessFault = 5 39 def storeAddrMisaligned = 6 40 def storeAccessFault = 7 41 def ecallU = 8 42 def ecallS = 9 43 def ecallM = 11 44 def instrPageFault = 12 45 def loadPageFault = 13 46 def storePageFault = 15 47 48 def singleStep = 14 49 50 val ExcPriority = Seq( 51 breakPoint, // TODO: different BP has different priority 52 singleStep, 53 instrPageFault, 54 instrAccessFault, 55 illegalInstr, 56 instrAddrMisaligned, 57 ecallM, ecallS, ecallU, 58 storePageFault, 59 loadPageFault, 60 storeAccessFault, 61 loadAccessFault, 62 storeAddrMisaligned, 63 loadAddrMisaligned 64 ) 65 val frontendSet = List( 66 // instrAddrMisaligned, 67 instrAccessFault, 68 illegalInstr, 69 instrPageFault 70 ) 71 val csrSet = List( 72 illegalInstr, 73 breakPoint, 74 ecallU, 75 ecallS, 76 ecallM 77 ) 78 val loadUnitSet = List( 79 loadAddrMisaligned, 80 loadAccessFault, 81 loadPageFault 82 ) 83 val storeUnitSet = List( 84 storeAddrMisaligned, 85 storeAccessFault, 86 storePageFault 87 ) 88 val atomicsUnitSet = (loadUnitSet ++ storeUnitSet).distinct 89 val allPossibleSet = (frontendSet ++ csrSet ++ loadUnitSet ++ storeUnitSet).distinct 90 val csrWbCount = (0 until 16).map(i => if (csrSet.contains(i)) 1 else 0) 91 val loadWbCount = (0 until 16).map(i => if (loadUnitSet.contains(i)) 1 else 0) 92 val storeWbCount = (0 until 16).map(i => if (storeUnitSet.contains(i)) 1 else 0) 93 val atomicsWbCount = (0 until 16).map(i => if (atomicsUnitSet.contains(i)) 1 else 0) 94 val writebackCount = (0 until 16).map(i => csrWbCount(i) + atomicsWbCount(i) + loadWbCount(i) + 2 * storeWbCount(i)) 95 def partialSelect(vec: Vec[Bool], select: Seq[Int], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = { 96 if (dontCareBits) { 97 val new_vec = Wire(ExceptionVec()) 98 new_vec := DontCare 99 select.map(i => new_vec(i) := vec(i)) 100 return new_vec 101 } 102 else if (falseBits) { 103 val new_vec = Wire(ExceptionVec()) 104 new_vec.map(_ := false.B) 105 select.map(i => new_vec(i) := vec(i)) 106 return new_vec 107 } 108 else { 109 val new_vec = Wire(Vec(select.length, Bool())) 110 select.zipWithIndex.map{ case(s, i) => new_vec(i) := vec(s) } 111 return new_vec 112 } 113 } 114 def selectFrontend(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 115 partialSelect(vec, frontendSet, dontCareBits, falseBits) 116 def selectCSR(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 117 partialSelect(vec, csrSet, dontCareBits, falseBits) 118 def selectLoad(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 119 partialSelect(vec, loadUnitSet, dontCareBits, falseBits) 120 def selectStore(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 121 partialSelect(vec, storeUnitSet, dontCareBits, falseBits) 122 def selectAtomics(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 123 partialSelect(vec, atomicsUnitSet, dontCareBits, falseBits) 124 def selectAll(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 125 partialSelect(vec, allPossibleSet, dontCareBits, falseBits) 126} 127 128class FpuCsrIO extends Bundle { 129 val fflags = Output(Valid(UInt(5.W))) 130 val isIllegal = Output(Bool()) 131 val dirty_fs = Output(Bool()) 132 val frm = Input(UInt(3.W)) 133} 134 135 136class PerfCounterIO(implicit p: Parameters) extends XSBundle { 137 val perfEventsFrontend = (new PerfEventsBundle(numCSRPCntFrontend )) 138 val perfEventsCtrl = (new PerfEventsBundle(numCSRPCntCtrl )) 139 val perfEventsLsu = (new PerfEventsBundle(numCSRPCntLsu )) 140 val perfEventsHc = Vec(numPCntHc * coreParams.L2NBanks,(UInt(6.W))) 141 val retiredInstr = UInt(3.W) 142 val frontendInfo = new Bundle { 143 val ibufFull = Bool() 144 val bpuInfo = new Bundle { 145 val bpRight = UInt(XLEN.W) 146 val bpWrong = UInt(XLEN.W) 147 } 148 } 149 val ctrlInfo = new Bundle { 150 val robFull = Bool() 151 val intdqFull = Bool() 152 val fpdqFull = Bool() 153 val lsdqFull = Bool() 154 } 155 val memInfo = new Bundle { 156 val sqFull = Bool() 157 val lqFull = Bool() 158 val dcacheMSHRFull = Bool() 159 } 160 161 val cacheInfo = new Bundle { 162 val l2MSHRFull = Bool() 163 val l3MSHRFull = Bool() 164 val l2nAcquire = UInt(XLEN.W) 165 val l2nAcquireMiss = UInt(XLEN.W) 166 val l3nAcquire = UInt(XLEN.W) 167 val l3nAcquireMiss = UInt(XLEN.W) 168 } 169} 170 171class CSRFileIO(implicit p: Parameters) extends XSBundle { 172 val hartId = Input(UInt(64.W)) 173 // output (for func === CSROpType.jmp) 174 val perf = Input(new PerfCounterIO) 175 val isPerfCnt = Output(Bool()) 176 // to FPU 177 val fpu = Flipped(new FpuCsrIO) 178 // from rob 179 val exception = Flipped(ValidIO(new ExceptionInfo)) 180 // to ROB 181 val isXRet = Output(Bool()) 182 val trapTarget = Output(UInt(VAddrBits.W)) 183 val interrupt = Output(Bool()) 184 // from LSQ 185 val memExceptionVAddr = Input(UInt(VAddrBits.W)) 186 // from outside cpu,externalInterrupt 187 val externalInterrupt = new ExternalInterruptIO 188 // TLB 189 val tlb = Output(new TlbCsrBundle) 190 // Debug Mode 191 val singleStep = Output(Bool()) 192 val debugMode = Output(Bool()) 193 // Custom microarchiture ctrl signal 194 val customCtrl = Output(new CustomCSRCtrlIO) 195 val distributedUpdate = Flipped(new DistributedCSRUpdateReq) 196 // to Fence to disable sfence 197 val disableSfence = Output(Bool()) 198 // distributed csr w 199} 200 201class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMPMethod with PMAMethod 202{ 203 val csrio = IO(new CSRFileIO) 204 205 val cfIn = io.in.bits.uop.cf 206 val cfOut = Wire(new CtrlFlow) 207 cfOut := cfIn 208 val flushPipe = Wire(Bool()) 209 210 val (valid, src1, src2, func) = ( 211 io.in.valid, 212 io.in.bits.src(0), 213 io.in.bits.uop.ctrl.imm, 214 io.in.bits.uop.ctrl.fuOpType 215 ) 216 217 // CSR define 218 219 class Priv extends Bundle { 220 val m = Output(Bool()) 221 val h = Output(Bool()) 222 val s = Output(Bool()) 223 val u = Output(Bool()) 224 } 225 226 val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U) 227 228 class DcsrStruct extends Bundle { 229 val xdebugver = Output(UInt(2.W)) 230 val zero4 = Output(UInt(2.W)) 231 val zero3 = Output(UInt(12.W)) 232 val ebreakm = Output(Bool()) 233 val ebreakh = Output(Bool()) 234 val ebreaks = Output(Bool()) 235 val ebreaku = Output(Bool()) 236 val zero2 = Output(Bool()) 237 val stopcycle = Output(Bool()) 238 val stoptime = Output(Bool()) 239 val cause = Output(UInt(3.W)) 240 val zero1 = Output(UInt(3.W)) 241 val step = Output(Bool()) 242 val prv = Output(UInt(2.W)) 243 } 244 245 class MstatusStruct extends Bundle { 246 val sd = Output(UInt(1.W)) 247 248 val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null 249 val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 250 val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 251 val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 252 253 val tsr = Output(UInt(1.W)) 254 val tw = Output(UInt(1.W)) 255 val tvm = Output(UInt(1.W)) 256 val mxr = Output(UInt(1.W)) 257 val sum = Output(UInt(1.W)) 258 val mprv = Output(UInt(1.W)) 259 val xs = Output(UInt(2.W)) 260 val fs = Output(UInt(2.W)) 261 val mpp = Output(UInt(2.W)) 262 val hpp = Output(UInt(2.W)) 263 val spp = Output(UInt(1.W)) 264 val pie = new Priv 265 val ie = new Priv 266 assert(this.getWidth == XLEN) 267 } 268 269 class Interrupt extends Bundle { 270// val d = Output(Bool()) // Debug 271 val e = new Priv 272 val t = new Priv 273 val s = new Priv 274 } 275 276 // Debug CSRs 277 val dcsr = RegInit(UInt(32.W), 0x4000b010.U) 278 val dpc = Reg(UInt(64.W)) 279 val dscratch = Reg(UInt(64.W)) 280 val dscratch1 = Reg(UInt(64.W)) 281 val debugMode = RegInit(false.B) 282 val debugIntrEnable = RegInit(true.B) 283 csrio.debugMode := debugMode 284 285 val dpcPrev = RegNext(dpc) 286 XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x.", dpc, dpcPrev) 287 288 // dcsr value table 289 // | debugver | 0100 290 // | zero | 10 bits of 0 291 // | ebreakvs | 0 292 // | ebreakvu | 0 293 // | ebreakm | 1 if ebreak enters debug 294 // | zero | 0 295 // | ebreaks | 296 // | ebreaku | 297 // | stepie | 0 disable interrupts in singlestep 298 // | stopcount| stop counter, 0 299 // | stoptime | stop time, 0 300 // | cause | 3 bits read only 301 // | v | 0 302 // | mprven | 1 303 // | nmip | read only 304 // | step | 305 // | prv | 2 bits 306 307 val dcsrData = Wire(new DcsrStruct) 308 dcsrData := dcsr.asTypeOf(new DcsrStruct) 309 val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(2, 0), XLEN)// Dcsr write mask 310 def dcsrUpdateSideEffect(dcsr: UInt): UInt = { 311 val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct)) 312 val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11 313 dcsrNew 314 } 315 csrio.singleStep := dcsrData.step 316 317 // Machine-Level CSRs 318 319 val mtvec = RegInit(UInt(XLEN.W), 0.U) 320 val mcounteren = RegInit(UInt(XLEN.W), 0.U) 321 val mcause = RegInit(UInt(XLEN.W), 0.U) 322 val mtval = RegInit(UInt(XLEN.W), 0.U) 323 val mepc = Reg(UInt(XLEN.W)) 324 325 val mie = RegInit(0.U(XLEN.W)) 326 val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 327 val mipReg = RegInit(0.U(XLEN.W)) 328 val mipFixMask = ZeroExt(GenMask(9) | GenMask(5) | GenMask(1), XLEN) 329 val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 330 331 def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt() 332 def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt() 333 var extList = List('a', 's', 'i', 'u') 334 if (HasMExtension) { extList = extList :+ 'm' } 335 if (HasCExtension) { extList = extList :+ 'c' } 336 if (HasFPU) { extList = extList ++ List('f', 'd') } 337 val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U 338 val misa = RegInit(UInt(XLEN.W), misaInitVal) 339 340 // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 341 // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 342 343 val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 344 val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented 345 val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 346 val mhartid = RegInit(UInt(XLEN.W), csrio.hartId) // the hardware thread running the code 347 val mstatus = RegInit(UInt(XLEN.W), 0.U) 348 349 // mstatus Value Table 350 // | sd | 351 // | pad1 | 352 // | sxl | hardlinked to 10, use 00 to pass xv6 test 353 // | uxl | hardlinked to 00 354 // | pad0 | 355 // | tsr | 356 // | tw | 357 // | tvm | 358 // | mxr | 359 // | sum | 360 // | mprv | 361 // | xs | 00 | 362 // | fs | 00 | 363 // | mpp | 00 | 364 // | hpp | 00 | 365 // | spp | 0 | 366 // | pie | 0000 | pie.h is used as UBE 367 // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 368 369 val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 370 def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 371 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 372 val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 373 mstatusNew 374 } 375 376 val mstatusMask = (~ZeroExt(( 377 GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) | 378 GenMask(37) | // MBE 379 GenMask(36) | // SBE 380 GenMask(6) // UBE 381 ), 64)).asUInt() 382 383 val medeleg = RegInit(UInt(XLEN.W), 0.U) 384 val mideleg = RegInit(UInt(XLEN.W), 0.U) 385 val mscratch = RegInit(UInt(XLEN.W), 0.U) 386 387 // PMP Mapping 388 val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter 389 val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter 390 val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp) 391 val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma) 392 393 // Superviser-Level CSRs 394 395 // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 396 val sstatusWmask = "hc6122".U(XLEN.W) 397 // Sstatus Write Mask 398 // ------------------------------------------------------- 399 // 19 9 5 2 400 // 0 1100 0000 0001 0010 0010 401 // 0 c 0 1 2 2 402 // ------------------------------------------------------- 403 val sstatusRmask = sstatusWmask | "h8000000300018000".U 404 // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 405 val stvec = RegInit(UInt(XLEN.W), 0.U) 406 // val sie = RegInit(0.U(XLEN.W)) 407 val sieMask = "h222".U & mideleg 408 val sipMask = "h222".U & mideleg 409 val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode 410 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 411 // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 412 // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0 413 // TODO: use config to control the length of asid 414 // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0 415 val satpMask = Cat("h8".U(4.W),Asid_true_mask(AsidLength),"hfffffffffff".U((XLEN - 4 - 16).W)) 416 val sepc = RegInit(UInt(XLEN.W), 0.U) 417 val scause = RegInit(UInt(XLEN.W), 0.U) 418 val stval = Reg(UInt(XLEN.W)) 419 val sscratch = RegInit(UInt(XLEN.W), 0.U) 420 val scounteren = RegInit(UInt(XLEN.W), 0.U) 421 422 // sbpctl 423 // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB} 424 val sbpctl = RegInit(UInt(XLEN.W), "h7f".U) 425 csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0) 426 csrio.customCtrl.bp_ctrl.btb_enable := sbpctl(1) 427 csrio.customCtrl.bp_ctrl.bim_enable := sbpctl(2) 428 csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3) 429 csrio.customCtrl.bp_ctrl.sc_enable := sbpctl(4) 430 csrio.customCtrl.bp_ctrl.ras_enable := sbpctl(5) 431 csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6) 432 433 // spfctl Bit 0: L1plusCache Prefetcher Enable 434 // spfctl Bit 1: L2Cache Prefetcher Enable 435 val spfctl = RegInit(UInt(XLEN.W), "h3".U) 436 csrio.customCtrl.l1plus_pf_enable := spfctl(0) 437 csrio.customCtrl.l2_pf_enable := spfctl(1) 438 439 // sdsid: Differentiated Services ID 440 val sdsid = RegInit(UInt(XLEN.W), 0.U) 441 csrio.customCtrl.dsid := sdsid 442 443 // slvpredctl: load violation predict settings 444 val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17 445 csrio.customCtrl.lvpred_disable := slvpredctl(0) 446 csrio.customCtrl.no_spec_load := slvpredctl(1) 447 csrio.customCtrl.storeset_wait_store := slvpredctl(2) 448 csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3) 449 csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4) 450 451 // smblockctl: memory block configurations 452 // bits 0-3: store buffer flush threshold (default: 8 entries) 453 val smblockctl_init_val = 454 ("hf".U & StoreBufferThreshold.U) | 455 (EnableLdVioCheckAfterReset.B.asUInt << 4) 456 val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val) 457 csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0) 458 // bits 4: enable load load violation check 459 csrio.customCtrl.ldld_vio_check := smblockctl(4) 460 461 val srnctl = RegInit(UInt(XLEN.W), "h3".U) 462 csrio.customCtrl.move_elim_enable := srnctl(0) 463 csrio.customCtrl.svinval_enable := srnctl(1) 464 465 val tlbBundle = Wire(new TlbCsrBundle) 466 tlbBundle.satp.apply(satp) 467 468 csrio.tlb := tlbBundle 469 470 // User-Level CSRs 471 val uepc = Reg(UInt(XLEN.W)) 472 473 // fcsr 474 class FcsrStruct extends Bundle { 475 val reserved = UInt((XLEN-3-5).W) 476 val frm = UInt(3.W) 477 val fflags = UInt(5.W) 478 assert(this.getWidth == XLEN) 479 } 480 val fcsr = RegInit(0.U(XLEN.W)) 481 // set mstatus->sd and mstatus->fs when true 482 val csrw_dirty_fp_state = WireInit(false.B) 483 484 def frm_wfn(wdata: UInt): UInt = { 485 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 486 csrw_dirty_fp_state := true.B 487 fcsrOld.frm := wdata(2,0) 488 fcsrOld.asUInt() 489 } 490 def frm_rfn(rdata: UInt): UInt = rdata(7,5) 491 492 def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 493 val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 494 val fcsrNew = WireInit(fcsrOld) 495 csrw_dirty_fp_state := true.B 496 if (update) { 497 fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 498 } else { 499 fcsrNew.fflags := wdata(4,0) 500 } 501 fcsrNew.asUInt() 502 } 503 def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 504 505 def fcsr_wfn(wdata: UInt): UInt = { 506 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 507 csrw_dirty_fp_state := true.B 508 Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 509 } 510 511 val fcsrMapping = Map( 512 MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 513 MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 514 MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 515 ) 516 517 // Hart Priviledge Mode 518 val priviledgeMode = RegInit(UInt(2.W), ModeM) 519 520 // Emu perfcnt 521 val hasEmuPerfCnt = !env.FPGAPlatform 522 val nrEmuPerfCnts = if (hasEmuPerfCnt) 0x80 else 0x3 523 524 val emuPerfCnts = List.fill(nrEmuPerfCnts)(RegInit(0.U(XLEN.W))) 525 val emuPerfCntCond = List.fill(nrEmuPerfCnts)(WireInit(false.B)) 526 (emuPerfCnts zip emuPerfCntCond).map { case (c, e) => when (e) { c := c + 1.U } } 527 528 val emuPerfCntsLoMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1000 + i, emuPerfCnts(i))) 529 val emuPerfCntsHiMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1080 + i, emuPerfCnts(i)(63, 32))) 530 println(s"CSR: hasEmuPerfCnt:${hasEmuPerfCnt}") 531 532 //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool()))) 533 // Perf Counter 534 val nrPerfCnts = 29 // 3...31 535 val priviledgeModeOH = UIntToOH(priviledgeMode) 536 val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool()))) 537 val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 538 val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 539 for (i <-0 until nrPerfCnts) { 540 perfEventscounten(i) := (Cat(perfEvents(i)(62),perfEvents(i)(61),(perfEvents(i)(61,60))) & priviledgeModeOH).orR 541 } 542 543 val hpmEvents = Wire(new PerfEventsBundle(numPCntHc * coreParams.L2NBanks)) 544 val pfevent = Module(new PFEvent) 545 pfevent.io.distribute_csr := csrio.customCtrl.distribute_csr 546 for(i <- 0 until numPCntHc * coreParams.L2NBanks) { 547 hpmEvents.perf_events(i).incr_step := csrio.perf.perfEventsHc(i) 548 } 549 550 val hpm_hc = Module(new HPerfmonitor(numPCntHc * coreParams.L2NBanks,numCSRPCntHc)) 551 val csrevents = pfevent.io.hpmevent.slice(24,29) 552 hpm_hc.io.hpm_event := csrevents 553 hpm_hc.io.events_sets := hpmEvents 554 val mcountinhibit = RegInit(0.U(XLEN.W)) 555 val mcycle = RegInit(0.U(XLEN.W)) 556 mcycle := mcycle + 1.U 557 val minstret = RegInit(0.U(XLEN.W)) 558 minstret := minstret + RegNext(csrio.perf.retiredInstr) 559 perfCnts( 0) := Mux((mcountinhibit( 3) | perfEventscounten( 0)),perfCnts( 0) , (perfCnts( 0) + RegNext(csrio.perf.perfEventsFrontend.perf_events(0 ).incr_step))) 560 perfCnts( 1) := Mux((mcountinhibit( 4) | perfEventscounten( 1)),perfCnts( 1) , (perfCnts( 1) + RegNext(csrio.perf.perfEventsFrontend.perf_events(1 ).incr_step))) 561 perfCnts( 2) := Mux((mcountinhibit( 5) | perfEventscounten( 2)),perfCnts( 2) , (perfCnts( 2) + RegNext(csrio.perf.perfEventsFrontend.perf_events(2 ).incr_step))) 562 perfCnts( 3) := Mux((mcountinhibit( 6) | perfEventscounten( 3)),perfCnts( 3) , (perfCnts( 3) + RegNext(csrio.perf.perfEventsFrontend.perf_events(3 ).incr_step))) 563 perfCnts( 4) := Mux((mcountinhibit( 7) | perfEventscounten( 4)),perfCnts( 4) , (perfCnts( 4) + RegNext(csrio.perf.perfEventsFrontend.perf_events(4 ).incr_step))) 564 perfCnts( 5) := Mux((mcountinhibit( 8) | perfEventscounten( 5)),perfCnts( 5) , (perfCnts( 5) + RegNext(csrio.perf.perfEventsFrontend.perf_events(5 ).incr_step))) 565 perfCnts( 6) := Mux((mcountinhibit( 9) | perfEventscounten( 6)),perfCnts( 6) , (perfCnts( 6) + RegNext(csrio.perf.perfEventsFrontend.perf_events(6 ).incr_step))) 566 perfCnts( 7) := Mux((mcountinhibit(10) | perfEventscounten( 7)),perfCnts( 7) , (perfCnts( 7) + RegNext(csrio.perf.perfEventsFrontend.perf_events(7 ).incr_step))) 567 perfCnts( 8) := Mux((mcountinhibit(11) | perfEventscounten( 8)),perfCnts( 8) , (perfCnts( 8) + RegNext(csrio.perf.perfEventsCtrl.perf_events(0 ).incr_step))) 568 perfCnts( 9) := Mux((mcountinhibit(12) | perfEventscounten( 9)),perfCnts( 9) , (perfCnts( 9) + RegNext(csrio.perf.perfEventsCtrl.perf_events(1 ).incr_step))) 569 perfCnts(10) := Mux((mcountinhibit(13) | perfEventscounten(10)),perfCnts(10) , (perfCnts(10) + RegNext(csrio.perf.perfEventsCtrl.perf_events(2 ).incr_step))) 570 perfCnts(11) := Mux((mcountinhibit(14) | perfEventscounten(11)),perfCnts(11) , (perfCnts(11) + RegNext(csrio.perf.perfEventsCtrl.perf_events(3 ).incr_step))) 571 perfCnts(12) := Mux((mcountinhibit(15) | perfEventscounten(12)),perfCnts(12) , (perfCnts(12) + RegNext(csrio.perf.perfEventsCtrl.perf_events(4 ).incr_step))) 572 perfCnts(13) := Mux((mcountinhibit(16) | perfEventscounten(13)),perfCnts(13) , (perfCnts(13) + RegNext(csrio.perf.perfEventsCtrl.perf_events(5 ).incr_step))) 573 perfCnts(14) := Mux((mcountinhibit(17) | perfEventscounten(14)),perfCnts(14) , (perfCnts(14) + RegNext(csrio.perf.perfEventsCtrl.perf_events(6 ).incr_step))) 574 perfCnts(15) := Mux((mcountinhibit(18) | perfEventscounten(15)),perfCnts(15) , (perfCnts(15) + RegNext(csrio.perf.perfEventsCtrl.perf_events(7 ).incr_step))) 575 perfCnts(16) := Mux((mcountinhibit(19) | perfEventscounten(16)),perfCnts(16) , (perfCnts(16) + RegNext(csrio.perf.perfEventsLsu.perf_events(0 ).incr_step))) 576 perfCnts(17) := Mux((mcountinhibit(20) | perfEventscounten(17)),perfCnts(17) , (perfCnts(17) + RegNext(csrio.perf.perfEventsLsu.perf_events(1 ).incr_step))) 577 perfCnts(18) := Mux((mcountinhibit(21) | perfEventscounten(18)),perfCnts(18) , (perfCnts(18) + RegNext(csrio.perf.perfEventsLsu.perf_events(2 ).incr_step))) 578 perfCnts(19) := Mux((mcountinhibit(22) | perfEventscounten(19)),perfCnts(19) , (perfCnts(19) + RegNext(csrio.perf.perfEventsLsu.perf_events(3 ).incr_step))) 579 perfCnts(20) := Mux((mcountinhibit(23) | perfEventscounten(20)),perfCnts(20) , (perfCnts(20) + RegNext(csrio.perf.perfEventsLsu.perf_events(4 ).incr_step))) 580 perfCnts(21) := Mux((mcountinhibit(24) | perfEventscounten(21)),perfCnts(21) , (perfCnts(21) + RegNext(csrio.perf.perfEventsLsu.perf_events(5 ).incr_step))) 581 perfCnts(22) := Mux((mcountinhibit(25) | perfEventscounten(22)),perfCnts(22) , (perfCnts(22) + RegNext(csrio.perf.perfEventsLsu.perf_events(6 ).incr_step))) 582 perfCnts(23) := Mux((mcountinhibit(26) | perfEventscounten(23)),perfCnts(23) , (perfCnts(23) + RegNext(csrio.perf.perfEventsLsu.perf_events(7 ).incr_step))) 583 perfCnts(24) := Mux((mcountinhibit(27) | perfEventscounten(24)),perfCnts(24) , (perfCnts(24) + RegNext(hpm_hc.io.events_selected.perf_events(0 ).incr_step))) 584 perfCnts(25) := Mux((mcountinhibit(28) | perfEventscounten(25)),perfCnts(25) , (perfCnts(25) + RegNext(hpm_hc.io.events_selected.perf_events(1 ).incr_step))) 585 perfCnts(26) := Mux((mcountinhibit(29) | perfEventscounten(26)),perfCnts(26) , (perfCnts(26) + RegNext(hpm_hc.io.events_selected.perf_events(2 ).incr_step))) 586 perfCnts(27) := Mux((mcountinhibit(30) | perfEventscounten(27)),perfCnts(27) , (perfCnts(27) + RegNext(hpm_hc.io.events_selected.perf_events(3 ).incr_step))) 587 perfCnts(28) := Mux((mcountinhibit(31) | perfEventscounten(28)),perfCnts(28) , (perfCnts(28) + RegNext(hpm_hc.io.events_selected.perf_events(4 ).incr_step))) 588 589 // CSR reg map 590 val basicPrivMapping = Map( 591 592 //--- User Trap Setup --- 593 // MaskedRegMap(Ustatus, ustatus), 594 // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 595 // MaskedRegMap(Utvec, utvec), 596 597 //--- User Trap Handling --- 598 // MaskedRegMap(Uscratch, uscratch), 599 // MaskedRegMap(Uepc, uepc), 600 // MaskedRegMap(Ucause, ucause), 601 // MaskedRegMap(Utval, utval), 602 // MaskedRegMap(Uip, uip), 603 604 //--- User Counter/Timers --- 605 // MaskedRegMap(Cycle, cycle), 606 // MaskedRegMap(Time, time), 607 // MaskedRegMap(Instret, instret), 608 609 //--- Supervisor Trap Setup --- 610 MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 611 // MaskedRegMap(Sedeleg, Sedeleg), 612 // MaskedRegMap(Sideleg, Sideleg), 613 MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 614 MaskedRegMap(Stvec, stvec), 615 MaskedRegMap(Scounteren, scounteren), 616 617 //--- Supervisor Trap Handling --- 618 MaskedRegMap(Sscratch, sscratch), 619 MaskedRegMap(Sepc, sepc), 620 MaskedRegMap(Scause, scause), 621 MaskedRegMap(Stval, stval), 622 MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask), 623 624 //--- Supervisor Protection and Translation --- 625 MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 626 627 //--- Supervisor Custom Read/Write Registers 628 MaskedRegMap(Sbpctl, sbpctl), 629 MaskedRegMap(Spfctl, spfctl), 630 MaskedRegMap(Sdsid, sdsid), 631 MaskedRegMap(Slvpredctl, slvpredctl), 632 MaskedRegMap(Smblockctl, smblockctl), 633 MaskedRegMap(Srnctl, srnctl), 634 635 //--- Machine Information Registers --- 636 MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 637 MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 638 MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 639 MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 640 641 //--- Machine Trap Setup --- 642 MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask), 643 MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 644 MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)), 645 MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)), 646 MaskedRegMap(Mie, mie), 647 MaskedRegMap(Mtvec, mtvec), 648 MaskedRegMap(Mcounteren, mcounteren), 649 650 //--- Machine Trap Handling --- 651 MaskedRegMap(Mscratch, mscratch), 652 MaskedRegMap(Mepc, mepc), 653 MaskedRegMap(Mcause, mcause), 654 MaskedRegMap(Mtval, mtval), 655 MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable), 656 657 //--- Debug Mode --- 658 MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect), 659 MaskedRegMap(Dpc, dpc), 660 MaskedRegMap(Dscratch, dscratch), 661 MaskedRegMap(Dscratch1, dscratch1) 662 ) 663 664 var perfCntMapping = Map( 665 MaskedRegMap(Mcountinhibit, mcountinhibit), 666 MaskedRegMap(Mcycle, mcycle), 667 MaskedRegMap(Minstret, minstret), 668 MaskedRegMap(Mhpmevent3 , perfEvents( 0)), 669 MaskedRegMap(Mhpmevent4 , perfEvents( 1)), 670 MaskedRegMap(Mhpmevent5 , perfEvents( 2)), 671 MaskedRegMap(Mhpmevent6 , perfEvents( 3)), 672 MaskedRegMap(Mhpmevent7 , perfEvents( 4)), 673 MaskedRegMap(Mhpmevent8 , perfEvents( 5)), 674 MaskedRegMap(Mhpmevent9 , perfEvents( 6)), 675 MaskedRegMap(Mhpmevent10, perfEvents( 7)), 676 MaskedRegMap(Mhpmevent11, perfEvents( 8)), 677 MaskedRegMap(Mhpmevent12, perfEvents( 9)), 678 MaskedRegMap(Mhpmevent13, perfEvents(10)), 679 MaskedRegMap(Mhpmevent14, perfEvents(11)), 680 MaskedRegMap(Mhpmevent15, perfEvents(12)), 681 MaskedRegMap(Mhpmevent16, perfEvents(13)), 682 MaskedRegMap(Mhpmevent17, perfEvents(14)), 683 MaskedRegMap(Mhpmevent18, perfEvents(15)), 684 MaskedRegMap(Mhpmevent19, perfEvents(16)), 685 MaskedRegMap(Mhpmevent20, perfEvents(17)), 686 MaskedRegMap(Mhpmevent21, perfEvents(18)), 687 MaskedRegMap(Mhpmevent22, perfEvents(19)), 688 MaskedRegMap(Mhpmevent23, perfEvents(20)), 689 MaskedRegMap(Mhpmevent24, perfEvents(21)), 690 MaskedRegMap(Mhpmevent25, perfEvents(22)), 691 MaskedRegMap(Mhpmevent26, perfEvents(23)), 692 MaskedRegMap(Mhpmevent27, perfEvents(24)), 693 MaskedRegMap(Mhpmevent28, perfEvents(25)), 694 MaskedRegMap(Mhpmevent29, perfEvents(26)), 695 MaskedRegMap(Mhpmevent30, perfEvents(27)), 696 MaskedRegMap(Mhpmevent31, perfEvents(28)), 697 MaskedRegMap(Mhpmcounter3 , perfCnts( 0)), 698 MaskedRegMap(Mhpmcounter4 , perfCnts( 1)), 699 MaskedRegMap(Mhpmcounter5 , perfCnts( 2)), 700 MaskedRegMap(Mhpmcounter6 , perfCnts( 3)), 701 MaskedRegMap(Mhpmcounter7 , perfCnts( 4)), 702 MaskedRegMap(Mhpmcounter8 , perfCnts( 5)), 703 MaskedRegMap(Mhpmcounter9 , perfCnts( 6)), 704 MaskedRegMap(Mhpmcounter10, perfCnts( 7)), 705 MaskedRegMap(Mhpmcounter11, perfCnts( 8)), 706 MaskedRegMap(Mhpmcounter12, perfCnts( 9)), 707 MaskedRegMap(Mhpmcounter13, perfCnts(10)), 708 MaskedRegMap(Mhpmcounter14, perfCnts(11)), 709 MaskedRegMap(Mhpmcounter15, perfCnts(12)), 710 MaskedRegMap(Mhpmcounter16, perfCnts(13)), 711 MaskedRegMap(Mhpmcounter17, perfCnts(14)), 712 MaskedRegMap(Mhpmcounter18, perfCnts(15)), 713 MaskedRegMap(Mhpmcounter19, perfCnts(16)), 714 MaskedRegMap(Mhpmcounter20, perfCnts(17)), 715 MaskedRegMap(Mhpmcounter21, perfCnts(18)), 716 MaskedRegMap(Mhpmcounter22, perfCnts(19)), 717 MaskedRegMap(Mhpmcounter23, perfCnts(20)), 718 MaskedRegMap(Mhpmcounter24, perfCnts(21)), 719 MaskedRegMap(Mhpmcounter25, perfCnts(22)), 720 MaskedRegMap(Mhpmcounter26, perfCnts(23)), 721 MaskedRegMap(Mhpmcounter27, perfCnts(24)), 722 MaskedRegMap(Mhpmcounter28, perfCnts(25)), 723 MaskedRegMap(Mhpmcounter29, perfCnts(26)), 724 MaskedRegMap(Mhpmcounter30, perfCnts(27)), 725 MaskedRegMap(Mhpmcounter31, perfCnts(28)), 726 ) 727 // TODO: mechanism should be implemented later 728 // val MhpmcounterStart = Mhpmcounter3 729 // val MhpmeventStart = Mhpmevent3 730 // for (i <- 0 until nrPerfCnts) { 731 // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 732 // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 733 // } 734 735 val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 736 name -> RegInit(0.U(attribute("width").toInt.W)) 737 }} 738 val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 739 MaskedRegMap( 740 Scachebase + attribute("offset").toInt, 741 cacheopRegs(name) 742 ) 743 }} 744 745 val mapping = basicPrivMapping ++ 746 perfCntMapping ++ 747 pmpMapping ++ 748 pmaMapping ++ 749 emuPerfCntsLoMapping ++ 750 (if (XLEN == 32) emuPerfCntsHiMapping else Nil) ++ 751 (if (HasFPU) fcsrMapping else Nil) ++ 752 (if (HasCustomCSRCacheOp) cacheopMapping else Nil) 753 754 val addr = src2(11, 0) 755 val csri = ZeroExt(src2(16, 12), XLEN) 756 val rdata = Wire(UInt(XLEN.W)) 757 val wdata = LookupTree(func, List( 758 CSROpType.wrt -> src1, 759 CSROpType.set -> (rdata | src1), 760 CSROpType.clr -> (rdata & (~src1).asUInt()), 761 CSROpType.wrti -> csri, 762 CSROpType.seti -> (rdata | csri), 763 CSROpType.clri -> (rdata & (~csri).asUInt()) 764 )) 765 766 val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) 767 csrio.isPerfCnt := addrInPerfCnt 768 769 // satp wen check 770 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 771 772 // csr access check, special case 773 val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool) 774 val accessPermitted = !(addr === Satp.U && tvmNotPermit) 775 csrio.disableSfence := tvmNotPermit 776 777 // general CSR wen check 778 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 779 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 780 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 781 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted 782 783 // Writeable check is ingored. 784 // Currently, write to illegal csr addr will be ignored 785 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 786 io.out.bits.data := rdata 787 io.out.bits.uop := io.in.bits.uop 788 io.out.bits.uop.cf := cfOut 789 io.out.bits.uop.ctrl.flushPipe := flushPipe 790 791 // send distribute csr a w signal 792 csrio.customCtrl.distribute_csr.w.valid := wen && permitted 793 csrio.customCtrl.distribute_csr.w.bits.data := wdata 794 csrio.customCtrl.distribute_csr.w.bits.addr := addr 795 796 // Fix Mip/Sip write 797 val fixMapping = Map( 798 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 799 MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask) 800 ) 801 val rdataFix = Wire(UInt(XLEN.W)) 802 val wdataFix = LookupTree(func, List( 803 CSROpType.wrt -> src1, 804 CSROpType.set -> (rdataFix | src1), 805 CSROpType.clr -> (rdataFix & (~src1).asUInt()), 806 CSROpType.wrti -> csri, 807 CSROpType.seti -> (rdataFix | csri), 808 CSROpType.clri -> (rdataFix & (~csri).asUInt()) 809 )) 810 MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix) 811 812 when (csrio.fpu.fflags.valid) { 813 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 814 } 815 // set fs and sd in mstatus 816 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 817 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 818 mstatusNew.fs := "b11".U 819 mstatusNew.sd := true.B 820 mstatus := mstatusNew.asUInt() 821 } 822 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 823 824 // CSR inst decode 825 val isEbreak = addr === privEbreak && func === CSROpType.jmp 826 val isEcall = addr === privEcall && func === CSROpType.jmp 827 val isMret = addr === privMret && func === CSROpType.jmp 828 val isSret = addr === privSret && func === CSROpType.jmp 829 val isUret = addr === privUret && func === CSROpType.jmp 830 val isDret = addr === privDret && func === CSROpType.jmp 831 832 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 833 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 834 835 // Illegal priviledged operation list 836 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 837 838 // Illegal priviledged instruction check 839 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 840 val isIllegalAccess = !permitted 841 val isIllegalPrivOp = illegalSModeSret 842 843 // expose several csr bits for tlb 844 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 845 tlbBundle.priv.sum := mstatusStruct.sum.asBool 846 tlbBundle.priv.imode := priviledgeMode 847 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 848 849 // Branch control 850 val retTarget = Wire(UInt(VAddrBits.W)) 851 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 852 flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall) 853 854 retTarget := DontCare 855 // val illegalEret = TODO 856 857 when (valid && isDret) { 858 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 859 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 860 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 861 val debugModeNew = WireInit(debugMode) 862 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. 863 mstatus := mstatusNew.asUInt 864 priviledgeMode := dcsrNew.prv 865 retTarget := dpc(VAddrBits-1, 0) 866 debugModeNew := false.B 867 debugIntrEnable := true.B 868 debugMode := debugModeNew 869 XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 870 } 871 872 when (valid && isMret) { 873 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 874 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 875 mstatusNew.ie.m := mstatusOld.pie.m 876 priviledgeMode := mstatusOld.mpp 877 mstatusNew.pie.m := true.B 878 mstatusNew.mpp := ModeU 879 when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U } 880 mstatus := mstatusNew.asUInt 881 // lr := false.B 882 retTarget := mepc(VAddrBits-1, 0) 883 } 884 885 when (valid && isSret && !illegalSModeSret) { 886 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 887 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 888 mstatusNew.ie.s := mstatusOld.pie.s 889 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 890 mstatusNew.pie.s := true.B 891 mstatusNew.spp := ModeU 892 mstatus := mstatusNew.asUInt 893 mstatusNew.mprv := 0.U 894 // lr := false.B 895 retTarget := sepc(VAddrBits-1, 0) 896 } 897 898 when (valid && isUret) { 899 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 900 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 901 // mstatusNew.mpp.m := ModeU //TODO: add mode U 902 mstatusNew.ie.u := mstatusOld.pie.u 903 priviledgeMode := ModeU 904 mstatusNew.pie.u := true.B 905 mstatus := mstatusNew.asUInt 906 retTarget := uepc(VAddrBits-1, 0) 907 } 908 909 io.in.ready := true.B 910 io.out.valid := valid 911 912 val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku) 913 914 val csrExceptionVec = WireInit(cfIn.exceptionVec) 915 csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException 916 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 917 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 918 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 919 // Trigger an illegal instr exception when: 920 // * unimplemented csr is being read/written 921 // * csr access is illegal 922 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 923 cfOut.exceptionVec := csrExceptionVec 924 925 /** 926 * Exception and Intr 927 */ 928 val ideleg = (mideleg & mip.asUInt) 929 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 930 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 931 932 val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 933 XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 934 // send interrupt information to ROB 935 val intrVecEnable = Wire(Vec(12, Bool())) 936 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 937 val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 938 val intrBitSet = intrVec.orR() 939 csrio.interrupt := intrBitSet 940 mipWire.t.m := csrio.externalInterrupt.mtip 941 mipWire.s.m := csrio.externalInterrupt.msip 942 mipWire.e.m := csrio.externalInterrupt.meip 943 mipWire.e.s := csrio.externalInterrupt.meip 944 945 // interrupts 946 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 947 val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 948 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO) 949 val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr 950 951 // exceptions 952 val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 953 val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 954 val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 955 val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 956 val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 957 val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 958 val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 959 val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 960 val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 961 val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException 962 val hasSingleStep = csrio.exception.bits.uop.cf.exceptionVec(singleStep) && raiseException 963 964 val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 965 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 966 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 967 968 val raiseExceptionIntr = csrio.exception.valid 969 970 val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep 971 val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ??? 972 973 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 974 csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 975 ) 976 XSDebug(raiseExceptionIntr, 977 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 978 csrio.exception.bits.uop.cf.pc, 979 mstatus, 980 mideleg, 981 medeleg, 982 priviledgeMode 983 ) 984 985 // mtval write logic 986 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 987 when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) { 988 val tval = Mux( 989 hasInstrPageFault, 990 Mux( 991 csrio.exception.bits.uop.cf.crossPageIPFFix, 992 SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 993 SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 994 ), 995 memExceptionAddr 996 ) 997 when (priviledgeMode === ModeM) { 998 mtval := tval 999 }.otherwise { 1000 stval := tval 1001 } 1002 } 1003 1004 when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) { 1005 mtval := memExceptionAddr 1006 } 1007 1008 val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 1009 val deleg = Mux(raiseIntr, mideleg , medeleg) 1010 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 1011 val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 1012 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 1013 val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak 1014 1015 // ctrl block will use theses later for flush 1016 val isXRetFlag = RegInit(false.B) 1017 val retTargetReg = Reg(retTarget.cloneType) 1018 when (io.redirectIn.valid) { 1019 isXRetFlag := false.B 1020 }.elsewhen (isXRet) { 1021 isXRetFlag := true.B 1022 retTargetReg := retTarget 1023 } 1024 csrio.isXRet := isXRetFlag 1025 csrio.trapTarget := Mux(isXRetFlag, 1026 retTargetReg, 1027 Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget, 1028 Mux(delegS, stvec, mtvec))(VAddrBits-1, 0) 1029 ) 1030 1031 when (raiseExceptionIntr) { 1032 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1033 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1034 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1035 val debugModeNew = WireInit(debugMode) 1036 1037 when (raiseDebugExceptionIntr) { 1038 when (raiseDebugIntr) { 1039 debugModeNew := true.B 1040 mstatusNew.mprv := false.B 1041 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1042 dcsrNew.cause := 1.U 1043 dcsrNew.prv := priviledgeMode 1044 priviledgeMode := ModeM 1045 XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 1046 }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) { 1047 // ebreak or ss in running hart 1048 debugModeNew := true.B 1049 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1050 dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U) 1051 dcsrNew.prv := priviledgeMode // TODO 1052 priviledgeMode := ModeM 1053 mstatusNew.mprv := false.B 1054 } 1055 dcsr := dcsrNew.asUInt 1056 debugIntrEnable := false.B 1057 }.elsewhen (delegS) { 1058 scause := causeNO 1059 sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1060 mstatusNew.spp := priviledgeMode 1061 mstatusNew.pie.s := mstatusOld.ie.s 1062 mstatusNew.ie.s := false.B 1063 priviledgeMode := ModeS 1064 when (tvalWen) { stval := 0.U } 1065 }.otherwise { 1066 mcause := causeNO 1067 mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1068 mstatusNew.mpp := priviledgeMode 1069 mstatusNew.pie.m := mstatusOld.ie.m 1070 mstatusNew.ie.m := false.B 1071 priviledgeMode := ModeM 1072 when (tvalWen) { mtval := 0.U } 1073 } 1074 mstatus := mstatusNew.asUInt 1075 debugMode := debugModeNew 1076 } 1077 1078 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 1079 1080 // Distributed CSR update req 1081 // 1082 // For now we use it to implement customized cache op 1083 1084 when(csrio.distributedUpdate.w.valid){ 1085 // cacheopRegs can be distributed updated 1086 CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 1087 when((Scachebase + attribute("offset").toInt).U === csrio.distributedUpdate.w.bits.addr){ 1088 cacheopRegs(name) := csrio.distributedUpdate.w.bits.data 1089 } 1090 }} 1091 } 1092 1093 def readWithScala(addr: Int): UInt = mapping(addr)._1 1094 1095 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 1096 1097 if (!env.FPGAPlatform) { 1098 val difftest = Module(new DifftestArchEvent) 1099 difftest.io.clock := clock 1100 difftest.io.coreid := hardId.U 1101 difftest.io.intrNO := RegNext(difftestIntrNO) 1102 difftest.io.cause := RegNext(Mux(csrio.exception.valid, causeNO, 0.U)) 1103 difftest.io.exceptionPC := RegNext(SignExt(csrio.exception.bits.uop.cf.pc, XLEN)) 1104 } 1105 1106 if (!env.FPGAPlatform) { 1107 val difftest = Module(new DifftestCSRState) 1108 difftest.io.clock := clock 1109 difftest.io.coreid := hardId.U 1110 difftest.io.priviledgeMode := priviledgeMode 1111 difftest.io.mstatus := mstatus 1112 difftest.io.sstatus := mstatus & sstatusRmask 1113 difftest.io.mepc := mepc 1114 difftest.io.sepc := sepc 1115 difftest.io.mtval:= mtval 1116 difftest.io.stval:= stval 1117 difftest.io.mtvec := mtvec 1118 difftest.io.stvec := stvec 1119 difftest.io.mcause := mcause 1120 difftest.io.scause := scause 1121 difftest.io.satp := satp 1122 difftest.io.mip := mipReg 1123 difftest.io.mie := mie 1124 difftest.io.mscratch := mscratch 1125 difftest.io.sscratch := sscratch 1126 difftest.io.mideleg := mideleg 1127 difftest.io.medeleg := medeleg 1128 } 1129} 1130class PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst { 1131 val io = IO(new Bundle { 1132 val distribute_csr = Flipped(new DistributedCSRIO()) 1133 val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1134 }) 1135 1136 val w = io.distribute_csr.w 1137 1138 //val csrevents = Vec(29,RegInit(UInt(XLEN.W), 0.U)) 1139 val csrevent3 = RegInit(UInt(XLEN.W), 0.U) 1140 val csrevent4 = RegInit(UInt(XLEN.W), 0.U) 1141 val csrevent5 = RegInit(UInt(XLEN.W), 0.U) 1142 val csrevent6 = RegInit(UInt(XLEN.W), 0.U) 1143 val csrevent7 = RegInit(UInt(XLEN.W), 0.U) 1144 val csrevent8 = RegInit(UInt(XLEN.W), 0.U) 1145 val csrevent9 = RegInit(UInt(XLEN.W), 0.U) 1146 val csrevent10 = RegInit(UInt(XLEN.W), 0.U) 1147 val csrevent11 = RegInit(UInt(XLEN.W), 0.U) 1148 val csrevent12 = RegInit(UInt(XLEN.W), 0.U) 1149 val csrevent13 = RegInit(UInt(XLEN.W), 0.U) 1150 val csrevent14 = RegInit(UInt(XLEN.W), 0.U) 1151 val csrevent15 = RegInit(UInt(XLEN.W), 0.U) 1152 val csrevent16 = RegInit(UInt(XLEN.W), 0.U) 1153 val csrevent17 = RegInit(UInt(XLEN.W), 0.U) 1154 val csrevent18 = RegInit(UInt(XLEN.W), 0.U) 1155 val csrevent19 = RegInit(UInt(XLEN.W), 0.U) 1156 val csrevent20 = RegInit(UInt(XLEN.W), 0.U) 1157 val csrevent21 = RegInit(UInt(XLEN.W), 0.U) 1158 val csrevent22 = RegInit(UInt(XLEN.W), 0.U) 1159 val csrevent23 = RegInit(UInt(XLEN.W), 0.U) 1160 val csrevent24 = RegInit(UInt(XLEN.W), 0.U) 1161 val csrevent25 = RegInit(UInt(XLEN.W), 0.U) 1162 val csrevent26 = RegInit(UInt(XLEN.W), 0.U) 1163 val csrevent27 = RegInit(UInt(XLEN.W), 0.U) 1164 val csrevent28 = RegInit(UInt(XLEN.W), 0.U) 1165 val csrevent29 = RegInit(UInt(XLEN.W), 0.U) 1166 val csrevent30 = RegInit(UInt(XLEN.W), 0.U) 1167 val csrevent31 = RegInit(UInt(XLEN.W), 0.U) 1168 1169 var perfEventMapping = Map( 1170 MaskedRegMap(Mhpmevent3, csrevent3 ), 1171 MaskedRegMap(Mhpmevent4, csrevent4 ), 1172 MaskedRegMap(Mhpmevent5, csrevent5 ), 1173 MaskedRegMap(Mhpmevent6, csrevent6 ), 1174 MaskedRegMap(Mhpmevent7, csrevent7 ), 1175 MaskedRegMap(Mhpmevent8, csrevent8 ), 1176 MaskedRegMap(Mhpmevent9, csrevent9 ), 1177 MaskedRegMap(Mhpmevent10,csrevent10), 1178 MaskedRegMap(Mhpmevent11,csrevent11), 1179 MaskedRegMap(Mhpmevent12,csrevent12), 1180 MaskedRegMap(Mhpmevent13,csrevent13), 1181 MaskedRegMap(Mhpmevent14,csrevent14), 1182 MaskedRegMap(Mhpmevent15,csrevent15), 1183 MaskedRegMap(Mhpmevent16,csrevent16), 1184 MaskedRegMap(Mhpmevent17,csrevent17), 1185 MaskedRegMap(Mhpmevent18,csrevent18), 1186 MaskedRegMap(Mhpmevent19,csrevent19), 1187 MaskedRegMap(Mhpmevent20,csrevent20), 1188 MaskedRegMap(Mhpmevent21,csrevent21), 1189 MaskedRegMap(Mhpmevent22,csrevent22), 1190 MaskedRegMap(Mhpmevent23,csrevent23), 1191 MaskedRegMap(Mhpmevent24,csrevent24), 1192 MaskedRegMap(Mhpmevent25,csrevent25), 1193 MaskedRegMap(Mhpmevent26,csrevent26), 1194 MaskedRegMap(Mhpmevent27,csrevent27), 1195 MaskedRegMap(Mhpmevent28,csrevent28), 1196 MaskedRegMap(Mhpmevent29,csrevent29), 1197 MaskedRegMap(Mhpmevent30,csrevent30), 1198 MaskedRegMap(Mhpmevent31,csrevent31), 1199 ) 1200 1201 val rdata = Wire(UInt(XLEN.W)) 1202 MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 1203 io.hpmevent( 0) := csrevent3 1204 io.hpmevent( 1) := csrevent4 1205 io.hpmevent( 2) := csrevent5 1206 io.hpmevent( 3) := csrevent6 1207 io.hpmevent( 4) := csrevent7 1208 io.hpmevent( 5) := csrevent8 1209 io.hpmevent( 6) := csrevent9 1210 io.hpmevent( 7) := csrevent10 1211 io.hpmevent( 8) := csrevent11 1212 io.hpmevent( 9) := csrevent12 1213 io.hpmevent(10) := csrevent13 1214 io.hpmevent(11) := csrevent14 1215 io.hpmevent(12) := csrevent15 1216 io.hpmevent(13) := csrevent16 1217 io.hpmevent(14) := csrevent17 1218 io.hpmevent(15) := csrevent18 1219 io.hpmevent(16) := csrevent19 1220 io.hpmevent(17) := csrevent20 1221 io.hpmevent(18) := csrevent21 1222 io.hpmevent(19) := csrevent22 1223 io.hpmevent(20) := csrevent23 1224 io.hpmevent(21) := csrevent24 1225 io.hpmevent(22) := csrevent25 1226 io.hpmevent(23) := csrevent26 1227 io.hpmevent(24) := csrevent27 1228 io.hpmevent(25) := csrevent28 1229 io.hpmevent(26) := csrevent29 1230 io.hpmevent(27) := csrevent30 1231 io.hpmevent(28) := csrevent31 1232} 1233 1234