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 === I_Trigger), (triggerType === I_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.", 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), 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 def ReadTdata1(rdata: UInt) = { 353 val tdata1 = tdata1Phy(tselectPhy) 354 Cat( 355 2.U(4.W), // type, hardwired 356 0.U(1.W), // dmode, hardwired 357 0.U(6.W), // maskmax, hardwired to 0 because we don not support 358 1.U(2.W), // sizehi, hardwired 359 tdata1.hit, 360 tdata1.select, // select 361 tdata1.timing, 362 0.U(2.W), // sizelo 363 0.U(3.W), tdata1.action, // action, 0 is breakpoint 1 is enter debug 364 tdata1.chain, 365 0.U(2.W), tdata1.matchType, 366 tdata1.m, false.B, tdata1.s, tdata1.u, 367 GenESL(tdata1_function(tselectPhy)._2) 368 ) 369 } 370 def WriteTdata1(wdata: UInt) = { 371 val tdata1_new = WireInit(tdata1Phy(tselectPhy)) 372 tdata1_new.hit := wdata(20) 373 tdata1_new.select := wdata(19) 374 tdata1_new.timing := wdata(18) 375 tdata1_new.action := wdata(12) 376 tdata1_new.chain := tdata1_function(tselectPhy)._1.B && wdata(11) 377 when(wdata(10, 7) === 0.U || wdata(10, 7) === 2.U || wdata(10, 7) === 3.U) {tdata1_new.matchType := wdata(8, 7)} 378 tdata1_new.m := wdata(6) 379 tdata1_new.s := wdata(4) 380 tdata1_new.u := wdata(3) 381 tdata1Phy(tselectPhy) := tdata1_new 382 0.U 383 } 384 385 def ReadTselect(rdata: UInt) = Cat(0.U(60.W), tselectPhy) 386 def WriteTselect(wdata: UInt) = { 387 when (wdata <= 10.U){ 388 tselectPhy := wdata(3, 0) 389 } 390 0.U 391 } 392 393 def ReadTdata2(tdata: UInt) = tdata2Phy(tselectPhy) 394 def WriteTdata2(wdata: UInt) = { 395 tdata2Phy(tselectPhy) := wdata 396 0.U 397 } 398 399 def ReadTinfo(tdata: UInt) = 2.U(XLEN.W) 400 401 val tcontrolWriteMask = ZeroExt(GenMask(3) | GenMask(7), XLEN) 402 403 404 def GenTdataDistribute(tdata1: TdataBundle, tdata2: UInt): MatchTriggerIO = { 405 val res = Wire(new MatchTriggerIO) 406 res.matchType := tdata1.matchType 407 res.select := tdata1.select 408 res.timing := tdata1.timing 409 res.action := tdata1.action 410 res.chain := tdata1.chain 411 res.tdata2 := tdata2 412 res 413 } 414 415 csrio.customCtrl.frontend_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U, Seq( 416 0.U -> 0.U, 417 1.U -> 1.U, 418 6.U -> 2.U, 419 8.U -> 3.U 420 )) 421 csrio.customCtrl.mem_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U, Seq( 422 2.U -> 0.U, 423 3.U -> 1.U, 424 4.U -> 2.U, 425 5.U -> 3.U, 426 7.U -> 4.U, 427 9.U -> 5.U 428 )) 429 csrio.customCtrl.frontend_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy), tdata2Phy(tselectPhy)) 430 csrio.customCtrl.mem_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy), tdata2Phy(tselectPhy)) 431 432 // Machine-Level CSRs 433 434 val mtvec = RegInit(UInt(XLEN.W), 0.U) 435 val mcounteren = RegInit(UInt(XLEN.W), 0.U) 436 val mcause = RegInit(UInt(XLEN.W), 0.U) 437 val mtval = RegInit(UInt(XLEN.W), 0.U) 438 val mepc = Reg(UInt(XLEN.W)) 439 440 val mie = RegInit(0.U(XLEN.W)) 441 val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 442 val mipReg = RegInit(0.U(XLEN.W)) 443 val mipFixMask = ZeroExt(GenMask(9) | GenMask(5) | GenMask(1), XLEN) 444 val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 445 446 def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt() 447 def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt() 448 var extList = List('a', 's', 'i', 'u') 449 if (HasMExtension) { extList = extList :+ 'm' } 450 if (HasCExtension) { extList = extList :+ 'c' } 451 if (HasFPU) { extList = extList ++ List('f', 'd') } 452 val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U 453 val misa = RegInit(UInt(XLEN.W), misaInitVal) 454 455 // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 456 // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 457 458 val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 459 val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented 460 val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 461 val mhartid = RegInit(UInt(XLEN.W), csrio.hartId) // the hardware thread running the code 462 val mstatus = RegInit(UInt(XLEN.W), 0.U) 463 464 // mstatus Value Table 465 // | sd | 466 // | pad1 | 467 // | sxl | hardlinked to 10, use 00 to pass xv6 test 468 // | uxl | hardlinked to 00 469 // | pad0 | 470 // | tsr | 471 // | tw | 472 // | tvm | 473 // | mxr | 474 // | sum | 475 // | mprv | 476 // | xs | 00 | 477 // | fs | 00 | 478 // | mpp | 00 | 479 // | hpp | 00 | 480 // | spp | 0 | 481 // | pie | 0000 | pie.h is used as UBE 482 // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 483 484 val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 485 def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 486 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 487 val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 488 mstatusNew 489 } 490 491 val mstatusMask = (~ZeroExt(( 492 GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) | 493 GenMask(37) | // MBE 494 GenMask(36) | // SBE 495 GenMask(6) // UBE 496 ), 64)).asUInt() 497 498 val medeleg = RegInit(UInt(XLEN.W), 0.U) 499 val mideleg = RegInit(UInt(XLEN.W), 0.U) 500 val mscratch = RegInit(UInt(XLEN.W), 0.U) 501 502 // PMP Mapping 503 val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter 504 val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter 505 val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp) 506 val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma) 507 508 // Superviser-Level CSRs 509 510 // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 511 val sstatusWmask = "hc6122".U(XLEN.W) 512 // Sstatus Write Mask 513 // ------------------------------------------------------- 514 // 19 9 5 2 515 // 0 1100 0000 0001 0010 0010 516 // 0 c 0 1 2 2 517 // ------------------------------------------------------- 518 val sstatusRmask = sstatusWmask | "h8000000300018000".U 519 // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 520 val stvec = RegInit(UInt(XLEN.W), 0.U) 521 // val sie = RegInit(0.U(XLEN.W)) 522 val sieMask = "h222".U & mideleg 523 val sipMask = "h222".U & mideleg 524 val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode 525 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 526 // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 527 // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0 528 // TODO: use config to control the length of asid 529 // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0 530 val satpMask = Cat("h8".U(4.W),Asid_true_mask(AsidLength),"hfffffffffff".U((XLEN - 4 - 16).W)) 531 val sepc = RegInit(UInt(XLEN.W), 0.U) 532 val scause = RegInit(UInt(XLEN.W), 0.U) 533 val stval = Reg(UInt(XLEN.W)) 534 val sscratch = RegInit(UInt(XLEN.W), 0.U) 535 val scounteren = RegInit(UInt(XLEN.W), 0.U) 536 537 // sbpctl 538 // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB} 539 val sbpctl = RegInit(UInt(XLEN.W), "h7f".U) 540 csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0) 541 csrio.customCtrl.bp_ctrl.btb_enable := sbpctl(1) 542 csrio.customCtrl.bp_ctrl.bim_enable := sbpctl(2) 543 csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3) 544 csrio.customCtrl.bp_ctrl.sc_enable := sbpctl(4) 545 csrio.customCtrl.bp_ctrl.ras_enable := sbpctl(5) 546 csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6) 547 548 // spfctl Bit 0: L1plusCache Prefetcher Enable 549 // spfctl Bit 1: L2Cache Prefetcher Enable 550 val spfctl = RegInit(UInt(XLEN.W), "h3".U) 551 csrio.customCtrl.l1plus_pf_enable := spfctl(0) 552 csrio.customCtrl.l2_pf_enable := spfctl(1) 553 554 // sdsid: Differentiated Services ID 555 val sdsid = RegInit(UInt(XLEN.W), 0.U) 556 csrio.customCtrl.dsid := sdsid 557 558 // slvpredctl: load violation predict settings 559 val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17 560 csrio.customCtrl.lvpred_disable := slvpredctl(0) 561 csrio.customCtrl.no_spec_load := slvpredctl(1) 562 csrio.customCtrl.storeset_wait_store := slvpredctl(2) 563 csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3) 564 csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4) 565 566 // smblockctl: memory block configurations 567 // bits 0-3: store buffer flush threshold (default: 8 entries) 568 val smblockctl_init_val = 569 ("hf".U & StoreBufferThreshold.U) | 570 (EnableLdVioCheckAfterReset.B.asUInt << 4) 571 val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val) 572 csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0) 573 // bits 4: enable load load violation check 574 csrio.customCtrl.ldld_vio_check := smblockctl(4) 575 576 val srnctl = RegInit(UInt(XLEN.W), "h3".U) 577 csrio.customCtrl.move_elim_enable := srnctl(0) 578 csrio.customCtrl.svinval_enable := srnctl(1) 579 580 val tlbBundle = Wire(new TlbCsrBundle) 581 tlbBundle.satp.apply(satp) 582 583 csrio.tlb := tlbBundle 584 585 // User-Level CSRs 586 val uepc = Reg(UInt(XLEN.W)) 587 588 // fcsr 589 class FcsrStruct extends Bundle { 590 val reserved = UInt((XLEN-3-5).W) 591 val frm = UInt(3.W) 592 val fflags = UInt(5.W) 593 assert(this.getWidth == XLEN) 594 } 595 val fcsr = RegInit(0.U(XLEN.W)) 596 // set mstatus->sd and mstatus->fs when true 597 val csrw_dirty_fp_state = WireInit(false.B) 598 599 def frm_wfn(wdata: UInt): UInt = { 600 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 601 csrw_dirty_fp_state := true.B 602 fcsrOld.frm := wdata(2,0) 603 fcsrOld.asUInt() 604 } 605 def frm_rfn(rdata: UInt): UInt = rdata(7,5) 606 607 def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 608 val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 609 val fcsrNew = WireInit(fcsrOld) 610 csrw_dirty_fp_state := true.B 611 if (update) { 612 fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 613 } else { 614 fcsrNew.fflags := wdata(4,0) 615 } 616 fcsrNew.asUInt() 617 } 618 def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 619 620 def fcsr_wfn(wdata: UInt): UInt = { 621 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 622 csrw_dirty_fp_state := true.B 623 Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 624 } 625 626 val fcsrMapping = Map( 627 MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 628 MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 629 MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 630 ) 631 632 // Hart Priviledge Mode 633 val priviledgeMode = RegInit(UInt(2.W), ModeM) 634 635 //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool()))) 636 // Perf Counter 637 val nrPerfCnts = 29 // 3...31 638 val priviledgeModeOH = UIntToOH(priviledgeMode) 639 val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool()))) 640 val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 641 val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 642 List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 643 List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 644 List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 645 for (i <-0 until nrPerfCnts) { 646 perfEventscounten(i) := (Cat(perfEvents(i)(62),perfEvents(i)(61),(perfEvents(i)(61,60))) & priviledgeModeOH).orR 647 } 648 649 val hpmEvents = Wire(new PerfEventsBundle(numPCntHc * coreParams.L2NBanks)) 650 for(i <- 0 until numPCntHc * coreParams.L2NBanks) { 651 hpmEvents.perf_events(i).incr_step := csrio.perf.perfEventsHc(i) 652 } 653 654 val hpm_hc = Module(new HPerfmonitor(numPCntHc * coreParams.L2NBanks,numCSRPCntHc)) 655 val csrevents = perfEvents.slice(24,29) 656 hpm_hc.io.hpm_event := csrevents 657 hpm_hc.io.events_sets := hpmEvents 658 val mcountinhibit = RegInit(0.U(XLEN.W)) 659 val mcycle = RegInit(0.U(XLEN.W)) 660 mcycle := mcycle + 1.U 661 val minstret = RegInit(0.U(XLEN.W)) 662 val perf_events = csrio.perf.perfEventsFrontend.perf_events ++ 663 csrio.perf.perfEventsCtrl.perf_events ++ 664 csrio.perf.perfEventsLsu.perf_events ++ 665 hpm_hc.io.events_selected.perf_events 666 minstret := minstret + RegNext(csrio.perf.retiredInstr) 667 for(i <- 0 until 29){ 668 perfCnts(i) := Mux((mcountinhibit(i+3) | !perfEventscounten(i)), perfCnts(i), (perfCnts(i) + perf_events(i).incr_step)) 669 } 670 671 // CSR reg map 672 val basicPrivMapping = Map( 673 674 //--- User Trap Setup --- 675 // MaskedRegMap(Ustatus, ustatus), 676 // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 677 // MaskedRegMap(Utvec, utvec), 678 679 //--- User Trap Handling --- 680 // MaskedRegMap(Uscratch, uscratch), 681 // MaskedRegMap(Uepc, uepc), 682 // MaskedRegMap(Ucause, ucause), 683 // MaskedRegMap(Utval, utval), 684 // MaskedRegMap(Uip, uip), 685 686 //--- User Counter/Timers --- 687 // MaskedRegMap(Cycle, cycle), 688 // MaskedRegMap(Time, time), 689 // MaskedRegMap(Instret, instret), 690 691 //--- Supervisor Trap Setup --- 692 MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 693 // MaskedRegMap(Sedeleg, Sedeleg), 694 // MaskedRegMap(Sideleg, Sideleg), 695 MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 696 MaskedRegMap(Stvec, stvec), 697 MaskedRegMap(Scounteren, scounteren), 698 699 //--- Supervisor Trap Handling --- 700 MaskedRegMap(Sscratch, sscratch), 701 MaskedRegMap(Sepc, sepc), 702 MaskedRegMap(Scause, scause), 703 MaskedRegMap(Stval, stval), 704 MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask), 705 706 //--- Supervisor Protection and Translation --- 707 MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 708 709 //--- Supervisor Custom Read/Write Registers 710 MaskedRegMap(Sbpctl, sbpctl), 711 MaskedRegMap(Spfctl, spfctl), 712 MaskedRegMap(Sdsid, sdsid), 713 MaskedRegMap(Slvpredctl, slvpredctl), 714 MaskedRegMap(Smblockctl, smblockctl), 715 MaskedRegMap(Srnctl, srnctl), 716 717 //--- Machine Information Registers --- 718 MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 719 MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 720 MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 721 MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable), 722 723 //--- Machine Trap Setup --- 724 MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask), 725 MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 726 MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)), 727 MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)), 728 MaskedRegMap(Mie, mie), 729 MaskedRegMap(Mtvec, mtvec), 730 MaskedRegMap(Mcounteren, mcounteren), 731 732 //--- Machine Trap Handling --- 733 MaskedRegMap(Mscratch, mscratch), 734 MaskedRegMap(Mepc, mepc), 735 MaskedRegMap(Mcause, mcause), 736 MaskedRegMap(Mtval, mtval), 737 MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable), 738 739 //--- Trigger --- 740 MaskedRegMap(Tselect, tDummy, WritableMask, WriteTselect, WritableMask, ReadTselect), 741 MaskedRegMap(Tdata1, tDummy, WritableMask, WriteTdata1, WritableMask, ReadTdata1), 742 MaskedRegMap(Tdata2, tDummy, WritableMask, WriteTdata2, WritableMask, ReadTdata2), 743 MaskedRegMap(Tinfo, tDummy, 0.U(XLEN.W), MaskedRegMap.Unwritable, WritableMask, ReadTinfo), 744 MaskedRegMap(Tcontrol, tControlPhy, tcontrolWriteMask), 745 746 //--- Debug Mode --- 747 MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect), 748 MaskedRegMap(Dpc, dpc), 749 MaskedRegMap(Dscratch, dscratch), 750 MaskedRegMap(Dscratch1, dscratch1), 751 MaskedRegMap(Mcountinhibit, mcountinhibit), 752 MaskedRegMap(Mcycle, mcycle), 753 MaskedRegMap(Minstret, minstret), 754 ) 755 756 val perfCntMapping = (0 until 29).map(i => {Map( 757 MaskedRegMap(addr = Mhpmevent3 +i, 758 reg = perfEvents(i), 759 wmask = "hf87fff3fcff3fcff".U(XLEN.W)), 760 MaskedRegMap(addr = Mhpmcounter3 +i, 761 reg = perfCnts(i)) 762 )}).fold(Map())((a,b) => a ++ b) 763 // TODO: mechanism should be implemented later 764 // val MhpmcounterStart = Mhpmcounter3 765 // val MhpmeventStart = Mhpmevent3 766 // for (i <- 0 until nrPerfCnts) { 767 // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 768 // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 769 // } 770 771 val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 772 name -> RegInit(0.U(attribute("width").toInt.W)) 773 }} 774 val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 775 MaskedRegMap( 776 Scachebase + attribute("offset").toInt, 777 cacheopRegs(name) 778 ) 779 }} 780 781 val mapping = basicPrivMapping ++ 782 perfCntMapping ++ 783 pmpMapping ++ 784 pmaMapping ++ 785 (if (HasFPU) fcsrMapping else Nil) ++ 786 (if (HasCustomCSRCacheOp) cacheopMapping else Nil) 787 788 val addr = src2(11, 0) 789 val csri = ZeroExt(src2(16, 12), XLEN) 790 val rdata = Wire(UInt(XLEN.W)) 791 val wdata = LookupTree(func, List( 792 CSROpType.wrt -> src1, 793 CSROpType.set -> (rdata | src1), 794 CSROpType.clr -> (rdata & (~src1).asUInt()), 795 CSROpType.wrti -> csri, 796 CSROpType.seti -> (rdata | csri), 797 CSROpType.clri -> (rdata & (~csri).asUInt()) 798 )) 799 800 val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) || 801 (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U) 802 csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp 803 804 // satp wen check 805 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 806 807 // csr access check, special case 808 val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool) 809 val accessPermitted = !(addr === Satp.U && tvmNotPermit) 810 csrio.disableSfence := tvmNotPermit 811 812 // general CSR wen check 813 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 814 val dcsrPermitted = dcsrPermissionCheck(addr, false.B, debugMode) 815 val triggerPermitted = triggerPermissionCheck(addr, true.B, debugMode) // todo dmode 816 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) && dcsrPermitted && triggerPermitted 817 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 818 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted 819 820 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 821 io.out.bits.data := rdata 822 io.out.bits.uop := io.in.bits.uop 823 io.out.bits.uop.cf := cfOut 824 io.out.bits.uop.ctrl.flushPipe := flushPipe 825 826 // send distribute csr a w signal 827 csrio.customCtrl.distribute_csr.w.valid := wen && permitted 828 csrio.customCtrl.distribute_csr.w.bits.data := wdata 829 csrio.customCtrl.distribute_csr.w.bits.addr := addr 830 831 // Fix Mip/Sip write 832 val fixMapping = Map( 833 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 834 MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask) 835 ) 836 val rdataFix = Wire(UInt(XLEN.W)) 837 val wdataFix = LookupTree(func, List( 838 CSROpType.wrt -> src1, 839 CSROpType.set -> (rdataFix | src1), 840 CSROpType.clr -> (rdataFix & (~src1).asUInt()), 841 CSROpType.wrti -> csri, 842 CSROpType.seti -> (rdataFix | csri), 843 CSROpType.clri -> (rdataFix & (~csri).asUInt()) 844 )) 845 MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix) 846 847 when (csrio.fpu.fflags.valid) { 848 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 849 } 850 // set fs and sd in mstatus 851 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 852 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 853 mstatusNew.fs := "b11".U 854 mstatusNew.sd := true.B 855 mstatus := mstatusNew.asUInt() 856 } 857 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 858 859 860 // Trigger Ctrl 861 csrio.customCtrl.trigger_enable := tdata1Phy.map{tdata1 => tdata1.m && priviledgeMode === ModeM || 862 tdata1.s && priviledgeMode === ModeS || tdata1.u && priviledgeMode === ModeU 863 } 864 csrio.customCtrl.frontend_trigger.t.valid := RegNext(wen && addr === Tdata1.U && tdata1_function(tselectPhy)._2 === I_Trigger) 865 csrio.customCtrl.mem_trigger.t.valid := RegNext(wen && addr === Tdata1.U && tdata1_function(tselectPhy)._2 =/= I_Trigger) 866 867 868 // CSR inst decode 869 val isEbreak = addr === privEbreak && func === CSROpType.jmp 870 val isEcall = addr === privEcall && func === CSROpType.jmp 871 val isMret = addr === privMret && func === CSROpType.jmp 872 val isSret = addr === privSret && func === CSROpType.jmp 873 val isUret = addr === privUret && func === CSROpType.jmp 874 val isDret = addr === privDret && func === CSROpType.jmp 875 876 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 877 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 878 879 // Illegal priviledged operation list 880 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 881 882 // Illegal priviledged instruction check 883 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 884 val isIllegalAccess = !permitted 885 val isIllegalPrivOp = illegalSModeSret 886 887 // expose several csr bits for tlb 888 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 889 tlbBundle.priv.sum := mstatusStruct.sum.asBool 890 tlbBundle.priv.imode := priviledgeMode 891 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 892 893 // Branch control 894 val retTarget = Wire(UInt(VAddrBits.W)) 895 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 896 flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall) 897 898 retTarget := DontCare 899 // val illegalEret = TODO 900 901 when (valid && isDret) { 902 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 903 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 904 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 905 val debugModeNew = WireInit(debugMode) 906 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. 907 mstatus := mstatusNew.asUInt 908 priviledgeMode := dcsrNew.prv 909 retTarget := dpc(VAddrBits-1, 0) 910 debugModeNew := false.B 911 debugIntrEnable := true.B 912 debugMode := debugModeNew 913 XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget) 914 } 915 916 when (valid && isMret) { 917 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 918 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 919 mstatusNew.ie.m := mstatusOld.pie.m 920 priviledgeMode := mstatusOld.mpp 921 mstatusNew.pie.m := true.B 922 mstatusNew.mpp := ModeU 923 when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U } 924 mstatus := mstatusNew.asUInt 925 // lr := false.B 926 retTarget := mepc(VAddrBits-1, 0) 927 } 928 929 when (valid && isSret && !illegalSModeSret) { 930 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 931 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 932 mstatusNew.ie.s := mstatusOld.pie.s 933 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 934 mstatusNew.pie.s := true.B 935 mstatusNew.spp := ModeU 936 mstatus := mstatusNew.asUInt 937 mstatusNew.mprv := 0.U 938 // lr := false.B 939 retTarget := sepc(VAddrBits-1, 0) 940 } 941 942 when (valid && isUret) { 943 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 944 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 945 // mstatusNew.mpp.m := ModeU //TODO: add mode U 946 mstatusNew.ie.u := mstatusOld.pie.u 947 priviledgeMode := ModeU 948 mstatusNew.pie.u := true.B 949 mstatus := mstatusNew.asUInt 950 retTarget := uepc(VAddrBits-1, 0) 951 } 952 953 io.in.ready := true.B 954 io.out.valid := valid 955 956 val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku) 957 958 val csrExceptionVec = WireInit(cfIn.exceptionVec) 959 csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException 960 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 961 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 962 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 963 // Trigger an illegal instr exception when: 964 // * unimplemented csr is being read/written 965 // * csr access is illegal 966 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 967 cfOut.exceptionVec := csrExceptionVec 968 969 /** 970 * Exception and Intr 971 */ 972 val ideleg = (mideleg & mip.asUInt) 973 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 974 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 975 976 val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable 977 XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!") 978 // send interrupt information to ROB 979 val intrVecEnable = Wire(Vec(12, Bool())) 980 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 981 val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt)) 982 val intrBitSet = intrVec.orR() 983 csrio.interrupt := intrBitSet 984 mipWire.t.m := csrio.externalInterrupt.mtip 985 mipWire.s.m := csrio.externalInterrupt.msip 986 mipWire.e.m := csrio.externalInterrupt.meip 987 mipWire.e.s := csrio.externalInterrupt.seip 988 989 // interrupts 990 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 991 val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 992 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO) 993 val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr 994 995 // exceptions 996 val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 997 val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 998 val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 999 val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 1000 val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 1001 val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 1002 val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 1003 val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 1004 val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 1005 val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException 1006 val hasSingleStep = csrio.exception.bits.uop.ctrl.singleStep && raiseException 1007 val hasTriggerHit = csrio.exception.bits.uop.cf.trigger.triggerHitVec.orR && raiseException 1008 1009 val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 1010 val regularExceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 1011 val exceptionNO = Mux(hasSingleStep || hasTriggerHit, 3.U, regularExceptionNO) 1012 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 1013 1014 val raiseExceptionIntr = csrio.exception.valid 1015 1016 val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep || hasTriggerHit // todo 1017 val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ??? 1018 1019 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 1020 csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 1021 ) 1022 XSDebug(raiseExceptionIntr, 1023 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 1024 csrio.exception.bits.uop.cf.pc, 1025 mstatus, 1026 mideleg, 1027 medeleg, 1028 priviledgeMode 1029 ) 1030 1031 // mtval write logic 1032 // Due to timing reasons of memExceptionVAddr, we delay the write of mtval and stval 1033 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 1034 when (RegNext(RegNext(hasInstrPageFault || hasLoadPageFault || hasStorePageFault))) { 1035 val tval = RegNext(Mux( 1036 RegNext(hasInstrPageFault), 1037 RegNext(Mux( 1038 csrio.exception.bits.uop.cf.crossPageIPFFix, 1039 SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 1040 SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1041 )), 1042 memExceptionAddr 1043 )) 1044 when (RegNext(RegNext(priviledgeMode === ModeM))) { 1045 mtval := tval 1046 }.otherwise { 1047 stval := tval 1048 } 1049 } 1050 1051 when (RegNext(RegNext(hasLoadAddrMisaligned || hasStoreAddrMisaligned))) { 1052 mtval := RegNext(memExceptionAddr) 1053 } 1054 1055 val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec 1056 val deleg = Mux(raiseIntr, mideleg , medeleg) 1057 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 1058 val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 1059 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 1060 val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak 1061 1062 // ctrl block will use theses later for flush 1063 val isXRetFlag = RegInit(false.B) 1064 val retTargetReg = Reg(retTarget.cloneType) 1065 when (io.redirectIn.valid) { 1066 isXRetFlag := false.B 1067 }.elsewhen (isXRet) { 1068 isXRetFlag := true.B 1069 retTargetReg := retTarget 1070 } 1071 csrio.isXRet := isXRetFlag 1072 csrio.trapTarget := Mux(isXRetFlag, 1073 retTargetReg, 1074 Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget, 1075 Mux(delegS, stvec, mtvec))(VAddrBits-1, 0) 1076 ) 1077 1078 when (raiseExceptionIntr) { 1079 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1080 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 1081 val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct)) 1082 val debugModeNew = WireInit(debugMode) 1083 1084 when (raiseDebugExceptionIntr) { 1085 when (raiseDebugIntr) { 1086 debugModeNew := true.B 1087 mstatusNew.mprv := false.B 1088 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1089 dcsrNew.cause := 1.U 1090 dcsrNew.prv := priviledgeMode 1091 priviledgeMode := ModeM 1092 XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc) 1093 }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) { 1094 // ebreak or ss in running hart 1095 debugModeNew := true.B 1096 dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1097 dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U) 1098 dcsrNew.prv := priviledgeMode // TODO 1099 priviledgeMode := ModeM 1100 mstatusNew.mprv := false.B 1101 } 1102 dcsr := dcsrNew.asUInt 1103 debugIntrEnable := false.B 1104 }.elsewhen (delegS) { 1105 scause := causeNO 1106 sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1107 mstatusNew.spp := priviledgeMode 1108 mstatusNew.pie.s := mstatusOld.ie.s 1109 mstatusNew.ie.s := false.B 1110 priviledgeMode := ModeS 1111 when (tvalWen) { stval := 0.U } 1112 }.otherwise { 1113 mcause := causeNO 1114 mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 1115 mstatusNew.mpp := priviledgeMode 1116 mstatusNew.pie.m := mstatusOld.ie.m 1117 mstatusNew.ie.m := false.B 1118 priviledgeMode := ModeM 1119 when (tvalWen) { mtval := 0.U } 1120 } 1121 mstatus := mstatusNew.asUInt 1122 debugMode := debugModeNew 1123 } 1124 1125 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 1126 1127 // Distributed CSR update req 1128 // 1129 // For now we use it to implement customized cache op 1130 1131 when(csrio.distributedUpdate.w.valid){ 1132 // cacheopRegs can be distributed updated 1133 CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => { 1134 when((Scachebase + attribute("offset").toInt).U === csrio.distributedUpdate.w.bits.addr){ 1135 cacheopRegs(name) := csrio.distributedUpdate.w.bits.data 1136 } 1137 }} 1138 } 1139 1140 def readWithScala(addr: Int): UInt = mapping(addr)._1 1141 1142 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 1143 1144 // Always instantiate basic difftest modules. 1145 if (env.AlwaysBasicDiff || env.EnableDifftest) { 1146 val difftest = Module(new DifftestArchEvent) 1147 difftest.io.clock := clock 1148 difftest.io.coreid := csrio.hartId 1149 difftest.io.intrNO := RegNext(RegNext(RegNext(difftestIntrNO))) 1150 difftest.io.cause := RegNext(RegNext(RegNext(Mux(csrio.exception.valid, causeNO, 0.U)))) 1151 difftest.io.exceptionPC := RegNext(RegNext(RegNext(SignExt(csrio.exception.bits.uop.cf.pc, XLEN)))) 1152 } 1153 1154 // Always instantiate basic difftest modules. 1155 if (env.AlwaysBasicDiff || env.EnableDifftest) { 1156 val difftest = Module(new DifftestCSRState) 1157 difftest.io.clock := clock 1158 difftest.io.coreid := csrio.hartId 1159 difftest.io.priviledgeMode := priviledgeMode 1160 difftest.io.mstatus := mstatus 1161 difftest.io.sstatus := mstatus & sstatusRmask 1162 difftest.io.mepc := mepc 1163 difftest.io.sepc := sepc 1164 difftest.io.mtval:= mtval 1165 difftest.io.stval:= stval 1166 difftest.io.mtvec := mtvec 1167 difftest.io.stvec := stvec 1168 difftest.io.mcause := mcause 1169 difftest.io.scause := scause 1170 difftest.io.satp := satp 1171 difftest.io.mip := mipReg 1172 difftest.io.mie := mie 1173 difftest.io.mscratch := mscratch 1174 difftest.io.sscratch := sscratch 1175 difftest.io.mideleg := mideleg 1176 difftest.io.medeleg := medeleg 1177 } 1178} 1179 1180class PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst { 1181 val io = IO(new Bundle { 1182 val distribute_csr = Flipped(new DistributedCSRIO()) 1183 val hpmevent = Output(Vec(29, UInt(XLEN.W))) 1184 }) 1185 1186 val w = io.distribute_csr.w 1187 1188 val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 1189 List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 1190 List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 1191 List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 1192 1193 val perfEventMapping = (0 until 29).map(i => {Map( 1194 MaskedRegMap(addr = Mhpmevent3 +i, 1195 reg = perfEvents(i), 1196 wmask = "hf87fff3fcff3fcff".U(XLEN.W)) 1197 )}).fold(Map())((a,b) => a ++ b) 1198 1199 val rdata = Wire(UInt(XLEN.W)) 1200 MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data) 1201 for(i <- 0 until 29){ 1202 io.hpmevent(i) := perfEvents(i) 1203 } 1204} 1205 1206