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._ 10 11object hartId extends (() => Int) { 12 var x = 0 13 def apply(): Int = { 14 x = x + 1 15 x-1 16 } 17} 18 19trait HasExceptionNO { 20 def instrAddrMisaligned = 0 21 def instrAccessFault = 1 22 def illegalInstr = 2 23 def breakPoint = 3 24 def loadAddrMisaligned = 4 25 def loadAccessFault = 5 26 def storeAddrMisaligned = 6 27 def storeAccessFault = 7 28 def ecallU = 8 29 def ecallS = 9 30 def ecallM = 11 31 def instrPageFault = 12 32 def loadPageFault = 13 33 def storePageFault = 15 34 35 val ExcPriority = Seq( 36 breakPoint, // TODO: different BP has different priority 37 instrPageFault, 38 instrAccessFault, 39 illegalInstr, 40 instrAddrMisaligned, 41 ecallM, ecallS, ecallU, 42 storePageFault, 43 loadPageFault, 44 storeAccessFault, 45 loadAccessFault, 46 storeAddrMisaligned, 47 loadAddrMisaligned 48 ) 49 val frontendSet = List( 50 // instrAddrMisaligned, 51 instrAccessFault, 52 illegalInstr, 53 instrPageFault 54 ) 55 val csrSet = List( 56 illegalInstr, 57 breakPoint, 58 ecallU, 59 ecallS, 60 ecallM 61 ) 62 val loadUnitSet = List( 63 loadAddrMisaligned, 64 loadAccessFault, 65 loadPageFault 66 ) 67 val storeUnitSet = List( 68 storeAddrMisaligned, 69 storeAccessFault, 70 storePageFault 71 ) 72 val atomicsUnitSet = (loadUnitSet ++ storeUnitSet).distinct 73 val allPossibleSet = (frontendSet ++ csrSet ++ loadUnitSet ++ storeUnitSet).distinct 74 val csrWbCount = (0 until 16).map(i => if (csrSet.contains(i)) 1 else 0) 75 val loadWbCount = (0 until 16).map(i => if (loadUnitSet.contains(i)) 1 else 0) 76 val storeWbCount = (0 until 16).map(i => if (storeUnitSet.contains(i)) 1 else 0) 77 val atomicsWbCount = (0 until 16).map(i => if (atomicsUnitSet.contains(i)) 1 else 0) 78 val writebackCount = (0 until 16).map(i => csrWbCount(i) + atomicsWbCount(i) + loadWbCount(i) + 2 * storeWbCount(i)) 79 def partialSelect(vec: Vec[Bool], select: Seq[Int], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = { 80 if (dontCareBits) { 81 val new_vec = Wire(ExceptionVec()) 82 new_vec := DontCare 83 select.map(i => new_vec(i) := vec(i)) 84 return new_vec 85 } 86 else if (falseBits) { 87 val new_vec = Wire(ExceptionVec()) 88 new_vec.map(_ := false.B) 89 select.map(i => new_vec(i) := vec(i)) 90 return new_vec 91 } 92 else { 93 val new_vec = Wire(Vec(select.length, Bool())) 94 select.zipWithIndex.map{ case(s, i) => new_vec(i) := vec(s) } 95 return new_vec 96 } 97 } 98 def selectFrontend(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 99 partialSelect(vec, frontendSet, dontCareBits, falseBits) 100 def selectCSR(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 101 partialSelect(vec, csrSet, dontCareBits, falseBits) 102 def selectLoad(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 103 partialSelect(vec, loadUnitSet, dontCareBits, falseBits) 104 def selectStore(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 105 partialSelect(vec, storeUnitSet, dontCareBits, falseBits) 106 def selectAtomics(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 107 partialSelect(vec, atomicsUnitSet, dontCareBits, falseBits) 108 def selectAll(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 109 partialSelect(vec, allPossibleSet, dontCareBits, falseBits) 110} 111 112class FpuCsrIO extends XSBundle { 113 val fflags = Output(Valid(UInt(5.W))) 114 val isIllegal = Output(Bool()) 115 val dirty_fs = Output(Bool()) 116 val frm = Input(UInt(3.W)) 117} 118 119 120class PerfCounterIO extends XSBundle { 121 val retiredInstr = Input(UInt(3.W)) 122 val value = Input(UInt(XLEN.W)) 123} 124 125class CSR extends FunctionUnit with HasCSRConst 126{ 127 val csrio = IO(new Bundle { 128 // output (for func === CSROpType.jmp) 129 val perf = new PerfCounterIO 130 val isPerfCnt = Output(Bool()) 131 // to FPU 132 val fpu = Flipped(new FpuCsrIO) 133 // from rob 134 val exception = Flipped(ValidIO(new ExceptionInfo)) 135 // to ROB 136 val isXRet = Output(Bool()) 137 val trapTarget = Output(UInt(VAddrBits.W)) 138 val interrupt = Output(Bool()) 139 // from LSQ 140 val memExceptionVAddr = Input(UInt(VAddrBits.W)) 141 // from outside cpu,externalInterrupt 142 val externalInterrupt = new ExternalInterruptIO 143 // TLB 144 val tlb = Output(new TlbCsrBundle) 145 }) 146 val difftestIO = IO(new Bundle() { 147 val intrNO = Output(UInt(64.W)) 148 val cause = Output(UInt(64.W)) 149 val priviledgeMode = Output(UInt(2.W)) 150 val mstatus = Output(UInt(64.W)) 151 val sstatus = Output(UInt(64.W)) 152 val mepc = Output(UInt(64.W)) 153 val sepc = Output(UInt(64.W)) 154 val mtval = Output(UInt(64.W)) 155 val stval = Output(UInt(64.W)) 156 val mtvec = Output(UInt(64.W)) 157 val stvec = Output(UInt(64.W)) 158 val mcause = Output(UInt(64.W)) 159 val scause = Output(UInt(64.W)) 160 val satp = Output(UInt(64.W)) 161 val mip = Output(UInt(64.W)) 162 val mie = Output(UInt(64.W)) 163 val mscratch = Output(UInt(64.W)) 164 val sscratch = Output(UInt(64.W)) 165 val mideleg = Output(UInt(64.W)) 166 val medeleg = Output(UInt(64.W)) 167 }) 168 difftestIO <> DontCare 169 170 val cfIn = io.in.bits.uop.cf 171 val cfOut = Wire(new CtrlFlow) 172 cfOut := cfIn 173 val flushPipe = Wire(Bool()) 174 175 val (valid, src1, src2, func) = ( 176 io.in.valid, 177 io.in.bits.src(0), 178 io.in.bits.uop.ctrl.imm, 179 io.in.bits.uop.ctrl.fuOpType 180 ) 181 182 // CSR define 183 184 class Priv extends Bundle { 185 val m = Output(Bool()) 186 val h = Output(Bool()) 187 val s = Output(Bool()) 188 val u = Output(Bool()) 189 } 190 191 val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U) 192 193 class MstatusStruct extends Bundle { 194 val sd = Output(UInt(1.W)) 195 196 val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null 197 val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 198 val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 199 val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 200 201 val tsr = Output(UInt(1.W)) 202 val tw = Output(UInt(1.W)) 203 val tvm = Output(UInt(1.W)) 204 val mxr = Output(UInt(1.W)) 205 val sum = Output(UInt(1.W)) 206 val mprv = Output(UInt(1.W)) 207 val xs = Output(UInt(2.W)) 208 val fs = Output(UInt(2.W)) 209 val mpp = Output(UInt(2.W)) 210 val hpp = Output(UInt(2.W)) 211 val spp = Output(UInt(1.W)) 212 val pie = new Priv 213 val ie = new Priv 214 assert(this.getWidth == XLEN) 215 } 216 217 class SatpStruct extends Bundle { 218 val mode = UInt(4.W) 219 val asid = UInt(16.W) 220 val ppn = UInt(44.W) 221 } 222 223 class Interrupt extends Bundle { 224 val e = new Priv 225 val t = new Priv 226 val s = new Priv 227 } 228 229 // Machine-Level CSRs 230 231 val mtvec = RegInit(UInt(XLEN.W), 0.U) 232 val mcounteren = RegInit(UInt(XLEN.W), 0.U) 233 val mcause = RegInit(UInt(XLEN.W), 0.U) 234 val mtval = RegInit(UInt(XLEN.W), 0.U) 235 val mepc = Reg(UInt(XLEN.W)) 236 237 val mie = RegInit(0.U(XLEN.W)) 238 val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 239 val mipReg = RegInit(0.U.asTypeOf(new Interrupt).asUInt) 240 val mipFixMask = GenMask(9) | GenMask(5) | GenMask(1) 241 val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 242 243 def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt() 244 def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt() 245 var extList = List('a', 's', 'i', 'u') 246 if (HasMExtension) { extList = extList :+ 'm' } 247 if (HasCExtension) { extList = extList :+ 'c' } 248 if (HasFPU) { extList = extList ++ List('f', 'd') } 249 val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U 250 val misa = RegInit(UInt(XLEN.W), misaInitVal) 251 252 // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 253 // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 254 255 val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 256 val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented 257 val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 258 val mhartNo = hartId() 259 val mhartid = RegInit(UInt(XLEN.W), mhartNo.asUInt) // the hardware thread running the code 260 val mstatus = RegInit(UInt(XLEN.W), 0.U) 261 262 // mstatus Value Table 263 // | sd | 264 // | pad1 | 265 // | sxl | hardlinked to 10, use 00 to pass xv6 test 266 // | uxl | hardlinked to 00 267 // | pad0 | 268 // | tsr | 269 // | tw | 270 // | tvm | 271 // | mxr | 272 // | sum | 273 // | mprv | 274 // | xs | 00 | 275 // | fs | 00 | 276 // | mpp | 00 | 277 // | hpp | 00 | 278 // | spp | 0 | 279 // | pie | 0000 | pie.h is used as UBE 280 // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 281 282 val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 283 def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 284 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 285 val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 286 mstatusNew 287 } 288 289 val mstatusMask = (~ZeroExt(( 290 GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) | 291 GenMask(37) | // MBE 292 GenMask(36) | // SBE 293 GenMask(6) // UBE 294 ), 64)).asUInt() 295 296 val medeleg = RegInit(UInt(XLEN.W), 0.U) 297 val mideleg = RegInit(UInt(XLEN.W), 0.U) 298 val mscratch = RegInit(UInt(XLEN.W), 0.U) 299 300 val pmpcfg0 = RegInit(UInt(XLEN.W), 0.U) 301 val pmpcfg1 = RegInit(UInt(XLEN.W), 0.U) 302 val pmpcfg2 = RegInit(UInt(XLEN.W), 0.U) 303 val pmpcfg3 = RegInit(UInt(XLEN.W), 0.U) 304 val pmpaddr0 = RegInit(UInt(XLEN.W), 0.U) 305 val pmpaddr1 = RegInit(UInt(XLEN.W), 0.U) 306 val pmpaddr2 = RegInit(UInt(XLEN.W), 0.U) 307 val pmpaddr3 = RegInit(UInt(XLEN.W), 0.U) 308 309 // Superviser-Level CSRs 310 311 // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 312 val sstatusWmask = "hc6122".U 313 // Sstatus Write Mask 314 // ------------------------------------------------------- 315 // 19 9 5 2 316 // 0 1100 0000 0001 0010 0010 317 // 0 c 0 1 2 2 318 // ------------------------------------------------------- 319 val sstatusRmask = sstatusWmask | "h8000000300018000".U 320 // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 321 val stvec = RegInit(UInt(XLEN.W), 0.U) 322 // val sie = RegInit(0.U(XLEN.W)) 323 val sieMask = "h222".U & mideleg 324 val sipMask = "h222".U & mideleg 325 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 326 // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 327 val satpMask = "h80000fffffffffff".U // disable asid, mode can only be 8 / 0 328 val sepc = RegInit(UInt(XLEN.W), 0.U) 329 val scause = RegInit(UInt(XLEN.W), 0.U) 330 val stval = Reg(UInt(XLEN.W)) 331 val sscratch = RegInit(UInt(XLEN.W), 0.U) 332 val scounteren = RegInit(UInt(XLEN.W), 0.U) 333 334 val tlbBundle = Wire(new TlbCsrBundle) 335 tlbBundle.satp := satp.asTypeOf(new SatpStruct) 336 csrio.tlb := tlbBundle 337 338 // User-Level CSRs 339 val uepc = Reg(UInt(XLEN.W)) 340 341 // fcsr 342 class FcsrStruct extends Bundle { 343 val reserved = UInt((XLEN-3-5).W) 344 val frm = UInt(3.W) 345 val fflags = UInt(5.W) 346 assert(this.getWidth == XLEN) 347 } 348 val fcsr = RegInit(0.U(XLEN.W)) 349 // set mstatus->sd and mstatus->fs when true 350 val csrw_dirty_fp_state = WireInit(false.B) 351 352 def frm_wfn(wdata: UInt): UInt = { 353 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 354 csrw_dirty_fp_state := true.B 355 fcsrOld.frm := wdata(2,0) 356 fcsrOld.asUInt() 357 } 358 def frm_rfn(rdata: UInt): UInt = rdata(7,5) 359 360 def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 361 val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 362 val fcsrNew = WireInit(fcsrOld) 363 csrw_dirty_fp_state := true.B 364 if (update) { 365 fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 366 } else { 367 fcsrNew.fflags := wdata(4,0) 368 } 369 fcsrNew.asUInt() 370 } 371 def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 372 373 def fcsr_wfn(wdata: UInt): UInt = { 374 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 375 csrw_dirty_fp_state := true.B 376 Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 377 } 378 379 val fcsrMapping = Map( 380 MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 381 MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 382 MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 383 ) 384 385 // Atom LR/SC Control Bits 386 // val setLr = WireInit(Bool(), false.B) 387 // val setLrVal = WireInit(Bool(), false.B) 388 // val setLrAddr = WireInit(UInt(AddrBits.W), DontCare) //TODO : need check 389 // val lr = RegInit(Bool(), false.B) 390 // val lrAddr = RegInit(UInt(AddrBits.W), 0.U) 391 // 392 // when (setLr) { 393 // lr := setLrVal 394 // lrAddr := setLrAddr 395 // } 396 397 // Hart Priviledge Mode 398 val priviledgeMode = RegInit(UInt(2.W), ModeM) 399 400 // Emu perfcnt 401 val hasEmuPerfCnt = !env.FPGAPlatform 402 val nrEmuPerfCnts = if (hasEmuPerfCnt) 0x80 else 0x3 403 404 val emuPerfCnts = List.fill(nrEmuPerfCnts)(RegInit(0.U(XLEN.W))) 405 val emuPerfCntCond = List.fill(nrEmuPerfCnts)(WireInit(false.B)) 406 (emuPerfCnts zip emuPerfCntCond).map { case (c, e) => when (e) { c := c + 1.U } } 407 408 val emuPerfCntsLoMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1000 + i, emuPerfCnts(i))) 409 val emuPerfCntsHiMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1080 + i, emuPerfCnts(i)(63, 32))) 410 println(s"CSR: hasEmuPerfCnt:${hasEmuPerfCnt}") 411 412 // Perf Counter 413 val nrPerfCnts = 29 // 3...31 414 val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 415 val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 416 val mcountinhibit = RegInit(0.U(XLEN.W)) 417 val mcycle = RegInit(0.U(XLEN.W)) 418 mcycle := mcycle + 1.U 419 val minstret = RegInit(0.U(XLEN.W)) 420 minstret := minstret + RegNext(csrio.perf.retiredInstr) 421 422 // CSR reg map 423 val basicPrivMapping = Map( 424 425 //--- User Trap Setup --- 426 // MaskedRegMap(Ustatus, ustatus), 427 // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 428 // MaskedRegMap(Utvec, utvec), 429 430 //--- User Trap Handling --- 431 // MaskedRegMap(Uscratch, uscratch), 432 // MaskedRegMap(Uepc, uepc), 433 // MaskedRegMap(Ucause, ucause), 434 // MaskedRegMap(Utval, utval), 435 // MaskedRegMap(Uip, uip), 436 437 //--- User Counter/Timers --- 438 // MaskedRegMap(Cycle, cycle), 439 // MaskedRegMap(Time, time), 440 // MaskedRegMap(Instret, instret), 441 442 //--- Supervisor Trap Setup --- 443 MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 444 // MaskedRegMap(Sedeleg, Sedeleg), 445 // MaskedRegMap(Sideleg, Sideleg), 446 MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 447 MaskedRegMap(Stvec, stvec), 448 MaskedRegMap(Scounteren, scounteren), 449 450 //--- Supervisor Trap Handling --- 451 MaskedRegMap(Sscratch, sscratch), 452 MaskedRegMap(Sepc, sepc), 453 MaskedRegMap(Scause, scause), 454 MaskedRegMap(Stval, stval), 455 MaskedRegMap(Sip, mip.asUInt, sipMask, MaskedRegMap.Unwritable, sipMask), 456 457 //--- Supervisor Protection and Translation --- 458 MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 459 460 //--- Machine Information Registers --- 461 MaskedRegMap(Mvendorid, mvendorid, 0.U, MaskedRegMap.Unwritable), 462 MaskedRegMap(Marchid, marchid, 0.U, MaskedRegMap.Unwritable), 463 MaskedRegMap(Mimpid, mimpid, 0.U, MaskedRegMap.Unwritable), 464 MaskedRegMap(Mhartid, mhartid, 0.U, MaskedRegMap.Unwritable), 465 466 //--- Machine Trap Setup --- 467 MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask), 468 MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 469 MaskedRegMap(Medeleg, medeleg, "hf3ff".U), 470 MaskedRegMap(Mideleg, mideleg, "h222".U), 471 MaskedRegMap(Mie, mie), 472 MaskedRegMap(Mtvec, mtvec), 473 MaskedRegMap(Mcounteren, mcounteren), 474 475 //--- Machine Trap Handling --- 476 MaskedRegMap(Mscratch, mscratch), 477 MaskedRegMap(Mepc, mepc), 478 MaskedRegMap(Mcause, mcause), 479 MaskedRegMap(Mtval, mtval), 480 MaskedRegMap(Mip, mip.asUInt, 0.U, MaskedRegMap.Unwritable), 481 ) 482 483 // PMP is unimplemented yet 484 val pmpMapping = Map( 485 MaskedRegMap(Pmpcfg0, pmpcfg0), 486 MaskedRegMap(Pmpcfg1, pmpcfg1), 487 MaskedRegMap(Pmpcfg2, pmpcfg2), 488 MaskedRegMap(Pmpcfg3, pmpcfg3), 489 MaskedRegMap(PmpaddrBase + 0, pmpaddr0), 490 MaskedRegMap(PmpaddrBase + 1, pmpaddr1), 491 MaskedRegMap(PmpaddrBase + 2, pmpaddr2), 492 MaskedRegMap(PmpaddrBase + 3, pmpaddr3) 493 ) 494 495 var perfCntMapping = Map( 496 MaskedRegMap(Mcountinhibit, mcountinhibit), 497 MaskedRegMap(Mcycle, mcycle), 498 MaskedRegMap(Minstret, minstret), 499 ) 500 val MhpmcounterStart = Mhpmcounter3 501 val MhpmeventStart = Mhpmevent3 502 for (i <- 0 until nrPerfCnts) { 503 perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 504 perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 505 } 506 507 val mapping = basicPrivMapping ++ 508 perfCntMapping ++ 509 pmpMapping ++ 510 emuPerfCntsLoMapping ++ 511 (if (XLEN == 32) emuPerfCntsHiMapping else Nil) ++ 512 (if (HasFPU) fcsrMapping else Nil) 513 514 val addr = src2(11, 0) 515 val csri = ZeroExt(src2(16, 12), XLEN) 516 val rdata = Wire(UInt(XLEN.W)) 517 val wdata = LookupTree(func, List( 518 CSROpType.wrt -> src1, 519 CSROpType.set -> (rdata | src1), 520 CSROpType.clr -> (rdata & (~src1).asUInt()), 521 CSROpType.wrti -> csri, 522 CSROpType.seti -> (rdata | csri), 523 CSROpType.clri -> (rdata & (~csri).asUInt()) 524 )) 525 526 val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) 527 csrio.isPerfCnt := addrInPerfCnt 528 529 // satp wen check 530 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 531 532 // general CSR wen check 533 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 534 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 535 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 536 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) 537 // Writeable check is ingored. 538 // Currently, write to illegal csr addr will be ignored 539 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 540 io.out.bits.data := rdata 541 io.out.bits.uop := io.in.bits.uop 542 io.out.bits.uop.cf := cfOut 543 io.out.bits.uop.ctrl.flushPipe := flushPipe 544 545 // Fix Mip/Sip write 546 val fixMapping = Map( 547 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 548 MaskedRegMap(Sip, mipReg.asUInt, sipMask, MaskedRegMap.NoSideEffect, sipMask) 549 ) 550 val rdataDummy = Wire(UInt(XLEN.W)) 551 MaskedRegMap.generate(fixMapping, addr, rdataDummy, wen, wdata) 552 553 when (csrio.fpu.fflags.valid) { 554 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 555 } 556 // set fs and sd in mstatus 557 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 558 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 559 mstatusNew.fs := "b11".U 560 mstatusNew.sd := true.B 561 mstatus := mstatusNew.asUInt() 562 } 563 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 564 565 // CSR inst decode 566 val isEbreak = addr === privEbreak && func === CSROpType.jmp 567 val isEcall = addr === privEcall && func === CSROpType.jmp 568 val isMret = addr === privMret && func === CSROpType.jmp 569 val isSret = addr === privSret && func === CSROpType.jmp 570 val isUret = addr === privUret && func === CSROpType.jmp 571 572 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 573 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 574 575 // Illegal priviledged operation list 576 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 577 578 // Illegal priviledged instruction check 579 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 580 val isIllegalAccess = !permitted 581 val isIllegalPrivOp = illegalSModeSret 582 583 // def MMUPermissionCheck(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) 584 // def MMUPermissionCheckLoad(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) && (pter || (mstatusStruct.mxr && ptex)) 585 // imem 586 // val imemPtev = true.B 587 // val imemPteu = true.B 588 // val imemPtex = true.B 589 // val imemReq = true.B 590 // val imemPermissionCheckPassed = MMUPermissionCheck(imemPtev, imemPteu) 591 // val hasInstrPageFault = imemReq && !(imemPermissionCheckPassed && imemPtex) 592 // assert(!hasInstrPageFault) 593 594 // dmem 595 // val dmemPtev = true.B 596 // val dmemPteu = true.B 597 // val dmemReq = true.B 598 // val dmemPermissionCheckPassed = MMUPermissionCheck(dmemPtev, dmemPteu) 599 // val dmemIsStore = true.B 600 601 // val hasLoadPageFault = dmemReq && !dmemIsStore && !(dmemPermissionCheckPassed) 602 // val hasStorePageFault = dmemReq && dmemIsStore && !(dmemPermissionCheckPassed) 603 // assert(!hasLoadPageFault) 604 // assert(!hasStorePageFault) 605 606 //TODO: Havn't test if io.dmemMMU.priviledgeMode is correct yet 607 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 608 tlbBundle.priv.sum := mstatusStruct.sum.asBool 609 tlbBundle.priv.imode := priviledgeMode 610 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 611 612 // Branch control 613 val retTarget = Wire(UInt(VAddrBits.W)) 614 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 615 flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall) 616 617 retTarget := DontCare 618 // val illegalEret = TODO 619 620 when (valid && isMret) { 621 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 622 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 623 mstatusNew.ie.m := mstatusOld.pie.m 624 priviledgeMode := mstatusOld.mpp 625 mstatusNew.pie.m := true.B 626 mstatusNew.mpp := ModeU 627 mstatusNew.mprv := 0.U 628 mstatus := mstatusNew.asUInt 629 // lr := false.B 630 retTarget := mepc(VAddrBits-1, 0) 631 } 632 633 when (valid && isSret && !illegalSModeSret) { 634 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 635 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 636 mstatusNew.ie.s := mstatusOld.pie.s 637 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 638 mstatusNew.pie.s := true.B 639 mstatusNew.spp := ModeU 640 mstatus := mstatusNew.asUInt 641 mstatusNew.mprv := 0.U 642 // lr := false.B 643 retTarget := sepc(VAddrBits-1, 0) 644 } 645 646 when (valid && isUret) { 647 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 648 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 649 // mstatusNew.mpp.m := ModeU //TODO: add mode U 650 mstatusNew.ie.u := mstatusOld.pie.u 651 priviledgeMode := ModeU 652 mstatusNew.pie.u := true.B 653 mstatus := mstatusNew.asUInt 654 retTarget := uepc(VAddrBits-1, 0) 655 } 656 657 io.in.ready := true.B 658 io.out.valid := valid 659 660 val csrExceptionVec = WireInit(cfIn.exceptionVec) 661 csrExceptionVec(breakPoint) := io.in.valid && isEbreak 662 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 663 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 664 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 665 // Trigger an illegal instr exception when: 666 // * unimplemented csr is being read/written 667 // * csr access is illegal 668 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 669 cfOut.exceptionVec := csrExceptionVec 670 671 /** 672 * Exception and Intr 673 */ 674 val ideleg = (mideleg & mip.asUInt) 675 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 676 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 677 678 // send interrupt information to ROQ 679 val intrVecEnable = Wire(Vec(12, Bool())) 680 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 681 val intrVec = mie(11,0) & mip.asUInt & intrVecEnable.asUInt 682 val intrBitSet = intrVec.orR() 683 csrio.interrupt := intrBitSet 684 mipWire.t.m := csrio.externalInterrupt.mtip 685 mipWire.s.m := csrio.externalInterrupt.msip 686 mipWire.e.m := csrio.externalInterrupt.meip 687 688 // interrupts 689 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 690 val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 691 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO) 692 693 // exceptions 694 val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 695 val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 696 val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 697 val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 698 val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 699 val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 700 val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 701 val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 702 val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 703 704 val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 705 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 706 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 707 708 val raiseExceptionIntr = csrio.exception.valid 709 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 710 csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 711 ) 712 XSDebug(raiseExceptionIntr, 713 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 714 csrio.exception.bits.uop.cf.pc, 715 mstatus, 716 mideleg, 717 medeleg, 718 priviledgeMode 719 ) 720 721 // mtval write logic 722 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 723 when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) { 724 val tval = Mux( 725 hasInstrPageFault, 726 Mux( 727 csrio.exception.bits.uop.cf.crossPageIPFFix, 728 SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 729 SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 730 ), 731 memExceptionAddr 732 ) 733 when (priviledgeMode === ModeM) { 734 mtval := tval 735 }.otherwise { 736 stval := tval 737 } 738 } 739 740 when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) { 741 mtval := memExceptionAddr 742 } 743 744 val deleg = Mux(raiseIntr, mideleg , medeleg) 745 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 746 val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 747 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 748 val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall 749 750 // ctrl block will use theses later for flush 751 val isXRetFlag = RegInit(false.B) 752 val retTargetReg = Reg(retTarget.cloneType) 753 when (io.flushIn) { 754 isXRetFlag := false.B 755 }.elsewhen (isXRet) { 756 isXRetFlag := true.B 757 retTargetReg := retTarget 758 } 759 csrio.isXRet := isXRetFlag 760 csrio.trapTarget := Mux(isXRetFlag, 761 retTargetReg, 762 Mux(delegS, stvec, mtvec)(VAddrBits-1, 0) 763 ) 764 765 when (raiseExceptionIntr) { 766 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 767 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 768 769 when (delegS) { 770 scause := causeNO 771 sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 772 mstatusNew.spp := priviledgeMode 773 mstatusNew.pie.s := mstatusOld.ie.s 774 mstatusNew.ie.s := false.B 775 priviledgeMode := ModeS 776 when (tvalWen) { stval := 0.U } 777 }.otherwise { 778 mcause := causeNO 779 mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 780 mstatusNew.mpp := priviledgeMode 781 mstatusNew.pie.m := mstatusOld.ie.m 782 mstatusNew.ie.m := false.B 783 priviledgeMode := ModeM 784 when (tvalWen) { mtval := 0.U } 785 } 786 787 mstatus := mstatusNew.asUInt 788 } 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(Mux(csrio.exception.valid, causeNO, 0.U), "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