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