xref: /XiangShan/src/main/scala/xiangshan/backend/fu/CSR.scala (revision ca18a0b47b0e4089fd0dd1c085091cb90bf98f25)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package xiangshan.backend.fu
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import freechips.rocketchip.util._
23import utils.MaskedRegMap.WritableMask
24import utils._
25import xiangshan._
26import xiangshan.backend._
27import xiangshan.cache._
28import xiangshan.frontend.BPUCtrl
29import xiangshan.backend.fu.util._
30import difftest._
31
32trait HasExceptionNO {
33  def instrAddrMisaligned = 0
34  def instrAccessFault    = 1
35  def illegalInstr        = 2
36  def breakPoint          = 3
37  def loadAddrMisaligned  = 4
38  def loadAccessFault     = 5
39  def storeAddrMisaligned = 6
40  def storeAccessFault    = 7
41  def ecallU              = 8
42  def ecallS              = 9
43  def ecallM              = 11
44  def instrPageFault      = 12
45  def loadPageFault       = 13
46  def storePageFault      = 15
47
48  def singleStep          = 14
49
50  val ExcPriority = Seq(
51    breakPoint, // TODO: different BP has different priority
52    singleStep,
53    instrPageFault,
54    instrAccessFault,
55    illegalInstr,
56    instrAddrMisaligned,
57    ecallM, ecallS, ecallU,
58    storePageFault,
59    loadPageFault,
60    storeAccessFault,
61    loadAccessFault,
62    storeAddrMisaligned,
63    loadAddrMisaligned
64  )
65  val frontendSet = List(
66    // instrAddrMisaligned,
67    instrAccessFault,
68    illegalInstr,
69    instrPageFault
70  )
71  val csrSet = List(
72    illegalInstr,
73    breakPoint,
74    ecallU,
75    ecallS,
76    ecallM
77  )
78  val loadUnitSet = List(
79    loadAddrMisaligned,
80    loadAccessFault,
81    loadPageFault
82  )
83  val storeUnitSet = List(
84    storeAddrMisaligned,
85    storeAccessFault,
86    storePageFault
87  )
88  val atomicsUnitSet = (loadUnitSet ++ storeUnitSet).distinct
89  val allPossibleSet = (frontendSet ++ csrSet ++ loadUnitSet ++ storeUnitSet).distinct
90  val csrWbCount = (0 until 16).map(i => if (csrSet.contains(i)) 1 else 0)
91  val loadWbCount = (0 until 16).map(i => if (loadUnitSet.contains(i)) 1 else 0)
92  val storeWbCount = (0 until 16).map(i => if (storeUnitSet.contains(i)) 1 else 0)
93  val atomicsWbCount = (0 until 16).map(i => if (atomicsUnitSet.contains(i)) 1 else 0)
94  val writebackCount = (0 until 16).map(i => csrWbCount(i) + atomicsWbCount(i) + loadWbCount(i) + 2 * storeWbCount(i))
95  def partialSelect(vec: Vec[Bool], select: Seq[Int], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = {
96    if (dontCareBits) {
97      val new_vec = Wire(ExceptionVec())
98      new_vec := DontCare
99      select.map(i => new_vec(i) := vec(i))
100      return new_vec
101    }
102    else if (falseBits) {
103      val new_vec = Wire(ExceptionVec())
104      new_vec.map(_ := false.B)
105      select.map(i => new_vec(i) := vec(i))
106      return new_vec
107    }
108    else {
109      val new_vec = Wire(Vec(select.length, Bool()))
110      select.zipWithIndex.map{ case(s, i) => new_vec(i) := vec(s) }
111      return new_vec
112    }
113  }
114  def selectFrontend(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
115    partialSelect(vec, frontendSet, dontCareBits, falseBits)
116  def selectCSR(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
117    partialSelect(vec, csrSet, dontCareBits, falseBits)
118  def selectLoad(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
119    partialSelect(vec, loadUnitSet, dontCareBits, falseBits)
120  def selectStore(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
121    partialSelect(vec, storeUnitSet, dontCareBits, falseBits)
122  def selectAtomics(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
123    partialSelect(vec, atomicsUnitSet, dontCareBits, falseBits)
124  def selectAll(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
125    partialSelect(vec, allPossibleSet, dontCareBits, falseBits)
126}
127
128class FpuCsrIO extends Bundle {
129  val fflags = Output(Valid(UInt(5.W)))
130  val isIllegal = Output(Bool())
131  val dirty_fs = Output(Bool())
132  val frm = Input(UInt(3.W))
133}
134
135
136class PerfCounterIO(implicit p: Parameters) extends XSBundle {
137  val retiredInstr = UInt(3.W)
138  val frontendInfo = new Bundle {
139    val ibufFull  = Bool()
140    val bpuInfo = new Bundle {
141      val bpRight = UInt(XLEN.W)
142      val bpWrong = UInt(XLEN.W)
143    }
144  }
145  val ctrlInfo = new Bundle {
146    val robFull   = Bool()
147    val intdqFull = Bool()
148    val fpdqFull  = Bool()
149    val lsdqFull  = Bool()
150  }
151  val memInfo = new Bundle {
152    val sqFull = Bool()
153    val lqFull = Bool()
154    val dcacheMSHRFull = Bool()
155  }
156
157  val cacheInfo = new Bundle {
158    val l2MSHRFull = Bool()
159    val l3MSHRFull = Bool()
160    val l2nAcquire = UInt(XLEN.W)
161    val l2nAcquireMiss = UInt(XLEN.W)
162    val l3nAcquire = UInt(XLEN.W)
163    val l3nAcquireMiss = UInt(XLEN.W)
164  }
165}
166
167class CSRFileIO(implicit p: Parameters) extends XSBundle {
168  val hartId = Input(UInt(64.W))
169  // output (for func === CSROpType.jmp)
170  val perf = Input(new PerfCounterIO)
171  val isPerfCnt = Output(Bool())
172  // to FPU
173  val fpu = Flipped(new FpuCsrIO)
174  // from rob
175  val exception = Flipped(ValidIO(new ExceptionInfo))
176  // to ROB
177  val isXRet = Output(Bool())
178  val trapTarget = Output(UInt(VAddrBits.W))
179  val interrupt = Output(Bool())
180  // from LSQ
181  val memExceptionVAddr = Input(UInt(VAddrBits.W))
182  // from outside cpu,externalInterrupt
183  val externalInterrupt = new ExternalInterruptIO
184  // TLB
185  val tlb = Output(new TlbCsrBundle)
186  // Debug Mode
187  val singleStep = Output(Bool())
188  val debugMode = Output(Bool())
189  // Custom microarchiture ctrl signal
190  val customCtrl = Output(new CustomCSRCtrlIO)
191  // to Fence to disable sfence
192  val disableSfence = Output(Bool())
193  // distributed csr w
194}
195
196class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMPConst
197{
198  val csrio = IO(new CSRFileIO)
199
200  val cfIn = io.in.bits.uop.cf
201  val cfOut = Wire(new CtrlFlow)
202  cfOut := cfIn
203  val flushPipe = Wire(Bool())
204
205  val (valid, src1, src2, func) = (
206    io.in.valid,
207    io.in.bits.src(0),
208    io.in.bits.uop.ctrl.imm,
209    io.in.bits.uop.ctrl.fuOpType
210  )
211
212  // CSR define
213
214  class Priv extends Bundle {
215    val m = Output(Bool())
216    val h = Output(Bool())
217    val s = Output(Bool())
218    val u = Output(Bool())
219  }
220
221  val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U)
222
223  class DcsrStruct extends Bundle {
224    val xdebugver = Output(UInt(2.W))
225    val zero4 = Output(UInt(2.W))
226    val zero3 = Output(UInt(12.W))
227    val ebreakm = Output(Bool())
228    val ebreakh = Output(Bool())
229    val ebreaks = Output(Bool())
230    val ebreaku = Output(Bool())
231    val zero2 = Output(Bool())
232    val stopcycle = Output(Bool())
233    val stoptime = Output(Bool())
234    val cause = Output(UInt(3.W))
235    val zero1 = Output(UInt(3.W))
236    val step = Output(Bool())
237    val prv = Output(UInt(2.W))
238  }
239
240  class MstatusStruct extends Bundle {
241    val sd = Output(UInt(1.W))
242
243    val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null
244    val sxl  = if (XLEN == 64) Output(UInt(2.W))  else null
245    val uxl  = if (XLEN == 64) Output(UInt(2.W))  else null
246    val pad0 = if (XLEN == 64) Output(UInt(9.W))  else Output(UInt(8.W))
247
248    val tsr = Output(UInt(1.W))
249    val tw = Output(UInt(1.W))
250    val tvm = Output(UInt(1.W))
251    val mxr = Output(UInt(1.W))
252    val sum = Output(UInt(1.W))
253    val mprv = Output(UInt(1.W))
254    val xs = Output(UInt(2.W))
255    val fs = Output(UInt(2.W))
256    val mpp = Output(UInt(2.W))
257    val hpp = Output(UInt(2.W))
258    val spp = Output(UInt(1.W))
259    val pie = new Priv
260    val ie = new Priv
261    assert(this.getWidth == XLEN)
262  }
263
264  class SatpStruct extends Bundle {
265    val mode = UInt(4.W)
266    val asid = UInt(16.W)
267    val ppn  = UInt(44.W)
268  }
269
270  class Interrupt extends Bundle {
271//  val d = Output(Bool())    // Debug
272    val e = new Priv
273    val t = new Priv
274    val s = new Priv
275  }
276
277  // Debug CSRs
278  val dcsr = RegInit(UInt(32.W), 0x4000b010.U)
279  val dpc = Reg(UInt(64.W))
280  val dscratch = Reg(UInt(64.W))
281  val dscratch1 = Reg(UInt(64.W))
282  val debugMode = RegInit(false.B)
283  val debugIntrEnable = RegInit(true.B)
284  csrio.debugMode := debugMode
285
286  val dpcPrev = RegNext(dpc)
287  XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x.", dpc, dpcPrev)
288
289  // dcsr value table
290  // | debugver | 0100
291  // | zero     | 10 bits of 0
292  // | ebreakvs | 0
293  // | ebreakvu | 0
294  // | ebreakm  | 1 if ebreak enters debug
295  // | zero     | 0
296  // | ebreaks  |
297  // | ebreaku  |
298  // | stepie   | 0 disable interrupts in singlestep
299  // | stopcount| stop counter, 0
300  // | stoptime | stop time, 0
301  // | cause    | 3 bits read only
302  // | v        | 0
303  // | mprven   | 1
304  // | nmip     | read only
305  // | step     |
306  // | prv      | 2 bits
307
308  val dcsrData = Wire(new DcsrStruct)
309  dcsrData := dcsr.asTypeOf(new DcsrStruct)
310  val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(2, 0), XLEN)// Dcsr write mask
311  def dcsrUpdateSideEffect(dcsr: UInt): UInt = {
312    val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct))
313    val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11
314    dcsrNew
315  }
316  csrio.singleStep := dcsrData.step
317
318  // Machine-Level CSRs
319
320  val mtvec = RegInit(UInt(XLEN.W), 0.U)
321  val mcounteren = RegInit(UInt(XLEN.W), 0.U)
322  val mcause = RegInit(UInt(XLEN.W), 0.U)
323  val mtval = RegInit(UInt(XLEN.W), 0.U)
324  val mepc = Reg(UInt(XLEN.W))
325
326  val mie = RegInit(0.U(XLEN.W))
327  val mipWire = WireInit(0.U.asTypeOf(new Interrupt))
328  val mipReg  = RegInit(0.U(XLEN.W))
329  val mipFixMask = ZeroExt(GenMask(9) | GenMask(5) | GenMask(1), XLEN)
330  val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt)
331
332  def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt()
333  def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt()
334  var extList = List('a', 's', 'i', 'u')
335  if (HasMExtension) { extList = extList :+ 'm' }
336  if (HasCExtension) { extList = extList :+ 'c' }
337  if (HasFPU) { extList = extList ++ List('f', 'd') }
338  val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U
339  val misa = RegInit(UInt(XLEN.W), misaInitVal)
340
341  // MXL = 2          | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101
342  // (XLEN-1, XLEN-2) |   |(25, 0)  ZY XWVU TSRQ PONM LKJI HGFE DCBA
343
344  val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation
345  val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented
346  val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation
347  val mhartid = RegInit(UInt(XLEN.W), csrio.hartId) // the hardware thread running the code
348  val mstatus = RegInit(UInt(XLEN.W), 0.U)
349
350  // mstatus Value Table
351  // | sd   |
352  // | pad1 |
353  // | sxl  | hardlinked to 10, use 00 to pass xv6 test
354  // | uxl  | hardlinked to 00
355  // | pad0 |
356  // | tsr  |
357  // | tw   |
358  // | tvm  |
359  // | mxr  |
360  // | sum  |
361  // | mprv |
362  // | xs   | 00 |
363  // | fs   | 00 |
364  // | mpp  | 00 |
365  // | hpp  | 00 |
366  // | spp  | 0 |
367  // | pie  | 0000 | pie.h is used as UBE
368  // | ie   | 0000 | uie hardlinked to 0, as N ext is not implemented
369
370  val mstatusStruct = mstatus.asTypeOf(new MstatusStruct)
371  def mstatusUpdateSideEffect(mstatus: UInt): UInt = {
372    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
373    val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0))
374    mstatusNew
375  }
376
377  val mstatusMask = (~ZeroExt((
378    GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) |
379    GenMask(37) | // MBE
380    GenMask(36) | // SBE
381    GenMask(6)    // UBE
382  ), 64)).asUInt()
383
384  val medeleg = RegInit(UInt(XLEN.W), 0.U)
385  val mideleg = RegInit(UInt(XLEN.W), 0.U)
386  val mscratch = RegInit(UInt(XLEN.W), 0.U)
387
388  // PMP Mapping
389  val pmp = Wire(Vec(NumPMP, new PMPBase()))
390  val pmpMapping = if (NumPMP > 0) { // TODO: remove duplicate codes
391    val pmpCfgPerCSR = XLEN / new PMPConfig().getWidth
392    def pmpCfgIndex(i: Int) = (XLEN / 32) * (i / pmpCfgPerCSR)
393
394    /** to fit MaskedRegMap's write, declare cfgs as Merged CSRs and split them into each pmp */
395    val cfgMerged = RegInit(VecInit(Seq.fill(NumPMP / pmpCfgPerCSR)(0.U(XLEN.W))))
396    val cfgs = WireInit(cfgMerged).asTypeOf(Vec(NumPMP, new PMPConfig()))
397    val addr = Reg(Vec(NumPMP, UInt((PAddrBits-PMPOffBits).W)))
398    for (i <- pmp.indices) {
399      pmp(i).gen(cfgs(i), addr(i))
400    }
401
402    val cfg_mapping = (0 until NumPMP by pmpCfgPerCSR).map(i => {Map(
403      MaskedRegMap(
404        addr = PmpcfgBase + pmpCfgIndex(i),
405        reg = cfgMerged(i/pmpCfgPerCSR),
406        wmask = WritableMask,
407        wfn = new PMPConfig().write_cfg_vec
408      ))
409    }).fold(Map())((a, b) => a ++ b) // ugly code, hit me if u have better codes
410    val addr_mapping = (0 until NumPMP).map(i => {Map(
411      MaskedRegMap(
412        addr = PmpaddrBase + i,
413        reg = addr(i),
414        wmask = WritableMask,
415        wfn = { if (i != NumPMP-1) pmp(i).write_addr(pmp(i+1)) else pmp(i).write_addr },
416        rmask = WritableMask,
417        rfn = new PMPBase().read_addr(pmp(i).cfg)
418      ))
419    }).fold(Map())((a, b) => a ++ b) // ugly code, hit me if u have better codes.
420    cfg_mapping ++ addr_mapping
421  } else {
422    Map()
423  }
424  // Superviser-Level CSRs
425
426  // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U)
427  val sstatusWmask = "hc6122".U(XLEN.W)
428  // Sstatus Write Mask
429  // -------------------------------------------------------
430  //    19           9   5     2
431  // 0  1100 0000 0001 0010 0010
432  // 0  c    0    1    2    2
433  // -------------------------------------------------------
434  val sstatusRmask = sstatusWmask | "h8000000300018000".U
435  // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32))
436  val stvec = RegInit(UInt(XLEN.W), 0.U)
437  // val sie = RegInit(0.U(XLEN.W))
438  val sieMask = "h222".U & mideleg
439  val sipMask = "h222".U & mideleg
440  val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode
441  val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W))
442  // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug
443  val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0
444  val sepc = RegInit(UInt(XLEN.W), 0.U)
445  val scause = RegInit(UInt(XLEN.W), 0.U)
446  val stval = Reg(UInt(XLEN.W))
447  val sscratch = RegInit(UInt(XLEN.W), 0.U)
448  val scounteren = RegInit(UInt(XLEN.W), 0.U)
449
450  // sbpctl
451  // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB}
452  val sbpctl = RegInit(UInt(XLEN.W), "h7f".U)
453  csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0)
454  csrio.customCtrl.bp_ctrl.btb_enable  := sbpctl(1)
455  csrio.customCtrl.bp_ctrl.bim_enable  := sbpctl(2)
456  csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3)
457  csrio.customCtrl.bp_ctrl.sc_enable   := sbpctl(4)
458  csrio.customCtrl.bp_ctrl.ras_enable  := sbpctl(5)
459  csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6)
460
461  // spfctl Bit 0: L1plusCache Prefetcher Enable
462  // spfctl Bit 1: L2Cache Prefetcher Enable
463  val spfctl = RegInit(UInt(XLEN.W), "h3".U)
464  csrio.customCtrl.l1plus_pf_enable := spfctl(0)
465  csrio.customCtrl.l2_pf_enable := spfctl(1)
466
467  // sdsid: Differentiated Services ID
468  val sdsid = RegInit(UInt(XLEN.W), 0.U)
469  csrio.customCtrl.dsid := sdsid
470
471  // slvpredctl: load violation predict settings
472  val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17
473  csrio.customCtrl.lvpred_disable := slvpredctl(0)
474  csrio.customCtrl.no_spec_load := slvpredctl(1)
475  csrio.customCtrl.storeset_wait_store := slvpredctl(2)
476  csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3)
477  csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4)
478
479  // smblockctl: memory block configurations
480  // bits 0-3: store buffer flush threshold (default: 8 entries)
481  val smblockctl = RegInit(UInt(XLEN.W), "hf".U & StoreBufferThreshold.U)
482  csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0)
483
484  val srnctl = RegInit(UInt(XLEN.W), "h1".U)
485  csrio.customCtrl.move_elim_enable := srnctl(0)
486
487  val tlbBundle = Wire(new TlbCsrBundle)
488  tlbBundle.satp := satp.asTypeOf(new SatpStruct)
489
490  csrio.tlb := tlbBundle
491
492  // User-Level CSRs
493  val uepc = Reg(UInt(XLEN.W))
494
495  // fcsr
496  class FcsrStruct extends Bundle {
497    val reserved = UInt((XLEN-3-5).W)
498    val frm = UInt(3.W)
499    val fflags = UInt(5.W)
500    assert(this.getWidth == XLEN)
501  }
502  val fcsr = RegInit(0.U(XLEN.W))
503  // set mstatus->sd and mstatus->fs when true
504  val csrw_dirty_fp_state = WireInit(false.B)
505
506  def frm_wfn(wdata: UInt): UInt = {
507    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
508    csrw_dirty_fp_state := true.B
509    fcsrOld.frm := wdata(2,0)
510    fcsrOld.asUInt()
511  }
512  def frm_rfn(rdata: UInt): UInt = rdata(7,5)
513
514  def fflags_wfn(update: Boolean)(wdata: UInt): UInt = {
515    val fcsrOld = fcsr.asTypeOf(new FcsrStruct)
516    val fcsrNew = WireInit(fcsrOld)
517    csrw_dirty_fp_state := true.B
518    if (update) {
519      fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags
520    } else {
521      fcsrNew.fflags := wdata(4,0)
522    }
523    fcsrNew.asUInt()
524  }
525  def fflags_rfn(rdata:UInt): UInt = rdata(4,0)
526
527  def fcsr_wfn(wdata: UInt): UInt = {
528    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
529    csrw_dirty_fp_state := true.B
530    Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags)
531  }
532
533  val fcsrMapping = Map(
534    MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn),
535    MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn),
536    MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn)
537  )
538
539  // Hart Priviledge Mode
540  val priviledgeMode = RegInit(UInt(2.W), ModeM)
541
542  // Emu perfcnt
543  val hasEmuPerfCnt = !env.FPGAPlatform
544  val nrEmuPerfCnts = if (hasEmuPerfCnt) 0x80 else 0x3
545
546  val emuPerfCnts    = List.fill(nrEmuPerfCnts)(RegInit(0.U(XLEN.W)))
547  val emuPerfCntCond = List.fill(nrEmuPerfCnts)(WireInit(false.B))
548  (emuPerfCnts zip emuPerfCntCond).map { case (c, e) => when (e) { c := c + 1.U } }
549
550  val emuPerfCntsLoMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1000 + i, emuPerfCnts(i)))
551  val emuPerfCntsHiMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1080 + i, emuPerfCnts(i)(63, 32)))
552  println(s"CSR: hasEmuPerfCnt:${hasEmuPerfCnt}")
553
554  // Perf Counter
555  val nrPerfCnts = 29  // 3...31
556  val perfCnts   = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W)))
557  val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W)))
558  val mcountinhibit = RegInit(0.U(XLEN.W))
559  val mcycle = RegInit(0.U(XLEN.W))
560  mcycle := mcycle + 1.U
561  val minstret = RegInit(0.U(XLEN.W))
562  minstret := minstret + RegNext(csrio.perf.retiredInstr)
563  val ibufFull  = RegInit(0.U(XLEN.W))
564  ibufFull := ibufFull + RegNext(csrio.perf.frontendInfo.ibufFull)
565  val robFull   = RegInit(0.U(XLEN.W))
566  robFull := robFull + RegNext(csrio.perf.ctrlInfo.robFull)
567  val intdqFull = RegInit(0.U(XLEN.W))
568  intdqFull := intdqFull + RegNext(csrio.perf.ctrlInfo.intdqFull)
569  val fpdqFull  = RegInit(0.U(XLEN.W))
570  fpdqFull := fpdqFull + RegNext(csrio.perf.ctrlInfo.fpdqFull)
571  val lsdqFull  = RegInit(0.U(XLEN.W))
572  lsdqFull := lsdqFull + RegNext(csrio.perf.ctrlInfo.lsdqFull)
573  val sqFull    = RegInit(0.U(XLEN.W))
574  sqFull := sqFull + RegNext(csrio.perf.memInfo.sqFull)
575  val lqFull    = RegInit(0.U(XLEN.W))
576  lqFull := lqFull + RegNext(csrio.perf.memInfo.lqFull)
577  val dcacheMSHRFull = RegInit(0.U(XLEN.W))
578  dcacheMSHRFull := dcacheMSHRFull + RegNext(csrio.perf.memInfo.dcacheMSHRFull)
579  val bpRight   = RegInit(0.U(XLEN.W))
580  bpRight := bpRight + RegNext(csrio.perf.frontendInfo.bpuInfo.bpRight)
581  val bpWrong   = RegInit(0.U(XLEN.W))
582  bpWrong := bpWrong + RegNext(csrio.perf.frontendInfo.bpuInfo.bpWrong)
583
584  // CSR reg map
585  val basicPrivMapping = Map(
586
587    //--- User Trap Setup ---
588    // MaskedRegMap(Ustatus, ustatus),
589    // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable),
590    // MaskedRegMap(Utvec, utvec),
591
592    //--- User Trap Handling ---
593    // MaskedRegMap(Uscratch, uscratch),
594    // MaskedRegMap(Uepc, uepc),
595    // MaskedRegMap(Ucause, ucause),
596    // MaskedRegMap(Utval, utval),
597    // MaskedRegMap(Uip, uip),
598
599    //--- User Counter/Timers ---
600    // MaskedRegMap(Cycle, cycle),
601    // MaskedRegMap(Time, time),
602    // MaskedRegMap(Instret, instret),
603
604    //--- Supervisor Trap Setup ---
605    MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask),
606    // MaskedRegMap(Sedeleg, Sedeleg),
607    // MaskedRegMap(Sideleg, Sideleg),
608    MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask),
609    MaskedRegMap(Stvec, stvec),
610    MaskedRegMap(Scounteren, scounteren),
611
612    //--- Supervisor Trap Handling ---
613    MaskedRegMap(Sscratch, sscratch),
614    MaskedRegMap(Sepc, sepc),
615    MaskedRegMap(Scause, scause),
616    MaskedRegMap(Stval, stval),
617    MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask),
618
619    //--- Supervisor Protection and Translation ---
620    MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask),
621
622    //--- Supervisor Custom Read/Write Registers
623    MaskedRegMap(Sbpctl, sbpctl),
624    MaskedRegMap(Spfctl, spfctl),
625    MaskedRegMap(Sdsid, sdsid),
626    MaskedRegMap(Slvpredctl, slvpredctl),
627    MaskedRegMap(Smblockctl, smblockctl),
628    MaskedRegMap(Srnctl, srnctl),
629
630    //--- Machine Information Registers ---
631    MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
632    MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
633    MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
634    MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
635
636    //--- Machine Trap Setup ---
637    MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask),
638    MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable
639    MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)),
640    MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)),
641    MaskedRegMap(Mie, mie),
642    MaskedRegMap(Mtvec, mtvec),
643    MaskedRegMap(Mcounteren, mcounteren),
644
645    //--- Machine Trap Handling ---
646    MaskedRegMap(Mscratch, mscratch),
647    MaskedRegMap(Mepc, mepc),
648    MaskedRegMap(Mcause, mcause),
649    MaskedRegMap(Mtval, mtval),
650    MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable),
651
652    //--- Debug Mode ---
653    MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect),
654    MaskedRegMap(Dpc, dpc),
655    MaskedRegMap(Dscratch, dscratch),
656    MaskedRegMap(Dscratch1, dscratch1)
657  )
658
659  var perfCntMapping = Map(
660    MaskedRegMap(Mcountinhibit, mcountinhibit),
661    MaskedRegMap(Mcycle, mcycle),
662    MaskedRegMap(Minstret, minstret),
663    MaskedRegMap(Mhpmevent3, ibufFull),
664    MaskedRegMap(Mhpmevent4, robFull),
665    MaskedRegMap(Mhpmevent5, intdqFull),
666    MaskedRegMap(Mhpmevent6, fpdqFull),
667    MaskedRegMap(Mhpmevent7, lsdqFull),
668    MaskedRegMap(Mhpmevent8, sqFull),
669    MaskedRegMap(Mhpmevent9, lqFull),
670    MaskedRegMap(Mhpmevent10, dcacheMSHRFull),
671    MaskedRegMap(Mhpmevent11, bpRight),
672    MaskedRegMap(Mhpmevent12, bpWrong),
673  )
674  // TODO: mechanism should be implemented later
675  // val MhpmcounterStart = Mhpmcounter3
676  // val MhpmeventStart   = Mhpmevent3
677  // for (i <- 0 until nrPerfCnts) {
678  //   perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i))
679  //   perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i))
680  // }
681
682  val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
683    MaskedRegMap(
684      Scachebase + attribute("offset").toInt,
685      RegInit(0.U(attribute("width").toInt.W))
686    )
687  }}
688
689  val mapping = basicPrivMapping ++
690                perfCntMapping ++
691                pmpMapping ++
692                emuPerfCntsLoMapping ++
693                (if (XLEN == 32) emuPerfCntsHiMapping else Nil) ++
694                (if (HasFPU) fcsrMapping else Nil) ++
695                (if (HasCustomCSRCacheOp) cacheopMapping else Nil)
696
697  val addr = src2(11, 0)
698  val csri = ZeroExt(src2(16, 12), XLEN)
699  val rdata = Wire(UInt(XLEN.W))
700  val wdata = LookupTree(func, List(
701    CSROpType.wrt  -> src1,
702    CSROpType.set  -> (rdata | src1),
703    CSROpType.clr  -> (rdata & (~src1).asUInt()),
704    CSROpType.wrti -> csri,
705    CSROpType.seti -> (rdata | csri),
706    CSROpType.clri -> (rdata & (~csri).asUInt())
707  ))
708
709  val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U)
710  csrio.isPerfCnt := addrInPerfCnt
711
712  // satp wen check
713  val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U)
714
715  // csr access check, special case
716  val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool)
717  val accessPermitted = !(addr === Satp.U && tvmNotPermit)
718  csrio.disableSfence := tvmNotPermit
719
720  // general CSR wen check
721  val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode)
722  val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode)
723  val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren)
724  val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted
725
726  // Writeable check is ingored.
727  // Currently, write to illegal csr addr will be ignored
728  MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata)
729  io.out.bits.data := rdata
730  io.out.bits.uop := io.in.bits.uop
731  io.out.bits.uop.cf := cfOut
732  io.out.bits.uop.ctrl.flushPipe := flushPipe
733
734  // send distribute csr a w signal
735  csrio.customCtrl.distribute_csr.w.valid := wen && permitted
736  csrio.customCtrl.distribute_csr.w.bits.data := wdata
737  csrio.customCtrl.distribute_csr.w.bits.addr := addr
738
739  // Fix Mip/Sip write
740  val fixMapping = Map(
741    MaskedRegMap(Mip, mipReg.asUInt, mipFixMask),
742    MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask)
743  )
744  val rdataFix = Wire(UInt(XLEN.W))
745  val wdataFix = LookupTree(func, List(
746    CSROpType.wrt  -> src1,
747    CSROpType.set  -> (rdataFix | src1),
748    CSROpType.clr  -> (rdataFix & (~src1).asUInt()),
749    CSROpType.wrti -> csri,
750    CSROpType.seti -> (rdataFix | csri),
751    CSROpType.clri -> (rdataFix & (~csri).asUInt())
752  ))
753  MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix)
754
755  when (csrio.fpu.fflags.valid) {
756    fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits)
757  }
758  // set fs and sd in mstatus
759  when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) {
760    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
761    mstatusNew.fs := "b11".U
762    mstatusNew.sd := true.B
763    mstatus := mstatusNew.asUInt()
764  }
765  csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm
766
767  // CSR inst decode
768  val isEbreak = addr === privEbreak && func === CSROpType.jmp
769  val isEcall  = addr === privEcall  && func === CSROpType.jmp
770  val isMret   = addr === privMret   && func === CSROpType.jmp
771  val isSret   = addr === privSret   && func === CSROpType.jmp
772  val isUret   = addr === privUret   && func === CSROpType.jmp
773  val isDret   = addr === privDret   && func === CSROpType.jmp
774
775  XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func)
776  XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode)
777
778  // Illegal priviledged operation list
779  val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool
780
781  // Illegal priviledged instruction check
782  val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr)
783  val isIllegalAccess = !permitted
784  val isIllegalPrivOp = illegalSModeSret
785
786  // expose several csr bits for tlb
787  tlbBundle.priv.mxr   := mstatusStruct.mxr.asBool
788  tlbBundle.priv.sum   := mstatusStruct.sum.asBool
789  tlbBundle.priv.imode := priviledgeMode
790  tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode)
791
792  // Branch control
793  val retTarget = Wire(UInt(VAddrBits.W))
794  val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed
795  flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall)
796
797  retTarget := DontCare
798  // val illegalEret = TODO
799
800  when (valid && isDret) {
801    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
802    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
803    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
804    val debugModeNew = WireInit(debugMode)
805    when (dcsr.asTypeOf(new DcsrStruct).prv =/= ModeM) {mstatusNew.mprv := 0.U} //If the new privilege mode is less privileged than M-mode, MPRV in mstatus is cleared.
806    mstatus := mstatusNew.asUInt
807    priviledgeMode := dcsrNew.prv
808    retTarget := dpc(VAddrBits-1, 0)
809    debugModeNew := false.B
810    debugIntrEnable := true.B
811    debugMode := debugModeNew
812    XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget)
813  }
814
815  when (valid && isMret) {
816    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
817    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
818    mstatusNew.ie.m := mstatusOld.pie.m
819    priviledgeMode := mstatusOld.mpp
820    mstatusNew.pie.m := true.B
821    mstatusNew.mpp := ModeU
822    when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U }
823    mstatus := mstatusNew.asUInt
824    // lr := false.B
825    retTarget := mepc(VAddrBits-1, 0)
826  }
827
828  when (valid && isSret && !illegalSModeSret) {
829    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
830    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
831    mstatusNew.ie.s := mstatusOld.pie.s
832    priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
833    mstatusNew.pie.s := true.B
834    mstatusNew.spp := ModeU
835    mstatus := mstatusNew.asUInt
836    mstatusNew.mprv := 0.U
837    // lr := false.B
838    retTarget := sepc(VAddrBits-1, 0)
839  }
840
841  when (valid && isUret) {
842    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
843    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
844    // mstatusNew.mpp.m := ModeU //TODO: add mode U
845    mstatusNew.ie.u := mstatusOld.pie.u
846    priviledgeMode := ModeU
847    mstatusNew.pie.u := true.B
848    mstatus := mstatusNew.asUInt
849    retTarget := uepc(VAddrBits-1, 0)
850  }
851
852  io.in.ready := true.B
853  io.out.valid := valid
854
855  val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku)
856
857  val csrExceptionVec = WireInit(cfIn.exceptionVec)
858  csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException
859  csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
860  csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
861  csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
862  // Trigger an illegal instr exception when:
863  // * unimplemented csr is being read/written
864  // * csr access is illegal
865  csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
866  cfOut.exceptionVec := csrExceptionVec
867
868  /**
869    * Exception and Intr
870    */
871  val ideleg =  (mideleg & mip.asUInt)
872  def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS),
873    ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM))
874
875  val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable
876  XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!")
877  // send interrupt information to ROB
878  val intrVecEnable = Wire(Vec(12, Bool()))
879  intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)}
880  val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt))
881  val intrBitSet = intrVec.orR()
882  csrio.interrupt := intrBitSet
883  mipWire.t.m := csrio.externalInterrupt.mtip
884  mipWire.s.m := csrio.externalInterrupt.msip
885  mipWire.e.m := csrio.externalInterrupt.meip
886  mipWire.e.s := csrio.externalInterrupt.meip
887
888  // interrupts
889  val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
890  val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt
891  XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO)
892  val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr
893
894  // exceptions
895  val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt
896  val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException
897  val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException
898  val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException
899  val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException
900  val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException
901  val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException
902  val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException
903  val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException
904  val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException
905  val hasSingleStep = csrio.exception.bits.uop.cf.exceptionVec(singleStep) && raiseException
906
907  val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec
908  val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
909  val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
910
911  val raiseExceptionIntr = csrio.exception.valid
912
913  val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep
914  val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ???
915
916  XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
917    csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt
918  )
919  XSDebug(raiseExceptionIntr,
920    "pc %x mstatus %x mideleg %x medeleg %x mode %x\n",
921    csrio.exception.bits.uop.cf.pc,
922    mstatus,
923    mideleg,
924    medeleg,
925    priviledgeMode
926  )
927
928  // mtval write logic
929  val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
930  when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) {
931    val tval = Mux(
932      hasInstrPageFault,
933      Mux(
934        csrio.exception.bits.uop.cf.crossPageIPFFix,
935        SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN),
936        SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
937      ),
938      memExceptionAddr
939    )
940    when (priviledgeMode === ModeM) {
941      mtval := tval
942    }.otherwise {
943      stval := tval
944    }
945  }
946
947  when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) {
948    mtval := memExceptionAddr
949  }
950
951  val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec
952  val deleg = Mux(raiseIntr, mideleg , medeleg)
953  // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM);
954  val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM)
955  val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check
956  val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak
957
958  // ctrl block will use theses later for flush
959  val isXRetFlag = RegInit(false.B)
960  val retTargetReg = Reg(retTarget.cloneType)
961  when (io.redirectIn.valid) {
962    isXRetFlag := false.B
963  }.elsewhen (isXRet) {
964    isXRetFlag := true.B
965    retTargetReg := retTarget
966  }
967  csrio.isXRet := isXRetFlag
968  csrio.trapTarget := Mux(isXRetFlag,
969    retTargetReg,
970    Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget,
971      Mux(delegS, stvec, mtvec))(VAddrBits-1, 0)
972  )
973
974  when (raiseExceptionIntr) {
975    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
976    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
977    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
978    val debugModeNew = WireInit(debugMode)
979
980    when (raiseDebugExceptionIntr) {
981      when (raiseDebugIntr) {
982        debugModeNew := true.B
983        mstatusNew.mprv := false.B
984        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
985        dcsrNew.cause := 1.U
986        dcsrNew.prv := priviledgeMode
987        priviledgeMode := ModeM
988        XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc)
989      }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) {
990        // ebreak or ss in running hart
991        debugModeNew := true.B
992        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
993        dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U)
994        dcsrNew.prv := priviledgeMode // TODO
995        priviledgeMode := ModeM
996        mstatusNew.mprv := false.B
997      }
998      dcsr := dcsrNew.asUInt
999      debugIntrEnable := false.B
1000    }.elsewhen (delegS) {
1001      scause := causeNO
1002      sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1003      mstatusNew.spp := priviledgeMode
1004      mstatusNew.pie.s := mstatusOld.ie.s
1005      mstatusNew.ie.s := false.B
1006      priviledgeMode := ModeS
1007      when (tvalWen) { stval := 0.U }
1008    }.otherwise {
1009      mcause := causeNO
1010      mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1011      mstatusNew.mpp := priviledgeMode
1012      mstatusNew.pie.m := mstatusOld.ie.m
1013      mstatusNew.ie.m := false.B
1014      priviledgeMode := ModeM
1015      when (tvalWen) { mtval := 0.U }
1016    }
1017    mstatus := mstatusNew.asUInt
1018    debugMode := debugModeNew
1019  }
1020
1021  XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc)
1022
1023  def readWithScala(addr: Int): UInt = mapping(addr)._1
1024
1025  val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
1026
1027  if (!env.FPGAPlatform) {
1028    val difftest = Module(new DifftestArchEvent)
1029    difftest.io.clock := clock
1030    difftest.io.coreid := hardId.U
1031    difftest.io.intrNO := RegNext(difftestIntrNO)
1032    difftest.io.cause := RegNext(Mux(csrio.exception.valid, causeNO, 0.U))
1033    difftest.io.exceptionPC := RegNext(SignExt(csrio.exception.bits.uop.cf.pc, XLEN))
1034  }
1035
1036  if (!env.FPGAPlatform) {
1037    val difftest = Module(new DifftestCSRState)
1038    difftest.io.clock := clock
1039    difftest.io.coreid := hardId.U
1040    difftest.io.priviledgeMode := priviledgeMode
1041    difftest.io.mstatus := mstatus
1042    difftest.io.sstatus := mstatus & sstatusRmask
1043    difftest.io.mepc := mepc
1044    difftest.io.sepc := sepc
1045    difftest.io.mtval:= mtval
1046    difftest.io.stval:= stval
1047    difftest.io.mtvec := mtvec
1048    difftest.io.stvec := stvec
1049    difftest.io.mcause := mcause
1050    difftest.io.scause := scause
1051    difftest.io.satp := satp
1052    difftest.io.mip := mipReg
1053    difftest.io.mie := mie
1054    difftest.io.mscratch := mscratch
1055    difftest.io.sscratch := sscratch
1056    difftest.io.mideleg := mideleg
1057    difftest.io.medeleg := medeleg
1058  }
1059}
1060