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