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