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