xref: /XiangShan/src/main/scala/xiangshan/backend/fu/CSR.scala (revision d8a66f7ecacc2b3538a1083b0716b7066c77ba3f)
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