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