xref: /XiangShan/src/main/scala/xiangshan/backend/fu/CSR.scala (revision 53c7ab8b2e79de0fa70909ea81a51720f666aaeb)
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 perf = new PerfCounterIO
131    val isPerfCnt = Output(Bool())
132    // to FPU
133    val fpu = Flipped(new FpuCsrIO)
134    // from rob
135    val exception = Flipped(ValidIO(new RoqExceptionInfo))
136    // to ROB
137    val isXRet = Output(Bool())
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  flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall)
617
618  retTarget := DontCare
619  // val illegalEret = TODO
620
621  when (valid && isMret) {
622    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
623    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
624    mstatusNew.ie.m := mstatusOld.pie.m
625    priviledgeMode := mstatusOld.mpp
626    mstatusNew.pie.m := true.B
627    mstatusNew.mpp := ModeU
628    mstatusNew.mprv := 0.U
629    mstatus := mstatusNew.asUInt
630    // lr := false.B
631    retTarget := mepc(VAddrBits-1, 0)
632  }
633
634  when (valid && isSret && !illegalSModeSret) {
635    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
636    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
637    mstatusNew.ie.s := mstatusOld.pie.s
638    priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
639    mstatusNew.pie.s := true.B
640    mstatusNew.spp := ModeU
641    mstatus := mstatusNew.asUInt
642    mstatusNew.mprv := 0.U
643    // lr := false.B
644    retTarget := sepc(VAddrBits-1, 0)
645  }
646
647  when (valid && isUret) {
648    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
649    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
650    // mstatusNew.mpp.m := ModeU //TODO: add mode U
651    mstatusNew.ie.u := mstatusOld.pie.u
652    priviledgeMode := ModeU
653    mstatusNew.pie.u := true.B
654    mstatus := mstatusNew.asUInt
655    retTarget := uepc(VAddrBits-1, 0)
656  }
657
658  io.in.ready := true.B
659  io.out.valid := valid
660
661  val csrExceptionVec = WireInit(cfIn.exceptionVec)
662  csrExceptionVec(breakPoint) := io.in.valid && isEbreak
663  csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
664  csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
665  csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
666  // Trigger an illegal instr exception when:
667  // * unimplemented csr is being read/written
668  // * csr access is illegal
669  csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
670  cfOut.exceptionVec := csrExceptionVec
671
672  /**
673    * Exception and Intr
674    */
675  val ideleg =  (mideleg & mip.asUInt)
676  def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS),
677    ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM))
678
679  // send interrupt information to ROQ
680  val intrVecEnable = Wire(Vec(12, Bool()))
681  intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)}
682  val intrVec = mie(11,0) & mip.asUInt & intrVecEnable.asUInt
683  val intrBitSet = intrVec.orR()
684  csrio.interrupt := intrBitSet
685  mipWire.t.m := csrio.externalInterrupt.mtip
686  mipWire.s.m := csrio.externalInterrupt.msip
687  mipWire.e.m := csrio.externalInterrupt.meip
688
689  // interrupts
690  val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
691  val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt
692  XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO)
693
694  // exceptions
695  val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt
696  val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException
697  val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException
698  val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException
699  val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException
700  val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException
701  val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException
702  val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException
703  val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException
704
705  val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec
706  val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
707  val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
708
709  val raiseExceptionIntr = csrio.exception.valid
710  XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
711    csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt
712  )
713  XSDebug(raiseExceptionIntr,
714    "pc %x mstatus %x mideleg %x medeleg %x mode %x\n",
715    csrio.exception.bits.uop.cf.pc,
716    mstatus,
717    mideleg,
718    medeleg,
719    priviledgeMode
720  )
721
722  // mtval write logic
723  val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
724  when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) {
725    val tval = Mux(
726      hasInstrPageFault,
727      Mux(
728        csrio.exception.bits.uop.cf.crossPageIPFFix,
729        SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN),
730        SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
731      ),
732      memExceptionAddr
733    )
734    when (priviledgeMode === ModeM) {
735      mtval := tval
736    }.otherwise {
737      stval := tval
738    }
739  }
740
741  when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) {
742    mtval := memExceptionAddr
743  }
744
745  val deleg = Mux(raiseIntr, mideleg , medeleg)
746  // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM);
747  val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM)
748  val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check
749  val isXRet = func === CSROpType.jmp && !isEcall
750  // ctrl block use these 2 cycles later
751  //  0          1       2
752  // XRet
753  //  wb  -> commit
754  //      -> flush -> frontend redirect
755  csrio.isXRet := RegNext(RegNext(isXRet))
756  csrio.trapTarget := Mux(RegNext(RegNext(isXRet)),
757    RegNext(RegNext(retTarget)),
758    Mux(delegS, stvec, mtvec)(VAddrBits-1, 0)
759  )
760
761  when (raiseExceptionIntr) {
762    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
763    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
764
765    when (delegS) {
766      scause := causeNO
767      sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
768      mstatusNew.spp := priviledgeMode
769      mstatusNew.pie.s := mstatusOld.ie.s
770      mstatusNew.ie.s := false.B
771      priviledgeMode := ModeS
772      when (tvalWen) { stval := 0.U }
773    }.otherwise {
774      mcause := causeNO
775      mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
776      mstatusNew.mpp := priviledgeMode
777      mstatusNew.pie.m := mstatusOld.ie.m
778      mstatusNew.ie.m := false.B
779      priviledgeMode := ModeM
780      when (tvalWen) { mtval := 0.U }
781    }
782
783    mstatus := mstatusNew.asUInt
784  }
785
786  XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc)
787
788
789  /**
790    * Emu Performance counters
791    */
792  val emuPerfCntList = Map(
793    // "Mcycle"    -> (0x1000, "perfCntCondMcycle"     ),
794    // "Minstret"  -> (0x1002, "perfCntCondMinstret"   ),
795    "BpInstr"     -> (0x1003, "perfCntCondBpInstr" ),
796    "BpRight"     -> (0x1004, "perfCntCondBpRight" ),
797    "BpWrong"     -> (0x1005, "perfCntCondBpWrong" ),
798    "BpBRight"    -> (0x1006, "perfCntCondBpBRight"),
799    "BpBWrong"    -> (0x1007, "perfCntCondBpBWrong"),
800    "BpJRight"    -> (0x1008, "perfCntCondBpJRight"),
801    "BpJWrong"    -> (0x1009, "perfCntCondBpJWrong"),
802    "BpIRight"    -> (0x100a, "perfCntCondBpIRight"),
803    "BpIWrong"    -> (0x100b, "perfCntCondBpIWrong"),
804    "BpRRight"    -> (0x100c, "perfCntCondBpRRight"),
805    "BpRWrong"    -> (0x100d, "perfCntCondBpRWrong"),
806    "RoqWalk"     -> (0x100f, "perfCntCondRoqWalk"  ),
807    "DTlbReqCnt0" -> (0x1015, "perfCntDtlbReqCnt0"  ),
808    "DTlbReqCnt1" -> (0x1016, "perfCntDtlbReqCnt1"  ),
809    "DTlbReqCnt2" -> (0x1017, "perfCntDtlbReqCnt2"  ),
810    "DTlbReqCnt3" -> (0x1018, "perfCntDtlbReqCnt3"  ),
811    "DTlbMissCnt0"-> (0x1019, "perfCntDtlbMissCnt0" ),
812    "DTlbMissCnt1"-> (0x1020, "perfCntDtlbMissCnt1" ),
813    "DTlbMissCnt2"-> (0x1021, "perfCntDtlbMissCnt2" ),
814    "DTlbMissCnt3"-> (0x1022, "perfCntDtlbMissCnt3" ),
815    "ITlbReqCnt0" -> (0x1023, "perfCntItlbReqCnt0"  ),
816    "ITlbMissCnt0"-> (0x1024, "perfCntItlbMissCnt0" ),
817    "PtwReqCnt"   -> (0x1025, "perfCntPtwReqCnt"    ),
818    "PtwCycleCnt" -> (0x1026, "perfCntPtwCycleCnt"  ),
819    "PtwL2TlbHit" -> (0x1027, "perfCntPtwL2TlbHit"  ),
820    "ICacheReq"   -> (0x1028, "perfCntIcacheReqCnt" ),
821    "ICacheMiss"  -> (0x1029, "perfCntIcacheMissCnt"),
822    "ICacheMMIO" -> (0x102a, "perfCntIcacheMMIOCnt"),
823    // "FetchFromLoopBuffer" -> (0x102b, "CntFetchFromLoopBuffer"),
824    // "ExitLoop1" -> (0x102c, "CntExitLoop1"),
825    // "ExitLoop2" -> (0x102d, "CntExitLoop2"),
826    // "ExitLoop3" -> (0x102e, "CntExitLoop3")
827
828    "ubtbRight"   -> (0x1030, "perfCntubtbRight"),
829    "ubtbWrong"   -> (0x1031, "perfCntubtbWrong"),
830    "btbRight"    -> (0x1032, "perfCntbtbRight"),
831    "btbWrong"    -> (0x1033, "perfCntbtbWrong"),
832    "tageRight"   -> (0x1034, "perfCnttageRight"),
833    "tageWrong"   -> (0x1035, "perfCnttageWrong"),
834    "rasRight"    -> (0x1036, "perfCntrasRight"),
835    "rasWrong"    -> (0x1037, "perfCntrasWrong"),
836    "loopRight"   -> (0x1038, "perfCntloopRight"),
837    "loopWrong"   -> (0x1039, "perfCntloopWrong"),
838    "s1Right"     -> (0x103a, "perfCntS1Right"),
839    "s1Wrong"     -> (0x103b, "perfCntS1Wrong"),
840    "s2Right"     -> (0x103c, "perfCntS2Right"),
841    "s2Wrong"     -> (0x103d, "perfCntS2Wrong"),
842    "s3Right"     -> (0x103e, "perfCntS3Right"),
843    "s3Wrong"     -> (0x103f, "perfCntS3Wrong"),
844    "takenAndRight" -> (0x1040, "perfCntTakenAndRight"),
845    "takenButWrong" -> (0x1041, "perfCntTakenButWrong"),
846    // "L2cacheHit" -> (0x1023, "perfCntCondL2cacheHit")
847  ) ++ (
848    (0 until dcacheParameters.nMissEntries).map(i =>
849      ("DCacheMissQueuePenalty" + Integer.toString(i, 10), (0x1042 + i, "perfCntDCacheMissQueuePenaltyEntry" + Integer.toString(i, 10)))
850    ).toMap
851  ) ++ (
852    (0 until icacheParameters.nMissEntries).map(i =>
853      ("ICacheMissQueuePenalty" + Integer.toString(i, 10), (0x1042 + dcacheParameters.nMissEntries + i, "perfCntICacheMissQueuePenaltyEntry" + Integer.toString(i, 10)))
854    ).toMap
855  ) ++ (
856    (0 until l1plusPrefetcherParameters.nEntries).map(i =>
857      ("L1+PrefetchPenalty" + Integer.toString(i, 10), (0x1042 + dcacheParameters.nMissEntries + icacheParameters.nMissEntries + i, "perfCntL1plusPrefetchPenaltyEntry" + Integer.toString(i, 10)))
858    ).toMap
859  ) ++ (
860    (0 until l2PrefetcherParameters.nEntries).map(i =>
861      ("L2PrefetchPenalty" + Integer.toString(i, 10), (0x1042 + dcacheParameters.nMissEntries + icacheParameters.nMissEntries + l1plusPrefetcherParameters.nEntries + i, "perfCntL2PrefetchPenaltyEntry" + Integer.toString(i, 10)))
862    ).toMap
863  )
864
865  emuPerfCntList.foreach {
866    case (_, (address, boringId)) =>
867      if (hasEmuPerfCnt) {
868        ExcitingUtils.addSink(emuPerfCntCond(address & 0x7f), boringId, ConnectionType.Perf)
869      }
870      // if (!hasEmuPerfCnt) {
871      //   // do not enable perfcnts except for Mcycle and Minstret
872      //   if (address != emuPerfCntList("Mcycle")._1 && address != emuPerfCntList("Minstret")._1) {
873      //     perfCntCond(address & 0x7f) := false.B
874      //   }
875      // }
876  }
877
878  val xstrap = WireInit(false.B)
879  if (!env.FPGAPlatform && EnableBPU) {
880    ExcitingUtils.addSink(xstrap, "XSTRAP", ConnectionType.Debug)
881  }
882  def readWithScala(addr: Int): UInt = mapping(addr)._1
883
884  val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
885
886  if (!env.FPGAPlatform) {
887
888    // display all perfcnt when nooptrap is executed
889    when (xstrap) {
890      printf("======== PerfCnt =========\n")
891      emuPerfCntList.toSeq.sortBy(_._2._1).foreach { case (str, (address, _)) =>
892        printf("%d <- " + str + "\n", readWithScala(address))
893      }
894    }
895
896    ExcitingUtils.addSource(difftestIntrNO, "difftestIntrNOfromCSR")
897    ExcitingUtils.addSource(causeNO, "difftestCausefromCSR")
898    ExcitingUtils.addSource(priviledgeMode, "difftestMode", Debug)
899    ExcitingUtils.addSource(mstatus, "difftestMstatus", Debug)
900    ExcitingUtils.addSource(mstatus & sstatusRmask, "difftestSstatus", Debug)
901    ExcitingUtils.addSource(mepc, "difftestMepc", Debug)
902    ExcitingUtils.addSource(sepc, "difftestSepc", Debug)
903    ExcitingUtils.addSource(mtval, "difftestMtval", Debug)
904    ExcitingUtils.addSource(stval, "difftestStval", Debug)
905    ExcitingUtils.addSource(mtvec, "difftestMtvec", Debug)
906    ExcitingUtils.addSource(stvec, "difftestStvec", Debug)
907    ExcitingUtils.addSource(mcause, "difftestMcause", Debug)
908    ExcitingUtils.addSource(scause, "difftestScause", Debug)
909    ExcitingUtils.addSource(satp, "difftestSatp", Debug)
910    ExcitingUtils.addSource(mipReg, "difftestMip", Debug)
911    ExcitingUtils.addSource(mie, "difftestMie", Debug)
912    ExcitingUtils.addSource(mscratch, "difftestMscratch", Debug)
913    ExcitingUtils.addSource(sscratch, "difftestSscratch", Debug)
914    ExcitingUtils.addSource(mideleg, "difftestMideleg", Debug)
915    ExcitingUtils.addSource(medeleg, "difftestMedeleg", Debug)
916  }
917
918  if (env.DualCoreDifftest) {
919    difftestIO.intrNO := RegNext(difftestIntrNO)
920    difftestIO.cause := RegNext(causeNO)
921    difftestIO.priviledgeMode := priviledgeMode
922    difftestIO.mstatus := mstatus
923    difftestIO.sstatus := mstatus & sstatusRmask
924    difftestIO.mepc := mepc
925    difftestIO.sepc := sepc
926    difftestIO.mtval:= mtval
927    difftestIO.stval:= stval
928    difftestIO.mtvec := mtvec
929    difftestIO.stvec := stvec
930    difftestIO.mcause := mcause
931    difftestIO.scause := scause
932    difftestIO.satp := satp
933    difftestIO.mip := mipReg
934    difftestIO.mie := mie
935    difftestIO.mscratch := mscratch
936    difftestIO.sscratch := sscratch
937    difftestIO.mideleg := mideleg
938    difftestIO.medeleg := medeleg
939  }
940}
941