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