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