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