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