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