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 // to Fence to disable sfence 194 val disableSfence = Output(Bool()) 195 // Custom microarchiture ctrl signal 196 val customCtrl = Output(new CustomCSRCtrlIO) 197 // distributed csr write 198 val distributedUpdate = Flipped(new DistributedCSRUpdateReq) 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 (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U) 754 csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp 755 756 // satp wen check 757 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 758 759 // csr access check, special case 760 val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool) 761 val accessPermitted = !(addr === Satp.U && tvmNotPermit) 762 csrio.disableSfence := tvmNotPermit 763 764 // general CSR wen check 765 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 766 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 767 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 768 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted 769 770 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 771 io.out.bits.data := rdata 772 io.out.bits.uop := io.in.bits.uop 773 io.out.bits.uop.cf := cfOut 774 io.out.bits.uop.ctrl.flushPipe := flushPipe 775 776 // send distribute csr a w signal 777 csrio.customCtrl.distribute_csr.w.valid := wen && permitted 778 csrio.customCtrl.distribute_csr.w.bits.data := wdata 779 csrio.customCtrl.distribute_csr.w.bits.addr := addr 780 781 // Fix Mip/Sip write 782 val fixMapping = Map( 783 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 784 MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask) 785 ) 786 val rdataFix = Wire(UInt(XLEN.W)) 787 val wdataFix = LookupTree(func, List( 788 CSROpType.wrt -> src1, 789 CSROpType.set -> (rdataFix | src1), 790 CSROpType.clr -> (rdataFix & (~src1).asUInt()), 791 CSROpType.wrti -> csri, 792 CSROpType.seti -> (rdataFix | csri), 793 CSROpType.clri -> (rdataFix & (~csri).asUInt()) 794 )) 795 MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix) 796 797 when (csrio.fpu.fflags.valid) { 798 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 799 } 800 // set fs and sd in mstatus 801 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 802 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 803 mstatusNew.fs := "b11".U 804 mstatusNew.sd := true.B 805 mstatus := mstatusNew.asUInt() 806 } 807 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 808 809 // CSR inst decode 810 val isEbreak = addr === privEbreak && func === CSROpType.jmp 811 val isEcall = addr === privEcall && func === CSROpType.jmp 812 val isMret = addr === privMret && func === CSROpType.jmp 813 val isSret = addr === privSret && func === CSROpType.jmp 814 val isUret = addr === privUret && func === CSROpType.jmp 815 val isDret = addr === privDret && func === CSROpType.jmp 816 817 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 818 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 819 820 // Illegal priviledged operation list 821 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 822 823 // Illegal priviledged instruction check 824 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 825 val isIllegalAccess = !permitted 826 val isIllegalPrivOp = illegalSModeSret 827 828 // expose several csr bits for tlb 829 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 830 tlbBundle.priv.sum := mstatusStruct.sum.asBool 831 tlbBundle.priv.imode := priviledgeMode 832 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 833 834 // Branch control 835 val retTarget = Wire(UInt(VAddrBits.W)) 836 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 837 flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall) 838 839 retTarget := DontCare 840 // val illegalEret = TODO 841 842 when (valid && isDret) { 843 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 844 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 845 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 846 val debugModeNew = WireInit(debugMode) 847 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. 848 mstatus := mstatusNew.asUInt 849 priviledgeMode := dcsrNew.prv 850 retTarget := dpc(VAddrBits-1, 0) 851 debugModeNew := false.B 852 debugIntrEnable := true.B 853 debugMode := debugModeNew 854 XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 855 } 856 857 when (valid && isMret) { 858 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 859 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 860 mstatusNew.ie.m := mstatusOld.pie.m 861 priviledgeMode := mstatusOld.mpp 862 mstatusNew.pie.m := true.B 863 mstatusNew.mpp := ModeU 864 when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U } 865 mstatus := mstatusNew.asUInt 866 // lr := false.B 867 retTarget := mepc(VAddrBits-1, 0) 868 } 869 870 when (valid && isSret && !illegalSModeSret) { 871 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 872 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 873 mstatusNew.ie.s := mstatusOld.pie.s 874 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 875 mstatusNew.pie.s := true.B 876 mstatusNew.spp := ModeU 877 mstatus := mstatusNew.asUInt 878 mstatusNew.mprv := 0.U 879 // lr := false.B 880 retTarget := sepc(VAddrBits-1, 0) 881 } 882 883 when (valid && isUret) { 884 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 885 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 886 // mstatusNew.mpp.m := ModeU //TODO: add mode U 887 mstatusNew.ie.u := mstatusOld.pie.u 888 priviledgeMode := ModeU 889 mstatusNew.pie.u := true.B 890 mstatus := mstatusNew.asUInt 891 retTarget := uepc(VAddrBits-1, 0) 892 } 893 894 io.in.ready := true.B 895 io.out.valid := valid 896 897 val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku) 898 899 val csrExceptionVec = WireInit(cfIn.exceptionVec) 900 csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException 901 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 902 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 903 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 904 // Trigger an illegal instr exception when: 905 // * unimplemented csr is being read/written 906 // * csr access is illegal 907 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 908 cfOut.exceptionVec := csrExceptionVec 909 910 /** 911 * Exception and Intr 912 */ 913 val ideleg = (mideleg & mip.asUInt) 914 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 915 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 916 917 val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 918 XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 919 // send interrupt information to ROB 920 val intrVecEnable = Wire(Vec(12, Bool())) 921 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 922 val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 923 val intrBitSet = intrVec.orR() 924 csrio.interrupt := intrBitSet 925 mipWire.t.m := csrio.externalInterrupt.mtip 926 mipWire.s.m := csrio.externalInterrupt.msip 927 mipWire.e.m := csrio.externalInterrupt.meip 928 mipWire.e.s := csrio.externalInterrupt.seip 929 930 // interrupts 931 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 932 val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 933 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO) 934 val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr 935 936 // exceptions 937 val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 938 val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 939 val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 940 val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 941 val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 942 val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 943 val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 944 val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 945 val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 946 val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException 947 val hasSingleStep = csrio.exception.bits.uop.cf.exceptionVec(singleStep) && raiseException 948 949 val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 950 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 951 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 952 953 val raiseExceptionIntr = csrio.exception.valid 954 955 val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep 956 val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ??? 957 958 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 959 csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 960 ) 961 XSDebug(raiseExceptionIntr, 962 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 963 csrio.exception.bits.uop.cf.pc, 964 mstatus, 965 mideleg, 966 medeleg, 967 priviledgeMode 968 ) 969 970 // mtval write logic 971 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 972 when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) { 973 val tval = Mux( 974 hasInstrPageFault, 975 Mux( 976 csrio.exception.bits.uop.cf.crossPageIPFFix, 977 SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 978 SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 979 ), 980 memExceptionAddr 981 ) 982 when (priviledgeMode === ModeM) { 983 mtval := tval 984 }.otherwise { 985 stval := tval 986 } 987 } 988 989 when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) { 990 mtval := memExceptionAddr 991 } 992 993 val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 994 val deleg = Mux(raiseIntr, mideleg , medeleg) 995 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 996 val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 997 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 998 val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak 999 1000 // ctrl block will use theses later for flush 1001 val isXRetFlag = RegInit(false.B) 1002 val retTargetReg = Reg(retTarget.cloneType) 1003 when (io.redirectIn.valid) { 1004 isXRetFlag := false.B 1005 }.elsewhen (isXRet) { 1006 isXRetFlag := true.B 1007 retTargetReg := retTarget 1008 } 1009 csrio.isXRet := isXRetFlag 1010 csrio.trapTarget := Mux(isXRetFlag, 1011 retTargetReg, 1012 Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget, 1013 Mux(delegS, stvec, mtvec))(VAddrBits-1, 0) 1014 ) 1015 1016 when (raiseExceptionIntr) { 1017 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1018 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1019 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1020 val debugModeNew = WireInit(debugMode) 1021 1022 when (raiseDebugExceptionIntr) { 1023 when (raiseDebugIntr) { 1024 debugModeNew := true.B 1025 mstatusNew.mprv := false.B 1026 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1027 dcsrNew.cause := 1.U 1028 dcsrNew.prv := priviledgeMode 1029 priviledgeMode := ModeM 1030 XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 1031 }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) { 1032 // ebreak or ss in running hart 1033 debugModeNew := true.B 1034 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1035 dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U) 1036 dcsrNew.prv := priviledgeMode // TODO 1037 priviledgeMode := ModeM 1038 mstatusNew.mprv := false.B 1039 } 1040 dcsr := dcsrNew.asUInt 1041 debugIntrEnable := false.B 1042 }.elsewhen (delegS) { 1043 scause := causeNO 1044 sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1045 mstatusNew.spp := priviledgeMode 1046 mstatusNew.pie.s := mstatusOld.ie.s 1047 mstatusNew.ie.s := false.B 1048 priviledgeMode := ModeS 1049 when (tvalWen) { stval := 0.U } 1050 }.otherwise { 1051 mcause := causeNO 1052 mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1053 mstatusNew.mpp := priviledgeMode 1054 mstatusNew.pie.m := mstatusOld.ie.m 1055 mstatusNew.ie.m := false.B 1056 priviledgeMode := ModeM 1057 when (tvalWen) { mtval := 0.U } 1058 } 1059 mstatus := mstatusNew.asUInt 1060 debugMode := debugModeNew 1061 } 1062 1063 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 1064 1065 // Distributed CSR update req 1066 // 1067 // For now we use it to implement customized cache op 1068 1069 when(csrio.distributedUpdate.w.valid){ 1070 // cacheopRegs can be distributed updated 1071 CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 1072 when((Scachebase + attribute("offset").toInt).U === csrio.distributedUpdate.w.bits.addr){ 1073 cacheopRegs(name) := csrio.distributedUpdate.w.bits.data 1074 } 1075 }} 1076 } 1077 1078 def readWithScala(addr: Int): UInt = mapping(addr)._1 1079 1080 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 1081 1082 // Always instantiate basic difftest modules. 1083 if (env.AlwaysBasicDiff || 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 // Always instantiate basic difftest modules. 1093 if (env.AlwaysBasicDiff || env.EnableDifftest) { 1094 val difftest = Module(new DifftestCSRState) 1095 difftest.io.clock := clock 1096 difftest.io.coreid := hardId.U 1097 difftest.io.priviledgeMode := priviledgeMode 1098 difftest.io.mstatus := mstatus 1099 difftest.io.sstatus := mstatus & sstatusRmask 1100 difftest.io.mepc := mepc 1101 difftest.io.sepc := sepc 1102 difftest.io.mtval:= mtval 1103 difftest.io.stval:= stval 1104 difftest.io.mtvec := mtvec 1105 difftest.io.stvec := stvec 1106 difftest.io.mcause := mcause 1107 difftest.io.scause := scause 1108 difftest.io.satp := satp 1109 difftest.io.mip := mipReg 1110 difftest.io.mie := mie 1111 difftest.io.mscratch := mscratch 1112 difftest.io.sscratch := sscratch 1113 difftest.io.mideleg := mideleg 1114 difftest.io.medeleg := medeleg 1115 } 1116} 1117 1118class PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst { 1119 val io = IO(new Bundle { 1120 val distribute_csr = Flipped(new DistributedCSRIO()) 1121 val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1122 }) 1123 1124 val w = io.distribute_csr.w 1125 1126 //val csrevents = Vec(29,RegInit(UInt(XLEN.W), 0.U)) 1127 val csrevent3 = RegInit(UInt(XLEN.W), 0.U) 1128 val csrevent4 = RegInit(UInt(XLEN.W), 0.U) 1129 val csrevent5 = RegInit(UInt(XLEN.W), 0.U) 1130 val csrevent6 = RegInit(UInt(XLEN.W), 0.U) 1131 val csrevent7 = RegInit(UInt(XLEN.W), 0.U) 1132 val csrevent8 = RegInit(UInt(XLEN.W), 0.U) 1133 val csrevent9 = RegInit(UInt(XLEN.W), 0.U) 1134 val csrevent10 = RegInit(UInt(XLEN.W), 0.U) 1135 val csrevent11 = RegInit(UInt(XLEN.W), 0.U) 1136 val csrevent12 = RegInit(UInt(XLEN.W), 0.U) 1137 val csrevent13 = RegInit(UInt(XLEN.W), 0.U) 1138 val csrevent14 = RegInit(UInt(XLEN.W), 0.U) 1139 val csrevent15 = RegInit(UInt(XLEN.W), 0.U) 1140 val csrevent16 = RegInit(UInt(XLEN.W), 0.U) 1141 val csrevent17 = RegInit(UInt(XLEN.W), 0.U) 1142 val csrevent18 = RegInit(UInt(XLEN.W), 0.U) 1143 val csrevent19 = RegInit(UInt(XLEN.W), 0.U) 1144 val csrevent20 = RegInit(UInt(XLEN.W), 0.U) 1145 val csrevent21 = RegInit(UInt(XLEN.W), 0.U) 1146 val csrevent22 = RegInit(UInt(XLEN.W), 0.U) 1147 val csrevent23 = RegInit(UInt(XLEN.W), 0.U) 1148 val csrevent24 = RegInit(UInt(XLEN.W), 0.U) 1149 val csrevent25 = RegInit(UInt(XLEN.W), 0.U) 1150 val csrevent26 = RegInit(UInt(XLEN.W), 0.U) 1151 val csrevent27 = RegInit(UInt(XLEN.W), 0.U) 1152 val csrevent28 = RegInit(UInt(XLEN.W), 0.U) 1153 val csrevent29 = RegInit(UInt(XLEN.W), 0.U) 1154 val csrevent30 = RegInit(UInt(XLEN.W), 0.U) 1155 val csrevent31 = RegInit(UInt(XLEN.W), 0.U) 1156 1157 var perfEventMapping = Map( 1158 MaskedRegMap(Mhpmevent3, csrevent3 ), 1159 MaskedRegMap(Mhpmevent4, csrevent4 ), 1160 MaskedRegMap(Mhpmevent5, csrevent5 ), 1161 MaskedRegMap(Mhpmevent6, csrevent6 ), 1162 MaskedRegMap(Mhpmevent7, csrevent7 ), 1163 MaskedRegMap(Mhpmevent8, csrevent8 ), 1164 MaskedRegMap(Mhpmevent9, csrevent9 ), 1165 MaskedRegMap(Mhpmevent10,csrevent10), 1166 MaskedRegMap(Mhpmevent11,csrevent11), 1167 MaskedRegMap(Mhpmevent12,csrevent12), 1168 MaskedRegMap(Mhpmevent13,csrevent13), 1169 MaskedRegMap(Mhpmevent14,csrevent14), 1170 MaskedRegMap(Mhpmevent15,csrevent15), 1171 MaskedRegMap(Mhpmevent16,csrevent16), 1172 MaskedRegMap(Mhpmevent17,csrevent17), 1173 MaskedRegMap(Mhpmevent18,csrevent18), 1174 MaskedRegMap(Mhpmevent19,csrevent19), 1175 MaskedRegMap(Mhpmevent20,csrevent20), 1176 MaskedRegMap(Mhpmevent21,csrevent21), 1177 MaskedRegMap(Mhpmevent22,csrevent22), 1178 MaskedRegMap(Mhpmevent23,csrevent23), 1179 MaskedRegMap(Mhpmevent24,csrevent24), 1180 MaskedRegMap(Mhpmevent25,csrevent25), 1181 MaskedRegMap(Mhpmevent26,csrevent26), 1182 MaskedRegMap(Mhpmevent27,csrevent27), 1183 MaskedRegMap(Mhpmevent28,csrevent28), 1184 MaskedRegMap(Mhpmevent29,csrevent29), 1185 MaskedRegMap(Mhpmevent30,csrevent30), 1186 MaskedRegMap(Mhpmevent31,csrevent31), 1187 ) 1188 1189 val rdata = Wire(UInt(XLEN.W)) 1190 MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 1191 io.hpmevent( 0) := csrevent3 1192 io.hpmevent( 1) := csrevent4 1193 io.hpmevent( 2) := csrevent5 1194 io.hpmevent( 3) := csrevent6 1195 io.hpmevent( 4) := csrevent7 1196 io.hpmevent( 5) := csrevent8 1197 io.hpmevent( 6) := csrevent9 1198 io.hpmevent( 7) := csrevent10 1199 io.hpmevent( 8) := csrevent11 1200 io.hpmevent( 9) := csrevent12 1201 io.hpmevent(10) := csrevent13 1202 io.hpmevent(11) := csrevent14 1203 io.hpmevent(12) := csrevent15 1204 io.hpmevent(13) := csrevent16 1205 io.hpmevent(14) := csrevent17 1206 io.hpmevent(15) := csrevent18 1207 io.hpmevent(16) := csrevent19 1208 io.hpmevent(17) := csrevent20 1209 io.hpmevent(18) := csrevent21 1210 io.hpmevent(19) := csrevent22 1211 io.hpmevent(20) := csrevent23 1212 io.hpmevent(21) := csrevent24 1213 io.hpmevent(22) := csrevent25 1214 io.hpmevent(23) := csrevent26 1215 io.hpmevent(24) := csrevent27 1216 io.hpmevent(25) := csrevent28 1217 io.hpmevent(26) := csrevent29 1218 io.hpmevent(27) := csrevent30 1219 io.hpmevent(28) := csrevent31 1220} 1221 1222