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