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