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 //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool()))) 521 // Perf Counter 522 val nrPerfCnts = 29 // 3...31 523 val priviledgeModeOH = UIntToOH(priviledgeMode) 524 val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool()))) 525 val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 526 val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 527 for (i <-0 until nrPerfCnts) { 528 perfEventscounten(i) := (Cat(perfEvents(i)(62),perfEvents(i)(61),(perfEvents(i)(61,60))) & priviledgeModeOH).orR 529 } 530 531 val hpmEvents = Wire(new PerfEventsBundle(numPCntHc * coreParams.L2NBanks)) 532 val pfevent = Module(new PFEvent) 533 pfevent.io.distribute_csr := csrio.customCtrl.distribute_csr 534 for(i <- 0 until numPCntHc * coreParams.L2NBanks) { 535 hpmEvents.perf_events(i).incr_step := csrio.perf.perfEventsHc(i) 536 } 537 538 val hpm_hc = Module(new HPerfmonitor(numPCntHc * coreParams.L2NBanks,numCSRPCntHc)) 539 val csrevents = pfevent.io.hpmevent.slice(24,29) 540 hpm_hc.io.hpm_event := csrevents 541 hpm_hc.io.events_sets := hpmEvents 542 val mcountinhibit = RegInit(0.U(XLEN.W)) 543 val mcycle = RegInit(0.U(XLEN.W)) 544 mcycle := mcycle + 1.U 545 val minstret = RegInit(0.U(XLEN.W)) 546 minstret := minstret + RegNext(csrio.perf.retiredInstr) 547 perfCnts( 0) := Mux((mcountinhibit( 3) | perfEventscounten( 0)),perfCnts( 0) , (perfCnts( 0) + RegNext(csrio.perf.perfEventsFrontend.perf_events(0 ).incr_step))) 548 perfCnts( 1) := Mux((mcountinhibit( 4) | perfEventscounten( 1)),perfCnts( 1) , (perfCnts( 1) + RegNext(csrio.perf.perfEventsFrontend.perf_events(1 ).incr_step))) 549 perfCnts( 2) := Mux((mcountinhibit( 5) | perfEventscounten( 2)),perfCnts( 2) , (perfCnts( 2) + RegNext(csrio.perf.perfEventsFrontend.perf_events(2 ).incr_step))) 550 perfCnts( 3) := Mux((mcountinhibit( 6) | perfEventscounten( 3)),perfCnts( 3) , (perfCnts( 3) + RegNext(csrio.perf.perfEventsFrontend.perf_events(3 ).incr_step))) 551 perfCnts( 4) := Mux((mcountinhibit( 7) | perfEventscounten( 4)),perfCnts( 4) , (perfCnts( 4) + RegNext(csrio.perf.perfEventsFrontend.perf_events(4 ).incr_step))) 552 perfCnts( 5) := Mux((mcountinhibit( 8) | perfEventscounten( 5)),perfCnts( 5) , (perfCnts( 5) + RegNext(csrio.perf.perfEventsFrontend.perf_events(5 ).incr_step))) 553 perfCnts( 6) := Mux((mcountinhibit( 9) | perfEventscounten( 6)),perfCnts( 6) , (perfCnts( 6) + RegNext(csrio.perf.perfEventsFrontend.perf_events(6 ).incr_step))) 554 perfCnts( 7) := Mux((mcountinhibit(10) | perfEventscounten( 7)),perfCnts( 7) , (perfCnts( 7) + RegNext(csrio.perf.perfEventsFrontend.perf_events(7 ).incr_step))) 555 perfCnts( 8) := Mux((mcountinhibit(11) | perfEventscounten( 8)),perfCnts( 8) , (perfCnts( 8) + RegNext(csrio.perf.perfEventsCtrl.perf_events(0 ).incr_step))) 556 perfCnts( 9) := Mux((mcountinhibit(12) | perfEventscounten( 9)),perfCnts( 9) , (perfCnts( 9) + RegNext(csrio.perf.perfEventsCtrl.perf_events(1 ).incr_step))) 557 perfCnts(10) := Mux((mcountinhibit(13) | perfEventscounten(10)),perfCnts(10) , (perfCnts(10) + RegNext(csrio.perf.perfEventsCtrl.perf_events(2 ).incr_step))) 558 perfCnts(11) := Mux((mcountinhibit(14) | perfEventscounten(11)),perfCnts(11) , (perfCnts(11) + RegNext(csrio.perf.perfEventsCtrl.perf_events(3 ).incr_step))) 559 perfCnts(12) := Mux((mcountinhibit(15) | perfEventscounten(12)),perfCnts(12) , (perfCnts(12) + RegNext(csrio.perf.perfEventsCtrl.perf_events(4 ).incr_step))) 560 perfCnts(13) := Mux((mcountinhibit(16) | perfEventscounten(13)),perfCnts(13) , (perfCnts(13) + RegNext(csrio.perf.perfEventsCtrl.perf_events(5 ).incr_step))) 561 perfCnts(14) := Mux((mcountinhibit(17) | perfEventscounten(14)),perfCnts(14) , (perfCnts(14) + RegNext(csrio.perf.perfEventsCtrl.perf_events(6 ).incr_step))) 562 perfCnts(15) := Mux((mcountinhibit(18) | perfEventscounten(15)),perfCnts(15) , (perfCnts(15) + RegNext(csrio.perf.perfEventsCtrl.perf_events(7 ).incr_step))) 563 perfCnts(16) := Mux((mcountinhibit(19) | perfEventscounten(16)),perfCnts(16) , (perfCnts(16) + RegNext(csrio.perf.perfEventsLsu.perf_events(0 ).incr_step))) 564 perfCnts(17) := Mux((mcountinhibit(20) | perfEventscounten(17)),perfCnts(17) , (perfCnts(17) + RegNext(csrio.perf.perfEventsLsu.perf_events(1 ).incr_step))) 565 perfCnts(18) := Mux((mcountinhibit(21) | perfEventscounten(18)),perfCnts(18) , (perfCnts(18) + RegNext(csrio.perf.perfEventsLsu.perf_events(2 ).incr_step))) 566 perfCnts(19) := Mux((mcountinhibit(22) | perfEventscounten(19)),perfCnts(19) , (perfCnts(19) + RegNext(csrio.perf.perfEventsLsu.perf_events(3 ).incr_step))) 567 perfCnts(20) := Mux((mcountinhibit(23) | perfEventscounten(20)),perfCnts(20) , (perfCnts(20) + RegNext(csrio.perf.perfEventsLsu.perf_events(4 ).incr_step))) 568 perfCnts(21) := Mux((mcountinhibit(24) | perfEventscounten(21)),perfCnts(21) , (perfCnts(21) + RegNext(csrio.perf.perfEventsLsu.perf_events(5 ).incr_step))) 569 perfCnts(22) := Mux((mcountinhibit(25) | perfEventscounten(22)),perfCnts(22) , (perfCnts(22) + RegNext(csrio.perf.perfEventsLsu.perf_events(6 ).incr_step))) 570 perfCnts(23) := Mux((mcountinhibit(26) | perfEventscounten(23)),perfCnts(23) , (perfCnts(23) + RegNext(csrio.perf.perfEventsLsu.perf_events(7 ).incr_step))) 571 perfCnts(24) := Mux((mcountinhibit(27) | perfEventscounten(24)),perfCnts(24) , (perfCnts(24) + RegNext(hpm_hc.io.events_selected.perf_events(0 ).incr_step))) 572 perfCnts(25) := Mux((mcountinhibit(28) | perfEventscounten(25)),perfCnts(25) , (perfCnts(25) + RegNext(hpm_hc.io.events_selected.perf_events(1 ).incr_step))) 573 perfCnts(26) := Mux((mcountinhibit(29) | perfEventscounten(26)),perfCnts(26) , (perfCnts(26) + RegNext(hpm_hc.io.events_selected.perf_events(2 ).incr_step))) 574 perfCnts(27) := Mux((mcountinhibit(30) | perfEventscounten(27)),perfCnts(27) , (perfCnts(27) + RegNext(hpm_hc.io.events_selected.perf_events(3 ).incr_step))) 575 perfCnts(28) := Mux((mcountinhibit(31) | perfEventscounten(28)),perfCnts(28) , (perfCnts(28) + RegNext(hpm_hc.io.events_selected.perf_events(4 ).incr_step))) 576 577 // CSR reg map 578 val basicPrivMapping = Map( 579 580 //--- User Trap Setup --- 581 // MaskedRegMap(Ustatus, ustatus), 582 // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 583 // MaskedRegMap(Utvec, utvec), 584 585 //--- User Trap Handling --- 586 // MaskedRegMap(Uscratch, uscratch), 587 // MaskedRegMap(Uepc, uepc), 588 // MaskedRegMap(Ucause, ucause), 589 // MaskedRegMap(Utval, utval), 590 // MaskedRegMap(Uip, uip), 591 592 //--- User Counter/Timers --- 593 // MaskedRegMap(Cycle, cycle), 594 // MaskedRegMap(Time, time), 595 // MaskedRegMap(Instret, instret), 596 597 //--- Supervisor Trap Setup --- 598 MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 599 // MaskedRegMap(Sedeleg, Sedeleg), 600 // MaskedRegMap(Sideleg, Sideleg), 601 MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 602 MaskedRegMap(Stvec, stvec), 603 MaskedRegMap(Scounteren, scounteren), 604 605 //--- Supervisor Trap Handling --- 606 MaskedRegMap(Sscratch, sscratch), 607 MaskedRegMap(Sepc, sepc), 608 MaskedRegMap(Scause, scause), 609 MaskedRegMap(Stval, stval), 610 MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask), 611 612 //--- Supervisor Protection and Translation --- 613 MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 614 615 //--- Supervisor Custom Read/Write Registers 616 MaskedRegMap(Sbpctl, sbpctl), 617 MaskedRegMap(Spfctl, spfctl), 618 MaskedRegMap(Sdsid, sdsid), 619 MaskedRegMap(Slvpredctl, slvpredctl), 620 MaskedRegMap(Smblockctl, smblockctl), 621 MaskedRegMap(Srnctl, srnctl), 622 623 //--- Machine Information Registers --- 624 MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 625 MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 626 MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 627 MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 628 629 //--- Machine Trap Setup --- 630 MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask), 631 MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 632 MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)), 633 MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)), 634 MaskedRegMap(Mie, mie), 635 MaskedRegMap(Mtvec, mtvec), 636 MaskedRegMap(Mcounteren, mcounteren), 637 638 //--- Machine Trap Handling --- 639 MaskedRegMap(Mscratch, mscratch), 640 MaskedRegMap(Mepc, mepc), 641 MaskedRegMap(Mcause, mcause), 642 MaskedRegMap(Mtval, mtval), 643 MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable), 644 645 //--- Debug Mode --- 646 MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect), 647 MaskedRegMap(Dpc, dpc), 648 MaskedRegMap(Dscratch, dscratch), 649 MaskedRegMap(Dscratch1, dscratch1) 650 ) 651 652 var perfCntMapping = Map( 653 MaskedRegMap(Mcountinhibit, mcountinhibit), 654 MaskedRegMap(Mcycle, mcycle), 655 MaskedRegMap(Minstret, minstret), 656 MaskedRegMap(Mhpmevent3 , perfEvents( 0)), 657 MaskedRegMap(Mhpmevent4 , perfEvents( 1)), 658 MaskedRegMap(Mhpmevent5 , perfEvents( 2)), 659 MaskedRegMap(Mhpmevent6 , perfEvents( 3)), 660 MaskedRegMap(Mhpmevent7 , perfEvents( 4)), 661 MaskedRegMap(Mhpmevent8 , perfEvents( 5)), 662 MaskedRegMap(Mhpmevent9 , perfEvents( 6)), 663 MaskedRegMap(Mhpmevent10, perfEvents( 7)), 664 MaskedRegMap(Mhpmevent11, perfEvents( 8)), 665 MaskedRegMap(Mhpmevent12, perfEvents( 9)), 666 MaskedRegMap(Mhpmevent13, perfEvents(10)), 667 MaskedRegMap(Mhpmevent14, perfEvents(11)), 668 MaskedRegMap(Mhpmevent15, perfEvents(12)), 669 MaskedRegMap(Mhpmevent16, perfEvents(13)), 670 MaskedRegMap(Mhpmevent17, perfEvents(14)), 671 MaskedRegMap(Mhpmevent18, perfEvents(15)), 672 MaskedRegMap(Mhpmevent19, perfEvents(16)), 673 MaskedRegMap(Mhpmevent20, perfEvents(17)), 674 MaskedRegMap(Mhpmevent21, perfEvents(18)), 675 MaskedRegMap(Mhpmevent22, perfEvents(19)), 676 MaskedRegMap(Mhpmevent23, perfEvents(20)), 677 MaskedRegMap(Mhpmevent24, perfEvents(21)), 678 MaskedRegMap(Mhpmevent25, perfEvents(22)), 679 MaskedRegMap(Mhpmevent26, perfEvents(23)), 680 MaskedRegMap(Mhpmevent27, perfEvents(24)), 681 MaskedRegMap(Mhpmevent28, perfEvents(25)), 682 MaskedRegMap(Mhpmevent29, perfEvents(26)), 683 MaskedRegMap(Mhpmevent30, perfEvents(27)), 684 MaskedRegMap(Mhpmevent31, perfEvents(28)), 685 MaskedRegMap(Mhpmcounter3 , perfCnts( 0)), 686 MaskedRegMap(Mhpmcounter4 , perfCnts( 1)), 687 MaskedRegMap(Mhpmcounter5 , perfCnts( 2)), 688 MaskedRegMap(Mhpmcounter6 , perfCnts( 3)), 689 MaskedRegMap(Mhpmcounter7 , perfCnts( 4)), 690 MaskedRegMap(Mhpmcounter8 , perfCnts( 5)), 691 MaskedRegMap(Mhpmcounter9 , perfCnts( 6)), 692 MaskedRegMap(Mhpmcounter10, perfCnts( 7)), 693 MaskedRegMap(Mhpmcounter11, perfCnts( 8)), 694 MaskedRegMap(Mhpmcounter12, perfCnts( 9)), 695 MaskedRegMap(Mhpmcounter13, perfCnts(10)), 696 MaskedRegMap(Mhpmcounter14, perfCnts(11)), 697 MaskedRegMap(Mhpmcounter15, perfCnts(12)), 698 MaskedRegMap(Mhpmcounter16, perfCnts(13)), 699 MaskedRegMap(Mhpmcounter17, perfCnts(14)), 700 MaskedRegMap(Mhpmcounter18, perfCnts(15)), 701 MaskedRegMap(Mhpmcounter19, perfCnts(16)), 702 MaskedRegMap(Mhpmcounter20, perfCnts(17)), 703 MaskedRegMap(Mhpmcounter21, perfCnts(18)), 704 MaskedRegMap(Mhpmcounter22, perfCnts(19)), 705 MaskedRegMap(Mhpmcounter23, perfCnts(20)), 706 MaskedRegMap(Mhpmcounter24, perfCnts(21)), 707 MaskedRegMap(Mhpmcounter25, perfCnts(22)), 708 MaskedRegMap(Mhpmcounter26, perfCnts(23)), 709 MaskedRegMap(Mhpmcounter27, perfCnts(24)), 710 MaskedRegMap(Mhpmcounter28, perfCnts(25)), 711 MaskedRegMap(Mhpmcounter29, perfCnts(26)), 712 MaskedRegMap(Mhpmcounter30, perfCnts(27)), 713 MaskedRegMap(Mhpmcounter31, perfCnts(28)), 714 ) 715 // TODO: mechanism should be implemented later 716 // val MhpmcounterStart = Mhpmcounter3 717 // val MhpmeventStart = Mhpmevent3 718 // for (i <- 0 until nrPerfCnts) { 719 // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 720 // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 721 // } 722 723 val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 724 name -> RegInit(0.U(attribute("width").toInt.W)) 725 }} 726 val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 727 MaskedRegMap( 728 Scachebase + attribute("offset").toInt, 729 cacheopRegs(name) 730 ) 731 }} 732 733 val mapping = basicPrivMapping ++ 734 perfCntMapping ++ 735 pmpMapping ++ 736 pmaMapping ++ 737 (if (HasFPU) fcsrMapping else Nil) ++ 738 (if (HasCustomCSRCacheOp) cacheopMapping else Nil) 739 740 val addr = src2(11, 0) 741 val csri = ZeroExt(src2(16, 12), XLEN) 742 val rdata = Wire(UInt(XLEN.W)) 743 val wdata = LookupTree(func, List( 744 CSROpType.wrt -> src1, 745 CSROpType.set -> (rdata | src1), 746 CSROpType.clr -> (rdata & (~src1).asUInt()), 747 CSROpType.wrti -> csri, 748 CSROpType.seti -> (rdata | csri), 749 CSROpType.clri -> (rdata & (~csri).asUInt()) 750 )) 751 752 val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) 753 csrio.isPerfCnt := addrInPerfCnt 754 755 // satp wen check 756 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 757 758 // csr access check, special case 759 val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool) 760 val accessPermitted = !(addr === Satp.U && tvmNotPermit) 761 csrio.disableSfence := tvmNotPermit 762 763 // general CSR wen check 764 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 765 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 766 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 767 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted 768 769 // Writeable check is ingored. 770 // Currently, write to illegal csr addr will be ignored 771 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 772 io.out.bits.data := rdata 773 io.out.bits.uop := io.in.bits.uop 774 io.out.bits.uop.cf := cfOut 775 io.out.bits.uop.ctrl.flushPipe := flushPipe 776 777 // send distribute csr a w signal 778 csrio.customCtrl.distribute_csr.w.valid := wen && permitted 779 csrio.customCtrl.distribute_csr.w.bits.data := wdata 780 csrio.customCtrl.distribute_csr.w.bits.addr := addr 781 782 // Fix Mip/Sip write 783 val fixMapping = Map( 784 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 785 MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask) 786 ) 787 val rdataFix = Wire(UInt(XLEN.W)) 788 val wdataFix = LookupTree(func, List( 789 CSROpType.wrt -> src1, 790 CSROpType.set -> (rdataFix | src1), 791 CSROpType.clr -> (rdataFix & (~src1).asUInt()), 792 CSROpType.wrti -> csri, 793 CSROpType.seti -> (rdataFix | csri), 794 CSROpType.clri -> (rdataFix & (~csri).asUInt()) 795 )) 796 MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix) 797 798 when (csrio.fpu.fflags.valid) { 799 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 800 } 801 // set fs and sd in mstatus 802 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 803 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 804 mstatusNew.fs := "b11".U 805 mstatusNew.sd := true.B 806 mstatus := mstatusNew.asUInt() 807 } 808 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 809 810 // CSR inst decode 811 val isEbreak = addr === privEbreak && func === CSROpType.jmp 812 val isEcall = addr === privEcall && func === CSROpType.jmp 813 val isMret = addr === privMret && func === CSROpType.jmp 814 val isSret = addr === privSret && func === CSROpType.jmp 815 val isUret = addr === privUret && func === CSROpType.jmp 816 val isDret = addr === privDret && func === CSROpType.jmp 817 818 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 819 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 820 821 // Illegal priviledged operation list 822 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 823 824 // Illegal priviledged instruction check 825 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 826 val isIllegalAccess = !permitted 827 val isIllegalPrivOp = illegalSModeSret 828 829 // expose several csr bits for tlb 830 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 831 tlbBundle.priv.sum := mstatusStruct.sum.asBool 832 tlbBundle.priv.imode := priviledgeMode 833 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 834 835 // Branch control 836 val retTarget = Wire(UInt(VAddrBits.W)) 837 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 838 flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall) 839 840 retTarget := DontCare 841 // val illegalEret = TODO 842 843 when (valid && isDret) { 844 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 845 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 846 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 847 val debugModeNew = WireInit(debugMode) 848 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. 849 mstatus := mstatusNew.asUInt 850 priviledgeMode := dcsrNew.prv 851 retTarget := dpc(VAddrBits-1, 0) 852 debugModeNew := false.B 853 debugIntrEnable := true.B 854 debugMode := debugModeNew 855 XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 856 } 857 858 when (valid && isMret) { 859 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 860 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 861 mstatusNew.ie.m := mstatusOld.pie.m 862 priviledgeMode := mstatusOld.mpp 863 mstatusNew.pie.m := true.B 864 mstatusNew.mpp := ModeU 865 when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U } 866 mstatus := mstatusNew.asUInt 867 // lr := false.B 868 retTarget := mepc(VAddrBits-1, 0) 869 } 870 871 when (valid && isSret && !illegalSModeSret) { 872 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 873 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 874 mstatusNew.ie.s := mstatusOld.pie.s 875 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 876 mstatusNew.pie.s := true.B 877 mstatusNew.spp := ModeU 878 mstatus := mstatusNew.asUInt 879 mstatusNew.mprv := 0.U 880 // lr := false.B 881 retTarget := sepc(VAddrBits-1, 0) 882 } 883 884 when (valid && isUret) { 885 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 886 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 887 // mstatusNew.mpp.m := ModeU //TODO: add mode U 888 mstatusNew.ie.u := mstatusOld.pie.u 889 priviledgeMode := ModeU 890 mstatusNew.pie.u := true.B 891 mstatus := mstatusNew.asUInt 892 retTarget := uepc(VAddrBits-1, 0) 893 } 894 895 io.in.ready := true.B 896 io.out.valid := valid 897 898 val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku) 899 900 val csrExceptionVec = WireInit(cfIn.exceptionVec) 901 csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException 902 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 903 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 904 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 905 // Trigger an illegal instr exception when: 906 // * unimplemented csr is being read/written 907 // * csr access is illegal 908 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 909 cfOut.exceptionVec := csrExceptionVec 910 911 /** 912 * Exception and Intr 913 */ 914 val ideleg = (mideleg & mip.asUInt) 915 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 916 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 917 918 val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 919 XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 920 // send interrupt information to ROB 921 val intrVecEnable = Wire(Vec(12, Bool())) 922 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 923 val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 924 val intrBitSet = intrVec.orR() 925 csrio.interrupt := intrBitSet 926 mipWire.t.m := csrio.externalInterrupt.mtip 927 mipWire.s.m := csrio.externalInterrupt.msip 928 mipWire.e.m := csrio.externalInterrupt.meip 929 mipWire.e.s := csrio.externalInterrupt.meip 930 931 // interrupts 932 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 933 val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 934 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO) 935 val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr 936 937 // exceptions 938 val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 939 val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 940 val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 941 val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 942 val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 943 val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 944 val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 945 val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 946 val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 947 val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException 948 val hasSingleStep = csrio.exception.bits.uop.cf.exceptionVec(singleStep) && raiseException 949 950 val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 951 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 952 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 953 954 val raiseExceptionIntr = csrio.exception.valid 955 956 val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep 957 val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ??? 958 959 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 960 csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 961 ) 962 XSDebug(raiseExceptionIntr, 963 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 964 csrio.exception.bits.uop.cf.pc, 965 mstatus, 966 mideleg, 967 medeleg, 968 priviledgeMode 969 ) 970 971 // mtval write logic 972 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 973 when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) { 974 val tval = Mux( 975 hasInstrPageFault, 976 Mux( 977 csrio.exception.bits.uop.cf.crossPageIPFFix, 978 SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 979 SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 980 ), 981 memExceptionAddr 982 ) 983 when (priviledgeMode === ModeM) { 984 mtval := tval 985 }.otherwise { 986 stval := tval 987 } 988 } 989 990 when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) { 991 mtval := memExceptionAddr 992 } 993 994 val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 995 val deleg = Mux(raiseIntr, mideleg , medeleg) 996 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 997 val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 998 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 999 val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak 1000 1001 // ctrl block will use theses later for flush 1002 val isXRetFlag = RegInit(false.B) 1003 val retTargetReg = Reg(retTarget.cloneType) 1004 when (io.redirectIn.valid) { 1005 isXRetFlag := false.B 1006 }.elsewhen (isXRet) { 1007 isXRetFlag := true.B 1008 retTargetReg := retTarget 1009 } 1010 csrio.isXRet := isXRetFlag 1011 csrio.trapTarget := Mux(isXRetFlag, 1012 retTargetReg, 1013 Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget, 1014 Mux(delegS, stvec, mtvec))(VAddrBits-1, 0) 1015 ) 1016 1017 when (raiseExceptionIntr) { 1018 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1019 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1020 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1021 val debugModeNew = WireInit(debugMode) 1022 1023 when (raiseDebugExceptionIntr) { 1024 when (raiseDebugIntr) { 1025 debugModeNew := true.B 1026 mstatusNew.mprv := false.B 1027 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1028 dcsrNew.cause := 1.U 1029 dcsrNew.prv := priviledgeMode 1030 priviledgeMode := ModeM 1031 XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 1032 }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) { 1033 // ebreak or ss in running hart 1034 debugModeNew := true.B 1035 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1036 dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U) 1037 dcsrNew.prv := priviledgeMode // TODO 1038 priviledgeMode := ModeM 1039 mstatusNew.mprv := false.B 1040 } 1041 dcsr := dcsrNew.asUInt 1042 debugIntrEnable := false.B 1043 }.elsewhen (delegS) { 1044 scause := causeNO 1045 sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1046 mstatusNew.spp := priviledgeMode 1047 mstatusNew.pie.s := mstatusOld.ie.s 1048 mstatusNew.ie.s := false.B 1049 priviledgeMode := ModeS 1050 when (tvalWen) { stval := 0.U } 1051 }.otherwise { 1052 mcause := causeNO 1053 mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1054 mstatusNew.mpp := priviledgeMode 1055 mstatusNew.pie.m := mstatusOld.ie.m 1056 mstatusNew.ie.m := false.B 1057 priviledgeMode := ModeM 1058 when (tvalWen) { mtval := 0.U } 1059 } 1060 mstatus := mstatusNew.asUInt 1061 debugMode := debugModeNew 1062 } 1063 1064 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 1065 1066 // Distributed CSR update req 1067 // 1068 // For now we use it to implement customized cache op 1069 1070 when(csrio.distributedUpdate.w.valid){ 1071 // cacheopRegs can be distributed updated 1072 CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 1073 when((Scachebase + attribute("offset").toInt).U === csrio.distributedUpdate.w.bits.addr){ 1074 cacheopRegs(name) := csrio.distributedUpdate.w.bits.data 1075 } 1076 }} 1077 } 1078 1079 def readWithScala(addr: Int): UInt = mapping(addr)._1 1080 1081 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 1082 1083 if (env.EnableDifftest) { 1084 val difftest = Module(new DifftestArchEvent) 1085 difftest.io.clock := clock 1086 difftest.io.coreid := hardId.U 1087 difftest.io.intrNO := RegNext(difftestIntrNO) 1088 difftest.io.cause := RegNext(Mux(csrio.exception.valid, causeNO, 0.U)) 1089 difftest.io.exceptionPC := RegNext(SignExt(csrio.exception.bits.uop.cf.pc, XLEN)) 1090 } 1091 1092 if (env.EnableDifftest) { 1093 val difftest = Module(new DifftestCSRState) 1094 difftest.io.clock := clock 1095 difftest.io.coreid := hardId.U 1096 difftest.io.priviledgeMode := priviledgeMode 1097 difftest.io.mstatus := mstatus 1098 difftest.io.sstatus := mstatus & sstatusRmask 1099 difftest.io.mepc := mepc 1100 difftest.io.sepc := sepc 1101 difftest.io.mtval:= mtval 1102 difftest.io.stval:= stval 1103 difftest.io.mtvec := mtvec 1104 difftest.io.stvec := stvec 1105 difftest.io.mcause := mcause 1106 difftest.io.scause := scause 1107 difftest.io.satp := satp 1108 difftest.io.mip := mipReg 1109 difftest.io.mie := mie 1110 difftest.io.mscratch := mscratch 1111 difftest.io.sscratch := sscratch 1112 difftest.io.mideleg := mideleg 1113 difftest.io.medeleg := medeleg 1114 } 1115} 1116 1117class PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst { 1118 val io = IO(new Bundle { 1119 val distribute_csr = Flipped(new DistributedCSRIO()) 1120 val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1121 }) 1122 1123 val w = io.distribute_csr.w 1124 1125 //val csrevents = Vec(29,RegInit(UInt(XLEN.W), 0.U)) 1126 val csrevent3 = RegInit(UInt(XLEN.W), 0.U) 1127 val csrevent4 = RegInit(UInt(XLEN.W), 0.U) 1128 val csrevent5 = RegInit(UInt(XLEN.W), 0.U) 1129 val csrevent6 = RegInit(UInt(XLEN.W), 0.U) 1130 val csrevent7 = RegInit(UInt(XLEN.W), 0.U) 1131 val csrevent8 = RegInit(UInt(XLEN.W), 0.U) 1132 val csrevent9 = RegInit(UInt(XLEN.W), 0.U) 1133 val csrevent10 = RegInit(UInt(XLEN.W), 0.U) 1134 val csrevent11 = RegInit(UInt(XLEN.W), 0.U) 1135 val csrevent12 = RegInit(UInt(XLEN.W), 0.U) 1136 val csrevent13 = RegInit(UInt(XLEN.W), 0.U) 1137 val csrevent14 = RegInit(UInt(XLEN.W), 0.U) 1138 val csrevent15 = RegInit(UInt(XLEN.W), 0.U) 1139 val csrevent16 = RegInit(UInt(XLEN.W), 0.U) 1140 val csrevent17 = RegInit(UInt(XLEN.W), 0.U) 1141 val csrevent18 = RegInit(UInt(XLEN.W), 0.U) 1142 val csrevent19 = RegInit(UInt(XLEN.W), 0.U) 1143 val csrevent20 = RegInit(UInt(XLEN.W), 0.U) 1144 val csrevent21 = RegInit(UInt(XLEN.W), 0.U) 1145 val csrevent22 = RegInit(UInt(XLEN.W), 0.U) 1146 val csrevent23 = RegInit(UInt(XLEN.W), 0.U) 1147 val csrevent24 = RegInit(UInt(XLEN.W), 0.U) 1148 val csrevent25 = RegInit(UInt(XLEN.W), 0.U) 1149 val csrevent26 = RegInit(UInt(XLEN.W), 0.U) 1150 val csrevent27 = RegInit(UInt(XLEN.W), 0.U) 1151 val csrevent28 = RegInit(UInt(XLEN.W), 0.U) 1152 val csrevent29 = RegInit(UInt(XLEN.W), 0.U) 1153 val csrevent30 = RegInit(UInt(XLEN.W), 0.U) 1154 val csrevent31 = RegInit(UInt(XLEN.W), 0.U) 1155 1156 var perfEventMapping = Map( 1157 MaskedRegMap(Mhpmevent3, csrevent3 ), 1158 MaskedRegMap(Mhpmevent4, csrevent4 ), 1159 MaskedRegMap(Mhpmevent5, csrevent5 ), 1160 MaskedRegMap(Mhpmevent6, csrevent6 ), 1161 MaskedRegMap(Mhpmevent7, csrevent7 ), 1162 MaskedRegMap(Mhpmevent8, csrevent8 ), 1163 MaskedRegMap(Mhpmevent9, csrevent9 ), 1164 MaskedRegMap(Mhpmevent10,csrevent10), 1165 MaskedRegMap(Mhpmevent11,csrevent11), 1166 MaskedRegMap(Mhpmevent12,csrevent12), 1167 MaskedRegMap(Mhpmevent13,csrevent13), 1168 MaskedRegMap(Mhpmevent14,csrevent14), 1169 MaskedRegMap(Mhpmevent15,csrevent15), 1170 MaskedRegMap(Mhpmevent16,csrevent16), 1171 MaskedRegMap(Mhpmevent17,csrevent17), 1172 MaskedRegMap(Mhpmevent18,csrevent18), 1173 MaskedRegMap(Mhpmevent19,csrevent19), 1174 MaskedRegMap(Mhpmevent20,csrevent20), 1175 MaskedRegMap(Mhpmevent21,csrevent21), 1176 MaskedRegMap(Mhpmevent22,csrevent22), 1177 MaskedRegMap(Mhpmevent23,csrevent23), 1178 MaskedRegMap(Mhpmevent24,csrevent24), 1179 MaskedRegMap(Mhpmevent25,csrevent25), 1180 MaskedRegMap(Mhpmevent26,csrevent26), 1181 MaskedRegMap(Mhpmevent27,csrevent27), 1182 MaskedRegMap(Mhpmevent28,csrevent28), 1183 MaskedRegMap(Mhpmevent29,csrevent29), 1184 MaskedRegMap(Mhpmevent30,csrevent30), 1185 MaskedRegMap(Mhpmevent31,csrevent31), 1186 ) 1187 1188 val rdata = Wire(UInt(XLEN.W)) 1189 MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 1190 io.hpmevent( 0) := csrevent3 1191 io.hpmevent( 1) := csrevent4 1192 io.hpmevent( 2) := csrevent5 1193 io.hpmevent( 3) := csrevent6 1194 io.hpmevent( 4) := csrevent7 1195 io.hpmevent( 5) := csrevent8 1196 io.hpmevent( 6) := csrevent9 1197 io.hpmevent( 7) := csrevent10 1198 io.hpmevent( 8) := csrevent11 1199 io.hpmevent( 9) := csrevent12 1200 io.hpmevent(10) := csrevent13 1201 io.hpmevent(11) := csrevent14 1202 io.hpmevent(12) := csrevent15 1203 io.hpmevent(13) := csrevent16 1204 io.hpmevent(14) := csrevent17 1205 io.hpmevent(15) := csrevent18 1206 io.hpmevent(16) := csrevent19 1207 io.hpmevent(17) := csrevent20 1208 io.hpmevent(18) := csrevent21 1209 io.hpmevent(19) := csrevent22 1210 io.hpmevent(20) := csrevent23 1211 io.hpmevent(21) := csrevent24 1212 io.hpmevent(22) := csrevent25 1213 io.hpmevent(23) := csrevent26 1214 io.hpmevent(24) := csrevent27 1215 io.hpmevent(25) := csrevent28 1216 io.hpmevent(26) := csrevent29 1217 io.hpmevent(27) := csrevent30 1218 io.hpmevent(28) := csrevent31 1219} 1220 1221