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