1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.ExcitingUtils.{ConnectionType, Debug} 5import chisel3.util._ 6import utils._ 7import xiangshan._ 8import xiangshan.backend._ 9import xiangshan.backend.fu.util._ 10import utils.XSDebug 11 12object hartId extends (() => Int) { 13 var x = 0 14 def apply(): Int = { 15 x = x + 1 16 x-1 17 } 18} 19 20trait HasExceptionNO { 21 def instrAddrMisaligned = 0 22 def instrAccessFault = 1 23 def illegalInstr = 2 24 def breakPoint = 3 25 def loadAddrMisaligned = 4 26 def loadAccessFault = 5 27 def storeAddrMisaligned = 6 28 def storeAccessFault = 7 29 def ecallU = 8 30 def ecallS = 9 31 def ecallM = 11 32 def instrPageFault = 12 33 def loadPageFault = 13 34 def storePageFault = 15 35 36 val ExcPriority = Seq( 37 breakPoint, // TODO: different BP has different priority 38 instrPageFault, 39 instrAccessFault, 40 illegalInstr, 41 instrAddrMisaligned, 42 ecallM, ecallS, ecallU, 43 storePageFault, 44 loadPageFault, 45 storeAccessFault, 46 loadAccessFault, 47 storeAddrMisaligned, 48 loadAddrMisaligned 49 ) 50 val frontendSet = List( 51 // instrAddrMisaligned, 52 instrAccessFault, 53 illegalInstr, 54 instrPageFault 55 ) 56 val csrSet = List( 57 illegalInstr, 58 breakPoint, 59 ecallU, 60 ecallS, 61 ecallM 62 ) 63 val loadUnitSet = List( 64 loadAddrMisaligned, 65 loadAccessFault, 66 loadPageFault 67 ) 68 val storeUnitSet = List( 69 storeAddrMisaligned, 70 storeAccessFault, 71 storePageFault 72 ) 73 val atomicsUnitSet = (loadUnitSet ++ storeUnitSet).distinct 74 val allPossibleSet = (frontendSet ++ csrSet ++ loadUnitSet ++ storeUnitSet).distinct 75 val csrWbCount = (0 until 16).map(i => if (csrSet.contains(i)) 1 else 0) 76 val loadWbCount = (0 until 16).map(i => if (loadUnitSet.contains(i)) 1 else 0) 77 val storeWbCount = (0 until 16).map(i => if (storeUnitSet.contains(i)) 1 else 0) 78 val atomicsWbCount = (0 until 16).map(i => if (atomicsUnitSet.contains(i)) 1 else 0) 79 val writebackCount = (0 until 16).map(i => csrWbCount(i) + atomicsWbCount(i) + loadWbCount(i) + 2 * storeWbCount(i)) 80 def partialSelect(vec: Vec[Bool], select: Seq[Int], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = { 81 if (dontCareBits) { 82 val new_vec = Wire(ExceptionVec()) 83 new_vec := DontCare 84 select.map(i => new_vec(i) := vec(i)) 85 return new_vec 86 } 87 else if (falseBits) { 88 val new_vec = Wire(ExceptionVec()) 89 new_vec.map(_ := false.B) 90 select.map(i => new_vec(i) := vec(i)) 91 return new_vec 92 } 93 else { 94 val new_vec = Wire(Vec(select.length, Bool())) 95 select.zipWithIndex.map{ case(s, i) => new_vec(i) := vec(s) } 96 return new_vec 97 } 98 } 99 def selectFrontend(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 100 partialSelect(vec, frontendSet, dontCareBits, falseBits) 101 def selectCSR(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 102 partialSelect(vec, csrSet, dontCareBits, falseBits) 103 def selectLoad(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 104 partialSelect(vec, loadUnitSet, dontCareBits, falseBits) 105 def selectStore(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 106 partialSelect(vec, storeUnitSet, dontCareBits, falseBits) 107 def selectAtomics(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 108 partialSelect(vec, atomicsUnitSet, dontCareBits, falseBits) 109 def selectAll(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 110 partialSelect(vec, allPossibleSet, dontCareBits, falseBits) 111} 112 113class FpuCsrIO extends XSBundle { 114 val fflags = Output(Valid(UInt(5.W))) 115 val isIllegal = Output(Bool()) 116 val dirty_fs = Output(Bool()) 117 val frm = Input(UInt(3.W)) 118} 119 120 121class PerfCounterIO extends XSBundle { 122 val retiredInstr = Input(UInt(3.W)) 123 val value = Input(UInt(XLEN.W)) 124} 125 126class CSR extends FunctionUnit with HasCSRConst 127{ 128 val csrio = IO(new Bundle { 129 // output (for func === CSROpType.jmp) 130 val redirectOut = ValidIO(UInt(VAddrBits.W)) 131 val perf = new PerfCounterIO 132 val isPerfCnt = Output(Bool()) 133 // to FPU 134 val fpu = Flipped(new FpuCsrIO) 135 // from rob 136 val exception = Flipped(ValidIO(new MicroOp)) 137 val isInterrupt = Input(Bool()) 138 // to ROB 139 val trapTarget = Output(UInt(VAddrBits.W)) 140 val interrupt = Output(Bool()) 141 // from LSQ 142 val memExceptionVAddr = Input(UInt(VAddrBits.W)) 143 // from outside cpu,externalInterrupt 144 val externalInterrupt = new ExternalInterruptIO 145 // TLB 146 val tlb = Output(new TlbCsrBundle) 147 }) 148 val difftestIO = IO(new Bundle() { 149 val intrNO = Output(UInt(64.W)) 150 val cause = Output(UInt(64.W)) 151 val priviledgeMode = Output(UInt(2.W)) 152 val mstatus = Output(UInt(64.W)) 153 val sstatus = Output(UInt(64.W)) 154 val mepc = Output(UInt(64.W)) 155 val sepc = Output(UInt(64.W)) 156 val mtval = Output(UInt(64.W)) 157 val stval = Output(UInt(64.W)) 158 val mtvec = Output(UInt(64.W)) 159 val stvec = Output(UInt(64.W)) 160 val mcause = Output(UInt(64.W)) 161 val scause = Output(UInt(64.W)) 162 val satp = Output(UInt(64.W)) 163 val mip = Output(UInt(64.W)) 164 val mie = Output(UInt(64.W)) 165 val mscratch = Output(UInt(64.W)) 166 val sscratch = Output(UInt(64.W)) 167 val mideleg = Output(UInt(64.W)) 168 val medeleg = Output(UInt(64.W)) 169 }) 170 difftestIO <> DontCare 171 172 val cfIn = io.in.bits.uop.cf 173 val cfOut = Wire(new CtrlFlow) 174 cfOut := cfIn 175 val flushPipe = Wire(Bool()) 176 177 val (valid, src1, src2, func) = ( 178 io.in.valid, 179 io.in.bits.src(0), 180 io.in.bits.uop.ctrl.imm, 181 io.in.bits.uop.ctrl.fuOpType 182 ) 183 184 // CSR define 185 186 class Priv extends Bundle { 187 val m = Output(Bool()) 188 val h = Output(Bool()) 189 val s = Output(Bool()) 190 val u = Output(Bool()) 191 } 192 193 val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U) 194 195 class MstatusStruct extends Bundle { 196 val sd = Output(UInt(1.W)) 197 198 val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null 199 val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 200 val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 201 val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 202 203 val tsr = Output(UInt(1.W)) 204 val tw = Output(UInt(1.W)) 205 val tvm = Output(UInt(1.W)) 206 val mxr = Output(UInt(1.W)) 207 val sum = Output(UInt(1.W)) 208 val mprv = Output(UInt(1.W)) 209 val xs = Output(UInt(2.W)) 210 val fs = Output(UInt(2.W)) 211 val mpp = Output(UInt(2.W)) 212 val hpp = Output(UInt(2.W)) 213 val spp = Output(UInt(1.W)) 214 val pie = new Priv 215 val ie = new Priv 216 assert(this.getWidth == XLEN) 217 } 218 219 class SatpStruct extends Bundle { 220 val mode = UInt(4.W) 221 val asid = UInt(16.W) 222 val ppn = UInt(44.W) 223 } 224 225 class Interrupt extends Bundle { 226 val e = new Priv 227 val t = new Priv 228 val s = new Priv 229 } 230 231 // Machine-Level CSRs 232 233 val mtvec = RegInit(UInt(XLEN.W), 0.U) 234 val mcounteren = RegInit(UInt(XLEN.W), 0.U) 235 val mcause = RegInit(UInt(XLEN.W), 0.U) 236 val mtval = RegInit(UInt(XLEN.W), 0.U) 237 val mepc = Reg(UInt(XLEN.W)) 238 239 val mie = RegInit(0.U(XLEN.W)) 240 val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 241 val mipReg = RegInit(0.U.asTypeOf(new Interrupt).asUInt) 242 val mipFixMask = GenMask(9) | GenMask(5) | GenMask(1) 243 val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 244 245 def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt() 246 def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt() 247 var extList = List('a', 's', 'i', 'u') 248 if (HasMExtension) { extList = extList :+ 'm' } 249 if (HasCExtension) { extList = extList :+ 'c' } 250 if (HasFPU) { extList = extList ++ List('f', 'd') } 251 val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U 252 val misa = RegInit(UInt(XLEN.W), misaInitVal) 253 254 // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 255 // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 256 257 val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 258 val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented 259 val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 260 val mhartNo = hartId() 261 val mhartid = RegInit(UInt(XLEN.W), mhartNo.asUInt) // the hardware thread running the code 262 val mstatus = RegInit(UInt(XLEN.W), 0.U) 263 264 // mstatus Value Table 265 // | sd | 266 // | pad1 | 267 // | sxl | hardlinked to 10, use 00 to pass xv6 test 268 // | uxl | hardlinked to 00 269 // | pad0 | 270 // | tsr | 271 // | tw | 272 // | tvm | 273 // | mxr | 274 // | sum | 275 // | mprv | 276 // | xs | 00 | 277 // | fs | 00 | 278 // | mpp | 00 | 279 // | hpp | 00 | 280 // | spp | 0 | 281 // | pie | 0000 | pie.h is used as UBE 282 // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 283 284 val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 285 def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 286 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 287 val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 288 mstatusNew 289 } 290 291 val mstatusMask = (~ZeroExt(( 292 GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) | 293 GenMask(37) | // MBE 294 GenMask(36) | // SBE 295 GenMask(6) // UBE 296 ), 64)).asUInt() 297 298 val medeleg = RegInit(UInt(XLEN.W), 0.U) 299 val mideleg = RegInit(UInt(XLEN.W), 0.U) 300 val mscratch = RegInit(UInt(XLEN.W), 0.U) 301 302 val pmpcfg0 = RegInit(UInt(XLEN.W), 0.U) 303 val pmpcfg1 = RegInit(UInt(XLEN.W), 0.U) 304 val pmpcfg2 = RegInit(UInt(XLEN.W), 0.U) 305 val pmpcfg3 = RegInit(UInt(XLEN.W), 0.U) 306 val pmpaddr0 = RegInit(UInt(XLEN.W), 0.U) 307 val pmpaddr1 = RegInit(UInt(XLEN.W), 0.U) 308 val pmpaddr2 = RegInit(UInt(XLEN.W), 0.U) 309 val pmpaddr3 = RegInit(UInt(XLEN.W), 0.U) 310 311 // Superviser-Level CSRs 312 313 // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 314 val sstatusWmask = "hc6122".U 315 // Sstatus Write Mask 316 // ------------------------------------------------------- 317 // 19 9 5 2 318 // 0 1100 0000 0001 0010 0010 319 // 0 c 0 1 2 2 320 // ------------------------------------------------------- 321 val sstatusRmask = sstatusWmask | "h8000000300018000".U 322 // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 323 val stvec = RegInit(UInt(XLEN.W), 0.U) 324 // val sie = RegInit(0.U(XLEN.W)) 325 val sieMask = "h222".U & mideleg 326 val sipMask = "h222".U & mideleg 327 val satp = RegInit(0.U(XLEN.W)) 328 // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 329 val satpMask = "h80000fffffffffff".U // disable asid, mode can only be 8 / 0 330 val sepc = RegInit(UInt(XLEN.W), 0.U) 331 val scause = RegInit(UInt(XLEN.W), 0.U) 332 val stval = Reg(UInt(XLEN.W)) 333 val sscratch = RegInit(UInt(XLEN.W), 0.U) 334 val scounteren = RegInit(UInt(XLEN.W), 0.U) 335 336 val tlbBundle = Wire(new TlbCsrBundle) 337 tlbBundle.satp := satp.asTypeOf(new SatpStruct) 338 csrio.tlb := tlbBundle 339 340 // User-Level CSRs 341 val uepc = Reg(UInt(XLEN.W)) 342 343 // fcsr 344 class FcsrStruct extends Bundle { 345 val reserved = UInt((XLEN-3-5).W) 346 val frm = UInt(3.W) 347 val fflags = UInt(5.W) 348 assert(this.getWidth == XLEN) 349 } 350 val fcsr = RegInit(0.U(XLEN.W)) 351 // set mstatus->sd and mstatus->fs when true 352 val csrw_dirty_fp_state = WireInit(false.B) 353 354 def frm_wfn(wdata: UInt): UInt = { 355 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 356 csrw_dirty_fp_state := true.B 357 fcsrOld.frm := wdata(2,0) 358 fcsrOld.asUInt() 359 } 360 def frm_rfn(rdata: UInt): UInt = rdata(7,5) 361 362 def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 363 val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 364 val fcsrNew = WireInit(fcsrOld) 365 csrw_dirty_fp_state := true.B 366 if (update) { 367 fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 368 } else { 369 fcsrNew.fflags := wdata(4,0) 370 } 371 fcsrNew.asUInt() 372 } 373 def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 374 375 def fcsr_wfn(wdata: UInt): UInt = { 376 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 377 csrw_dirty_fp_state := true.B 378 Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 379 } 380 381 val fcsrMapping = Map( 382 MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 383 MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 384 MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 385 ) 386 387 // Atom LR/SC Control Bits 388 // val setLr = WireInit(Bool(), false.B) 389 // val setLrVal = WireInit(Bool(), false.B) 390 // val setLrAddr = WireInit(UInt(AddrBits.W), DontCare) //TODO : need check 391 // val lr = RegInit(Bool(), false.B) 392 // val lrAddr = RegInit(UInt(AddrBits.W), 0.U) 393 // 394 // when (setLr) { 395 // lr := setLrVal 396 // lrAddr := setLrAddr 397 // } 398 399 // Hart Priviledge Mode 400 val priviledgeMode = RegInit(UInt(2.W), ModeM) 401 402 // Emu perfcnt 403 val hasEmuPerfCnt = !env.FPGAPlatform 404 val nrEmuPerfCnts = if (hasEmuPerfCnt) 0x80 else 0x3 405 406 val emuPerfCnts = List.fill(nrEmuPerfCnts)(RegInit(0.U(XLEN.W))) 407 val emuPerfCntCond = List.fill(nrEmuPerfCnts)(WireInit(false.B)) 408 (emuPerfCnts zip emuPerfCntCond).map { case (c, e) => when (e) { c := c + 1.U } } 409 410 val emuPerfCntsLoMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1000 + i, emuPerfCnts(i))) 411 val emuPerfCntsHiMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1080 + i, emuPerfCnts(i)(63, 32))) 412 println(s"CSR: hasEmuPerfCnt:${hasEmuPerfCnt}") 413 414 // Perf Counter 415 val nrPerfCnts = 29 // 3...31 416 val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 417 val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 418 val mcountinhibit = RegInit(0.U(XLEN.W)) 419 val mcycle = RegInit(0.U(XLEN.W)) 420 mcycle := mcycle + 1.U 421 val minstret = RegInit(0.U(XLEN.W)) 422 minstret := minstret + RegNext(csrio.perf.retiredInstr) 423 424 // CSR reg map 425 val basicPrivMapping = Map( 426 427 //--- User Trap Setup --- 428 // MaskedRegMap(Ustatus, ustatus), 429 // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 430 // MaskedRegMap(Utvec, utvec), 431 432 //--- User Trap Handling --- 433 // MaskedRegMap(Uscratch, uscratch), 434 // MaskedRegMap(Uepc, uepc), 435 // MaskedRegMap(Ucause, ucause), 436 // MaskedRegMap(Utval, utval), 437 // MaskedRegMap(Uip, uip), 438 439 //--- User Counter/Timers --- 440 // MaskedRegMap(Cycle, cycle), 441 // MaskedRegMap(Time, time), 442 // MaskedRegMap(Instret, instret), 443 444 //--- Supervisor Trap Setup --- 445 MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 446 // MaskedRegMap(Sedeleg, Sedeleg), 447 // MaskedRegMap(Sideleg, Sideleg), 448 MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 449 MaskedRegMap(Stvec, stvec), 450 MaskedRegMap(Scounteren, scounteren), 451 452 //--- Supervisor Trap Handling --- 453 MaskedRegMap(Sscratch, sscratch), 454 MaskedRegMap(Sepc, sepc), 455 MaskedRegMap(Scause, scause), 456 MaskedRegMap(Stval, stval), 457 MaskedRegMap(Sip, mip.asUInt, sipMask, MaskedRegMap.Unwritable, sipMask), 458 459 //--- Supervisor Protection and Translation --- 460 MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 461 462 //--- Machine Information Registers --- 463 MaskedRegMap(Mvendorid, mvendorid, 0.U, MaskedRegMap.Unwritable), 464 MaskedRegMap(Marchid, marchid, 0.U, MaskedRegMap.Unwritable), 465 MaskedRegMap(Mimpid, mimpid, 0.U, MaskedRegMap.Unwritable), 466 MaskedRegMap(Mhartid, mhartid, 0.U, MaskedRegMap.Unwritable), 467 468 //--- Machine Trap Setup --- 469 MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask), 470 MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 471 MaskedRegMap(Medeleg, medeleg, "hf3ff".U), 472 MaskedRegMap(Mideleg, mideleg, "h222".U), 473 MaskedRegMap(Mie, mie), 474 MaskedRegMap(Mtvec, mtvec), 475 MaskedRegMap(Mcounteren, mcounteren), 476 477 //--- Machine Trap Handling --- 478 MaskedRegMap(Mscratch, mscratch), 479 MaskedRegMap(Mepc, mepc), 480 MaskedRegMap(Mcause, mcause), 481 MaskedRegMap(Mtval, mtval), 482 MaskedRegMap(Mip, mip.asUInt, 0.U, MaskedRegMap.Unwritable), 483 ) 484 485 // PMP is unimplemented yet 486 val pmpMapping = Map( 487 MaskedRegMap(Pmpcfg0, pmpcfg0), 488 MaskedRegMap(Pmpcfg1, pmpcfg1), 489 MaskedRegMap(Pmpcfg2, pmpcfg2), 490 MaskedRegMap(Pmpcfg3, pmpcfg3), 491 MaskedRegMap(PmpaddrBase + 0, pmpaddr0), 492 MaskedRegMap(PmpaddrBase + 1, pmpaddr1), 493 MaskedRegMap(PmpaddrBase + 2, pmpaddr2), 494 MaskedRegMap(PmpaddrBase + 3, pmpaddr3) 495 ) 496 497 var perfCntMapping = Map( 498 MaskedRegMap(Mcountinhibit, mcountinhibit), 499 MaskedRegMap(Mcycle, mcycle), 500 MaskedRegMap(Minstret, minstret), 501 ) 502 val MhpmcounterStart = Mhpmcounter3 503 val MhpmeventStart = Mhpmevent3 504 for (i <- 0 until nrPerfCnts) { 505 perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 506 perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 507 } 508 509 val mapping = basicPrivMapping ++ 510 perfCntMapping ++ 511 pmpMapping ++ 512 emuPerfCntsLoMapping ++ 513 (if (XLEN == 32) emuPerfCntsHiMapping else Nil) ++ 514 (if (HasFPU) fcsrMapping else Nil) 515 516 val addr = src2(11, 0) 517 val csri = ZeroExt(src2(16, 12), XLEN) 518 val rdata = Wire(UInt(XLEN.W)) 519 val wdata = LookupTree(func, List( 520 CSROpType.wrt -> src1, 521 CSROpType.set -> (rdata | src1), 522 CSROpType.clr -> (rdata & (~src1).asUInt()), 523 CSROpType.wrti -> csri, 524 CSROpType.seti -> (rdata | csri), 525 CSROpType.clri -> (rdata & (~csri).asUInt()) 526 )) 527 528 val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) 529 csrio.isPerfCnt := addrInPerfCnt 530 531 // satp wen check 532 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 533 534 // general CSR wen check 535 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 536 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 537 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 538 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) 539 // Writeable check is ingored. 540 // Currently, write to illegal csr addr will be ignored 541 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 542 io.out.bits.data := rdata 543 io.out.bits.uop := io.in.bits.uop 544 io.out.bits.uop.cf := cfOut 545 io.out.bits.uop.ctrl.flushPipe := flushPipe 546 547 // Fix Mip/Sip write 548 val fixMapping = Map( 549 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 550 MaskedRegMap(Sip, mipReg.asUInt, sipMask, MaskedRegMap.NoSideEffect, sipMask) 551 ) 552 val rdataDummy = Wire(UInt(XLEN.W)) 553 MaskedRegMap.generate(fixMapping, addr, rdataDummy, wen, wdata) 554 555 when (csrio.fpu.fflags.valid) { 556 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 557 } 558 // set fs and sd in mstatus 559 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 560 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 561 mstatusNew.fs := "b11".U 562 mstatusNew.sd := true.B 563 mstatus := mstatusNew.asUInt() 564 } 565 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 566 567 // CSR inst decode 568 val isEbreak = addr === privEbreak && func === CSROpType.jmp 569 val isEcall = addr === privEcall && func === CSROpType.jmp 570 val isMret = addr === privMret && func === CSROpType.jmp 571 val isSret = addr === privSret && func === CSROpType.jmp 572 val isUret = addr === privUret && func === CSROpType.jmp 573 574 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 575 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 576 577 // Illegal priviledged operation list 578 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 579 580 // Illegal priviledged instruction check 581 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 582 val isIllegalAccess = !permitted 583 val isIllegalPrivOp = illegalSModeSret 584 585 // def MMUPermissionCheck(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) 586 // def MMUPermissionCheckLoad(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) && (pter || (mstatusStruct.mxr && ptex)) 587 // imem 588 // val imemPtev = true.B 589 // val imemPteu = true.B 590 // val imemPtex = true.B 591 // val imemReq = true.B 592 // val imemPermissionCheckPassed = MMUPermissionCheck(imemPtev, imemPteu) 593 // val hasInstrPageFault = imemReq && !(imemPermissionCheckPassed && imemPtex) 594 // assert(!hasInstrPageFault) 595 596 // dmem 597 // val dmemPtev = true.B 598 // val dmemPteu = true.B 599 // val dmemReq = true.B 600 // val dmemPermissionCheckPassed = MMUPermissionCheck(dmemPtev, dmemPteu) 601 // val dmemIsStore = true.B 602 603 // val hasLoadPageFault = dmemReq && !dmemIsStore && !(dmemPermissionCheckPassed) 604 // val hasStorePageFault = dmemReq && dmemIsStore && !(dmemPermissionCheckPassed) 605 // assert(!hasLoadPageFault) 606 // assert(!hasStorePageFault) 607 608 //TODO: Havn't test if io.dmemMMU.priviledgeMode is correct yet 609 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 610 tlbBundle.priv.sum := mstatusStruct.sum.asBool 611 tlbBundle.priv.imode := priviledgeMode 612 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 613 614 // Branch control 615 val retTarget = Wire(UInt(VAddrBits.W)) 616 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 617 csrio.redirectOut.valid := valid && func === CSROpType.jmp && !isEcall 618 csrio.redirectOut.bits := retTarget 619 flushPipe := resetSatp 620 XSDebug(csrio.redirectOut.valid, "redirect to %x, pc=%x\n", csrio.redirectOut.bits, cfIn.pc) 621 622 retTarget := DontCare 623 // val illegalEret = TODO 624 625 when (valid && isMret) { 626 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 627 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 628 mstatusNew.ie.m := mstatusOld.pie.m 629 priviledgeMode := mstatusOld.mpp 630 mstatusNew.pie.m := true.B 631 mstatusNew.mpp := ModeU 632 mstatusNew.mprv := 0.U 633 mstatus := mstatusNew.asUInt 634 // lr := false.B 635 retTarget := mepc(VAddrBits-1, 0) 636 } 637 638 when (valid && isSret && !illegalSModeSret) { 639 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 640 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 641 mstatusNew.ie.s := mstatusOld.pie.s 642 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 643 mstatusNew.pie.s := true.B 644 mstatusNew.spp := ModeU 645 mstatus := mstatusNew.asUInt 646 mstatusNew.mprv := 0.U 647 // lr := false.B 648 retTarget := sepc(VAddrBits-1, 0) 649 } 650 651 when (valid && isUret) { 652 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 653 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 654 // mstatusNew.mpp.m := ModeU //TODO: add mode U 655 mstatusNew.ie.u := mstatusOld.pie.u 656 priviledgeMode := ModeU 657 mstatusNew.pie.u := true.B 658 mstatus := mstatusNew.asUInt 659 retTarget := uepc(VAddrBits-1, 0) 660 } 661 662 XSDebug(csrio.redirectOut.valid, 663 "Rediret %x isSret:%d retTarget:%x sepc:%x cfInpc:%x valid:%d\n", 664 csrio.redirectOut.bits, isSret, retTarget, sepc, cfIn.pc, valid 665 ) 666 667 io.in.ready := true.B 668 io.out.valid := valid 669 670 val csrExceptionVec = WireInit(cfIn.exceptionVec) 671 csrExceptionVec(breakPoint) := io.in.valid && isEbreak 672 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 673 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 674 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 675 // Trigger an illegal instr exception when: 676 // * unimplemented csr is being read/written 677 // * csr access is illegal 678 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 679 cfOut.exceptionVec := csrExceptionVec 680 681 /** 682 * Exception and Intr 683 */ 684 val ideleg = (mideleg & mip.asUInt) 685 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 686 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 687 688 // send interrupt information to ROQ 689 val intrVecEnable = Wire(Vec(12, Bool())) 690 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 691 val intrVec = mie(11,0) & mip.asUInt & intrVecEnable.asUInt 692 val intrBitSet = intrVec.orR() 693 csrio.interrupt := intrBitSet 694 mipWire.t.m := csrio.externalInterrupt.mtip 695 mipWire.s.m := csrio.externalInterrupt.msip 696 mipWire.e.m := csrio.externalInterrupt.meip 697 698 // interrupts 699 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 700 val raiseIntr = csrio.exception.valid && csrio.isInterrupt 701 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.cf.pc, intrNO) 702 703 // exceptions 704 val raiseException = csrio.exception.valid && !csrio.isInterrupt 705 val hasInstrPageFault = csrio.exception.bits.cf.exceptionVec(instrPageFault) && raiseException 706 val hasLoadPageFault = csrio.exception.bits.cf.exceptionVec(loadPageFault) && raiseException 707 val hasStorePageFault = csrio.exception.bits.cf.exceptionVec(storePageFault) && raiseException 708 val hasStoreAddrMisaligned = csrio.exception.bits.cf.exceptionVec(storeAddrMisaligned) && raiseException 709 val hasLoadAddrMisaligned = csrio.exception.bits.cf.exceptionVec(loadAddrMisaligned) && raiseException 710 val hasInstrAccessFault = csrio.exception.bits.cf.exceptionVec(instrAccessFault) && raiseException 711 val hasLoadAccessFault = csrio.exception.bits.cf.exceptionVec(loadAccessFault) && raiseException 712 val hasStoreAccessFault = csrio.exception.bits.cf.exceptionVec(storeAccessFault) && raiseException 713 714 val raiseExceptionVec = csrio.exception.bits.cf.exceptionVec 715 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 716 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 717 718 val raiseExceptionIntr = csrio.exception.valid 719 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 720 csrio.exception.bits.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 721 ) 722 XSDebug(raiseExceptionIntr, 723 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 724 csrio.exception.bits.cf.pc, 725 mstatus, 726 mideleg, 727 medeleg, 728 priviledgeMode 729 ) 730 731 // mtval write logic 732 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 733 when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) { 734 val tval = Mux( 735 hasInstrPageFault, 736 Mux( 737 csrio.exception.bits.cf.crossPageIPFFix, 738 SignExt(csrio.exception.bits.cf.pc + 2.U, XLEN), 739 SignExt(csrio.exception.bits.cf.pc, XLEN) 740 ), 741 memExceptionAddr 742 ) 743 when (priviledgeMode === ModeM) { 744 mtval := tval 745 }.otherwise { 746 stval := tval 747 } 748 } 749 750 when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) { 751 mtval := memExceptionAddr 752 } 753 754 val deleg = Mux(raiseIntr, mideleg , medeleg) 755 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 756 val delegS = (deleg(causeNO(3,0))) && (priviledgeMode < ModeM) 757 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 758 csrio.trapTarget := Mux(delegS, stvec, mtvec)(VAddrBits-1, 0) 759 760 when (raiseExceptionIntr) { 761 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 762 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 763 764 when (delegS) { 765 scause := causeNO 766 sepc := SignExt(csrio.exception.bits.cf.pc, XLEN) 767 mstatusNew.spp := priviledgeMode 768 mstatusNew.pie.s := mstatusOld.ie.s 769 mstatusNew.ie.s := false.B 770 priviledgeMode := ModeS 771 when (tvalWen) { stval := 0.U } 772 }.otherwise { 773 mcause := causeNO 774 mepc := SignExt(csrio.exception.bits.cf.pc, XLEN) 775 mstatusNew.mpp := priviledgeMode 776 mstatusNew.pie.m := mstatusOld.ie.m 777 mstatusNew.ie.m := false.B 778 priviledgeMode := ModeM 779 when (tvalWen) { mtval := 0.U } 780 } 781 782 mstatus := mstatusNew.asUInt 783 } 784 785 XSDebug(raiseExceptionIntr && delegS, 786 "Red(%d, %x) raiseExcepIntr:%d isSret:%d sepc:%x delegs:%d deleg:%x\n", 787 csrio.redirectOut.valid, csrio.redirectOut.bits, raiseExceptionIntr, 788 isSret, sepc, delegS, deleg 789 ) 790 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 791 792 793 /** 794 * Emu Performance counters 795 */ 796 val emuPerfCntList = Map( 797 // "Mcycle" -> (0x1000, "perfCntCondMcycle" ), 798 // "Minstret" -> (0x1002, "perfCntCondMinstret" ), 799 "BpInstr" -> (0x1003, "perfCntCondBpInstr" ), 800 "BpRight" -> (0x1004, "perfCntCondBpRight" ), 801 "BpWrong" -> (0x1005, "perfCntCondBpWrong" ), 802 "BpBRight" -> (0x1006, "perfCntCondBpBRight"), 803 "BpBWrong" -> (0x1007, "perfCntCondBpBWrong"), 804 "BpJRight" -> (0x1008, "perfCntCondBpJRight"), 805 "BpJWrong" -> (0x1009, "perfCntCondBpJWrong"), 806 "BpIRight" -> (0x100a, "perfCntCondBpIRight"), 807 "BpIWrong" -> (0x100b, "perfCntCondBpIWrong"), 808 "BpRRight" -> (0x100c, "perfCntCondBpRRight"), 809 "BpRWrong" -> (0x100d, "perfCntCondBpRWrong"), 810 "RoqWalk" -> (0x100f, "perfCntCondRoqWalk" ), 811 "DTlbReqCnt0" -> (0x1015, "perfCntDtlbReqCnt0" ), 812 "DTlbReqCnt1" -> (0x1016, "perfCntDtlbReqCnt1" ), 813 "DTlbReqCnt2" -> (0x1017, "perfCntDtlbReqCnt2" ), 814 "DTlbReqCnt3" -> (0x1018, "perfCntDtlbReqCnt3" ), 815 "DTlbMissCnt0"-> (0x1019, "perfCntDtlbMissCnt0" ), 816 "DTlbMissCnt1"-> (0x1020, "perfCntDtlbMissCnt1" ), 817 "DTlbMissCnt2"-> (0x1021, "perfCntDtlbMissCnt2" ), 818 "DTlbMissCnt3"-> (0x1022, "perfCntDtlbMissCnt3" ), 819 "ITlbReqCnt0" -> (0x1023, "perfCntItlbReqCnt0" ), 820 "ITlbMissCnt0"-> (0x1024, "perfCntItlbMissCnt0" ), 821 "PtwReqCnt" -> (0x1025, "perfCntPtwReqCnt" ), 822 "PtwCycleCnt" -> (0x1026, "perfCntPtwCycleCnt" ), 823 "PtwL2TlbHit" -> (0x1027, "perfCntPtwL2TlbHit" ), 824 "ICacheReq" -> (0x1028, "perfCntIcacheReqCnt" ), 825 "ICacheMiss" -> (0x1029, "perfCntIcacheMissCnt"), 826 "ICacheMMIO" -> (0x102a, "perfCntIcacheMMIOCnt"), 827 // "FetchFromLoopBuffer" -> (0x102b, "CntFetchFromLoopBuffer"), 828 // "ExitLoop1" -> (0x102c, "CntExitLoop1"), 829 // "ExitLoop2" -> (0x102d, "CntExitLoop2"), 830 // "ExitLoop3" -> (0x102e, "CntExitLoop3") 831 832 "ubtbRight" -> (0x1030, "perfCntubtbRight"), 833 "ubtbWrong" -> (0x1031, "perfCntubtbWrong"), 834 "btbRight" -> (0x1032, "perfCntbtbRight"), 835 "btbWrong" -> (0x1033, "perfCntbtbWrong"), 836 "tageRight" -> (0x1034, "perfCnttageRight"), 837 "tageWrong" -> (0x1035, "perfCnttageWrong"), 838 "rasRight" -> (0x1036, "perfCntrasRight"), 839 "rasWrong" -> (0x1037, "perfCntrasWrong"), 840 "loopRight" -> (0x1038, "perfCntloopRight"), 841 "loopWrong" -> (0x1039, "perfCntloopWrong"), 842 "s1Right" -> (0x103a, "perfCntS1Right"), 843 "s1Wrong" -> (0x103b, "perfCntS1Wrong"), 844 "s2Right" -> (0x103c, "perfCntS2Right"), 845 "s2Wrong" -> (0x103d, "perfCntS2Wrong"), 846 "s3Right" -> (0x103e, "perfCntS3Right"), 847 "s3Wrong" -> (0x103f, "perfCntS3Wrong"), 848 "takenAndRight" -> (0x1040, "perfCntTakenAndRight"), 849 "takenButWrong" -> (0x1041, "perfCntTakenButWrong"), 850 // "L2cacheHit" -> (0x1023, "perfCntCondL2cacheHit") 851 ) ++ ( 852 (0 until dcacheParameters.nMissEntries).map(i => 853 ("DCacheMissQueuePenalty" + Integer.toString(i, 10), (0x1042 + i, "perfCntDCacheMissQueuePenaltyEntry" + Integer.toString(i, 10))) 854 ).toMap 855 ) ++ ( 856 (0 until icacheParameters.nMissEntries).map(i => 857 ("ICacheMissQueuePenalty" + Integer.toString(i, 10), (0x1042 + dcacheParameters.nMissEntries + i, "perfCntICacheMissQueuePenaltyEntry" + Integer.toString(i, 10))) 858 ).toMap 859 ) ++ ( 860 (0 until l1plusPrefetcherParameters.nEntries).map(i => 861 ("L1+PrefetchPenalty" + Integer.toString(i, 10), (0x1042 + dcacheParameters.nMissEntries + icacheParameters.nMissEntries + i, "perfCntL1plusPrefetchPenaltyEntry" + Integer.toString(i, 10))) 862 ).toMap 863 ) ++ ( 864 (0 until l2PrefetcherParameters.nEntries).map(i => 865 ("L2PrefetchPenalty" + Integer.toString(i, 10), (0x1042 + dcacheParameters.nMissEntries + icacheParameters.nMissEntries + l1plusPrefetcherParameters.nEntries + i, "perfCntL2PrefetchPenaltyEntry" + Integer.toString(i, 10))) 866 ).toMap 867 ) 868 869 emuPerfCntList.foreach { 870 case (_, (address, boringId)) => 871 if (hasEmuPerfCnt) { 872 ExcitingUtils.addSink(emuPerfCntCond(address & 0x7f), boringId, ConnectionType.Perf) 873 } 874 // if (!hasEmuPerfCnt) { 875 // // do not enable perfcnts except for Mcycle and Minstret 876 // if (address != emuPerfCntList("Mcycle")._1 && address != emuPerfCntList("Minstret")._1) { 877 // perfCntCond(address & 0x7f) := false.B 878 // } 879 // } 880 } 881 882 val xstrap = WireInit(false.B) 883 if (!env.FPGAPlatform && EnableBPU) { 884 ExcitingUtils.addSink(xstrap, "XSTRAP", ConnectionType.Debug) 885 } 886 def readWithScala(addr: Int): UInt = mapping(addr)._1 887 888 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 889 890 if (!env.FPGAPlatform) { 891 892 // display all perfcnt when nooptrap is executed 893 when (xstrap) { 894 printf("======== PerfCnt =========\n") 895 emuPerfCntList.toSeq.sortBy(_._2._1).foreach { case (str, (address, _)) => 896 printf("%d <- " + str + "\n", readWithScala(address)) 897 } 898 } 899 900 ExcitingUtils.addSource(difftestIntrNO, "difftestIntrNOfromCSR") 901 ExcitingUtils.addSource(causeNO, "difftestCausefromCSR") 902 ExcitingUtils.addSource(priviledgeMode, "difftestMode", Debug) 903 ExcitingUtils.addSource(mstatus, "difftestMstatus", Debug) 904 ExcitingUtils.addSource(mstatus & sstatusRmask, "difftestSstatus", Debug) 905 ExcitingUtils.addSource(mepc, "difftestMepc", Debug) 906 ExcitingUtils.addSource(sepc, "difftestSepc", Debug) 907 ExcitingUtils.addSource(mtval, "difftestMtval", Debug) 908 ExcitingUtils.addSource(stval, "difftestStval", Debug) 909 ExcitingUtils.addSource(mtvec, "difftestMtvec", Debug) 910 ExcitingUtils.addSource(stvec, "difftestStvec", Debug) 911 ExcitingUtils.addSource(mcause, "difftestMcause", Debug) 912 ExcitingUtils.addSource(scause, "difftestScause", Debug) 913 ExcitingUtils.addSource(satp, "difftestSatp", Debug) 914 ExcitingUtils.addSource(mipReg, "difftestMip", Debug) 915 ExcitingUtils.addSource(mie, "difftestMie", Debug) 916 ExcitingUtils.addSource(mscratch, "difftestMscratch", Debug) 917 ExcitingUtils.addSource(sscratch, "difftestSscratch", Debug) 918 ExcitingUtils.addSource(mideleg, "difftestMideleg", Debug) 919 ExcitingUtils.addSource(medeleg, "difftestMedeleg", Debug) 920 } 921 922 if (env.DualCoreDifftest) { 923 difftestIO.intrNO := RegNext(difftestIntrNO) 924 difftestIO.cause := RegNext(causeNO) 925 difftestIO.priviledgeMode := priviledgeMode 926 difftestIO.mstatus := mstatus 927 difftestIO.sstatus := mstatus & sstatusRmask 928 difftestIO.mepc := mepc 929 difftestIO.sepc := sepc 930 difftestIO.mtval:= mtval 931 difftestIO.stval:= stval 932 difftestIO.mtvec := mtvec 933 difftestIO.stvec := stvec 934 difftestIO.mcause := mcause 935 difftestIO.scause := scause 936 difftestIO.satp := satp 937 difftestIO.mip := mipReg 938 difftestIO.mie := mie 939 difftestIO.mscratch := mscratch 940 difftestIO.sscratch := sscratch 941 difftestIO.mideleg := mideleg 942 difftestIO.medeleg := medeleg 943 } 944} 945