xref: /XiangShan/src/main/scala/xiangshan/backend/fu/CSR.scala (revision 1545277abc67bbe5123a324f0b61142535bfe61f)
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 perfEventsFrontend  = (new PerfEventsBundle(numCSRPCntFrontend ))
138  val perfEventsCtrl      = (new PerfEventsBundle(numCSRPCntCtrl     ))
139  val perfEventsLsu       = (new PerfEventsBundle(numCSRPCntLsu      ))
140  val perfEventsHc        = Vec(numPCntHc * coreParams.L2NBanks,(UInt(6.W)))
141  val retiredInstr = UInt(3.W)
142  val frontendInfo = new Bundle {
143    val ibufFull  = Bool()
144    val bpuInfo = new Bundle {
145      val bpRight = UInt(XLEN.W)
146      val bpWrong = UInt(XLEN.W)
147    }
148  }
149  val ctrlInfo = new Bundle {
150    val robFull   = Bool()
151    val intdqFull = Bool()
152    val fpdqFull  = Bool()
153    val lsdqFull  = Bool()
154  }
155  val memInfo = new Bundle {
156    val sqFull = Bool()
157    val lqFull = Bool()
158    val dcacheMSHRFull = Bool()
159  }
160
161  val cacheInfo = new Bundle {
162    val l2MSHRFull = Bool()
163    val l3MSHRFull = Bool()
164    val l2nAcquire = UInt(XLEN.W)
165    val l2nAcquireMiss = UInt(XLEN.W)
166    val l3nAcquire = UInt(XLEN.W)
167    val l3nAcquireMiss = UInt(XLEN.W)
168  }
169}
170
171class CSRFileIO(implicit p: Parameters) extends XSBundle {
172  val hartId = Input(UInt(64.W))
173  // output (for func === CSROpType.jmp)
174  val perf = Input(new PerfCounterIO)
175  val isPerfCnt = Output(Bool())
176  // to FPU
177  val fpu = Flipped(new FpuCsrIO)
178  // from rob
179  val exception = Flipped(ValidIO(new ExceptionInfo))
180  // to ROB
181  val isXRet = Output(Bool())
182  val trapTarget = Output(UInt(VAddrBits.W))
183  val interrupt = Output(Bool())
184  // from LSQ
185  val memExceptionVAddr = Input(UInt(VAddrBits.W))
186  // from outside cpu,externalInterrupt
187  val externalInterrupt = new ExternalInterruptIO
188  // TLB
189  val tlb = Output(new TlbCsrBundle)
190  // Debug Mode
191  val singleStep = Output(Bool())
192  val debugMode = Output(Bool())
193  // Custom microarchiture ctrl signal
194  val customCtrl = Output(new CustomCSRCtrlIO)
195  val distributedUpdate = Flipped(new DistributedCSRUpdateReq)
196  // to Fence to disable sfence
197  val disableSfence = Output(Bool())
198  // distributed csr w
199}
200
201class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMPMethod with PMAMethod
202{
203  val csrio = IO(new CSRFileIO)
204
205  val cfIn = io.in.bits.uop.cf
206  val cfOut = Wire(new CtrlFlow)
207  cfOut := cfIn
208  val flushPipe = Wire(Bool())
209
210  val (valid, src1, src2, func) = (
211    io.in.valid,
212    io.in.bits.src(0),
213    io.in.bits.uop.ctrl.imm,
214    io.in.bits.uop.ctrl.fuOpType
215  )
216
217  // CSR define
218
219  class Priv extends Bundle {
220    val m = Output(Bool())
221    val h = Output(Bool())
222    val s = Output(Bool())
223    val u = Output(Bool())
224  }
225
226  val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U)
227
228  class DcsrStruct extends Bundle {
229    val xdebugver = Output(UInt(2.W))
230    val zero4 = Output(UInt(2.W))
231    val zero3 = Output(UInt(12.W))
232    val ebreakm = Output(Bool())
233    val ebreakh = Output(Bool())
234    val ebreaks = Output(Bool())
235    val ebreaku = Output(Bool())
236    val zero2 = Output(Bool())
237    val stopcycle = Output(Bool())
238    val stoptime = Output(Bool())
239    val cause = Output(UInt(3.W))
240    val zero1 = Output(UInt(3.W))
241    val step = Output(Bool())
242    val prv = Output(UInt(2.W))
243  }
244
245  class MstatusStruct extends Bundle {
246    val sd = Output(UInt(1.W))
247
248    val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null
249    val sxl  = if (XLEN == 64) Output(UInt(2.W))  else null
250    val uxl  = if (XLEN == 64) Output(UInt(2.W))  else null
251    val pad0 = if (XLEN == 64) Output(UInt(9.W))  else Output(UInt(8.W))
252
253    val tsr = Output(UInt(1.W))
254    val tw = Output(UInt(1.W))
255    val tvm = Output(UInt(1.W))
256    val mxr = Output(UInt(1.W))
257    val sum = Output(UInt(1.W))
258    val mprv = Output(UInt(1.W))
259    val xs = Output(UInt(2.W))
260    val fs = Output(UInt(2.W))
261    val mpp = Output(UInt(2.W))
262    val hpp = Output(UInt(2.W))
263    val spp = Output(UInt(1.W))
264    val pie = new Priv
265    val ie = new Priv
266    assert(this.getWidth == XLEN)
267  }
268
269  class Interrupt extends Bundle {
270//  val d = Output(Bool())    // Debug
271    val e = new Priv
272    val t = new Priv
273    val s = new Priv
274  }
275
276  // Debug CSRs
277  val dcsr = RegInit(UInt(32.W), 0x4000b010.U)
278  val dpc = Reg(UInt(64.W))
279  val dscratch = Reg(UInt(64.W))
280  val dscratch1 = Reg(UInt(64.W))
281  val debugMode = RegInit(false.B)
282  val debugIntrEnable = RegInit(true.B)
283  csrio.debugMode := debugMode
284
285  val dpcPrev = RegNext(dpc)
286  XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x.", dpc, dpcPrev)
287
288  // dcsr value table
289  // | debugver | 0100
290  // | zero     | 10 bits of 0
291  // | ebreakvs | 0
292  // | ebreakvu | 0
293  // | ebreakm  | 1 if ebreak enters debug
294  // | zero     | 0
295  // | ebreaks  |
296  // | ebreaku  |
297  // | stepie   | 0 disable interrupts in singlestep
298  // | stopcount| stop counter, 0
299  // | stoptime | stop time, 0
300  // | cause    | 3 bits read only
301  // | v        | 0
302  // | mprven   | 1
303  // | nmip     | read only
304  // | step     |
305  // | prv      | 2 bits
306
307  val dcsrData = Wire(new DcsrStruct)
308  dcsrData := dcsr.asTypeOf(new DcsrStruct)
309  val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(2, 0), XLEN)// Dcsr write mask
310  def dcsrUpdateSideEffect(dcsr: UInt): UInt = {
311    val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct))
312    val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11
313    dcsrNew
314  }
315  csrio.singleStep := dcsrData.step
316
317  // Machine-Level CSRs
318
319  val mtvec = RegInit(UInt(XLEN.W), 0.U)
320  val mcounteren = RegInit(UInt(XLEN.W), 0.U)
321  val mcause = RegInit(UInt(XLEN.W), 0.U)
322  val mtval = RegInit(UInt(XLEN.W), 0.U)
323  val mepc = Reg(UInt(XLEN.W))
324
325  val mie = RegInit(0.U(XLEN.W))
326  val mipWire = WireInit(0.U.asTypeOf(new Interrupt))
327  val mipReg  = RegInit(0.U(XLEN.W))
328  val mipFixMask = ZeroExt(GenMask(9) | GenMask(5) | GenMask(1), XLEN)
329  val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt)
330
331  def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt()
332  def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt()
333  var extList = List('a', 's', 'i', 'u')
334  if (HasMExtension) { extList = extList :+ 'm' }
335  if (HasCExtension) { extList = extList :+ 'c' }
336  if (HasFPU) { extList = extList ++ List('f', 'd') }
337  val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U
338  val misa = RegInit(UInt(XLEN.W), misaInitVal)
339
340  // MXL = 2          | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101
341  // (XLEN-1, XLEN-2) |   |(25, 0)  ZY XWVU TSRQ PONM LKJI HGFE DCBA
342
343  val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation
344  val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented
345  val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation
346  val mhartid = RegInit(UInt(XLEN.W), csrio.hartId) // the hardware thread running the code
347  val mstatus = RegInit(UInt(XLEN.W), 0.U)
348
349  // mstatus Value Table
350  // | sd   |
351  // | pad1 |
352  // | sxl  | hardlinked to 10, use 00 to pass xv6 test
353  // | uxl  | hardlinked to 00
354  // | pad0 |
355  // | tsr  |
356  // | tw   |
357  // | tvm  |
358  // | mxr  |
359  // | sum  |
360  // | mprv |
361  // | xs   | 00 |
362  // | fs   | 00 |
363  // | mpp  | 00 |
364  // | hpp  | 00 |
365  // | spp  | 0 |
366  // | pie  | 0000 | pie.h is used as UBE
367  // | ie   | 0000 | uie hardlinked to 0, as N ext is not implemented
368
369  val mstatusStruct = mstatus.asTypeOf(new MstatusStruct)
370  def mstatusUpdateSideEffect(mstatus: UInt): UInt = {
371    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
372    val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0))
373    mstatusNew
374  }
375
376  val mstatusMask = (~ZeroExt((
377    GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) |
378    GenMask(37) | // MBE
379    GenMask(36) | // SBE
380    GenMask(6)    // UBE
381  ), 64)).asUInt()
382
383  val medeleg = RegInit(UInt(XLEN.W), 0.U)
384  val mideleg = RegInit(UInt(XLEN.W), 0.U)
385  val mscratch = RegInit(UInt(XLEN.W), 0.U)
386
387  // PMP Mapping
388  val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter
389  val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter
390  val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp)
391  val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma)
392
393  // Superviser-Level CSRs
394
395  // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U)
396  val sstatusWmask = "hc6122".U(XLEN.W)
397  // Sstatus Write Mask
398  // -------------------------------------------------------
399  //    19           9   5     2
400  // 0  1100 0000 0001 0010 0010
401  // 0  c    0    1    2    2
402  // -------------------------------------------------------
403  val sstatusRmask = sstatusWmask | "h8000000300018000".U
404  // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32))
405  val stvec = RegInit(UInt(XLEN.W), 0.U)
406  // val sie = RegInit(0.U(XLEN.W))
407  val sieMask = "h222".U & mideleg
408  val sipMask = "h222".U & mideleg
409  val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode
410  val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W))
411  // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug
412  // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0
413  // TODO: use config to control the length of asid
414  // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0
415  val satpMask = Cat("h8".U(4.W),Asid_true_mask(AsidLength),"hfffffffffff".U((XLEN - 4 - 16).W))
416  val sepc = RegInit(UInt(XLEN.W), 0.U)
417  val scause = RegInit(UInt(XLEN.W), 0.U)
418  val stval = Reg(UInt(XLEN.W))
419  val sscratch = RegInit(UInt(XLEN.W), 0.U)
420  val scounteren = RegInit(UInt(XLEN.W), 0.U)
421
422  // sbpctl
423  // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB}
424  val sbpctl = RegInit(UInt(XLEN.W), "h7f".U)
425  csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0)
426  csrio.customCtrl.bp_ctrl.btb_enable  := sbpctl(1)
427  csrio.customCtrl.bp_ctrl.bim_enable  := sbpctl(2)
428  csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3)
429  csrio.customCtrl.bp_ctrl.sc_enable   := sbpctl(4)
430  csrio.customCtrl.bp_ctrl.ras_enable  := sbpctl(5)
431  csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6)
432
433  // spfctl Bit 0: L1plusCache Prefetcher Enable
434  // spfctl Bit 1: L2Cache Prefetcher Enable
435  val spfctl = RegInit(UInt(XLEN.W), "h3".U)
436  csrio.customCtrl.l1plus_pf_enable := spfctl(0)
437  csrio.customCtrl.l2_pf_enable := spfctl(1)
438
439  // sdsid: Differentiated Services ID
440  val sdsid = RegInit(UInt(XLEN.W), 0.U)
441  csrio.customCtrl.dsid := sdsid
442
443  // slvpredctl: load violation predict settings
444  val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17
445  csrio.customCtrl.lvpred_disable := slvpredctl(0)
446  csrio.customCtrl.no_spec_load := slvpredctl(1)
447  csrio.customCtrl.storeset_wait_store := slvpredctl(2)
448  csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3)
449  csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4)
450
451  // smblockctl: memory block configurations
452  // bits 0-3: store buffer flush threshold (default: 8 entries)
453  val smblockctl_init_val =
454    ("hf".U & StoreBufferThreshold.U) |
455    (EnableLdVioCheckAfterReset.B.asUInt << 4)
456  val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val)
457  csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0)
458  // bits 4: enable load load violation check
459  csrio.customCtrl.ldld_vio_check := smblockctl(4)
460
461  val srnctl = RegInit(UInt(XLEN.W), "h3".U)
462  csrio.customCtrl.move_elim_enable := srnctl(0)
463  csrio.customCtrl.svinval_enable := srnctl(1)
464
465  val tlbBundle = Wire(new TlbCsrBundle)
466  tlbBundle.satp.apply(satp)
467
468  csrio.tlb := tlbBundle
469
470  // User-Level CSRs
471  val uepc = Reg(UInt(XLEN.W))
472
473  // fcsr
474  class FcsrStruct extends Bundle {
475    val reserved = UInt((XLEN-3-5).W)
476    val frm = UInt(3.W)
477    val fflags = UInt(5.W)
478    assert(this.getWidth == XLEN)
479  }
480  val fcsr = RegInit(0.U(XLEN.W))
481  // set mstatus->sd and mstatus->fs when true
482  val csrw_dirty_fp_state = WireInit(false.B)
483
484  def frm_wfn(wdata: UInt): UInt = {
485    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
486    csrw_dirty_fp_state := true.B
487    fcsrOld.frm := wdata(2,0)
488    fcsrOld.asUInt()
489  }
490  def frm_rfn(rdata: UInt): UInt = rdata(7,5)
491
492  def fflags_wfn(update: Boolean)(wdata: UInt): UInt = {
493    val fcsrOld = fcsr.asTypeOf(new FcsrStruct)
494    val fcsrNew = WireInit(fcsrOld)
495    csrw_dirty_fp_state := true.B
496    if (update) {
497      fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags
498    } else {
499      fcsrNew.fflags := wdata(4,0)
500    }
501    fcsrNew.asUInt()
502  }
503  def fflags_rfn(rdata:UInt): UInt = rdata(4,0)
504
505  def fcsr_wfn(wdata: UInt): UInt = {
506    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
507    csrw_dirty_fp_state := true.B
508    Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags)
509  }
510
511  val fcsrMapping = Map(
512    MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn),
513    MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn),
514    MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn)
515  )
516
517  // Hart Priviledge Mode
518  val priviledgeMode = RegInit(UInt(2.W), ModeM)
519
520  //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool())))
521  // Perf Counter
522  val nrPerfCnts = 29  // 3...31
523  val priviledgeModeOH = UIntToOH(priviledgeMode)
524  val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool())))
525  val perfCnts   = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W)))
526  val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W)))
527  for (i <-0 until nrPerfCnts) {
528    perfEventscounten(i) := (Cat(perfEvents(i)(62),perfEvents(i)(61),(perfEvents(i)(61,60))) & priviledgeModeOH).orR
529  }
530
531  val hpmEvents = Wire(new PerfEventsBundle(numPCntHc * coreParams.L2NBanks))
532  val pfevent = Module(new PFEvent)
533  pfevent.io.distribute_csr := csrio.customCtrl.distribute_csr
534  for(i <- 0 until numPCntHc * coreParams.L2NBanks) {
535    hpmEvents.perf_events(i).incr_step := csrio.perf.perfEventsHc(i)
536  }
537
538  val hpm_hc = Module(new HPerfmonitor(numPCntHc * coreParams.L2NBanks,numCSRPCntHc))
539  val csrevents = pfevent.io.hpmevent.slice(24,29)
540  hpm_hc.io.hpm_event := csrevents
541  hpm_hc.io.events_sets := hpmEvents
542  val mcountinhibit = RegInit(0.U(XLEN.W))
543  val mcycle = RegInit(0.U(XLEN.W))
544  mcycle := mcycle + 1.U
545  val minstret = RegInit(0.U(XLEN.W))
546  minstret := minstret + RegNext(csrio.perf.retiredInstr)
547  perfCnts( 0)  := Mux((mcountinhibit( 3) | perfEventscounten( 0)),perfCnts( 0) , (perfCnts( 0) + RegNext(csrio.perf.perfEventsFrontend.perf_events(0 ).incr_step)))
548  perfCnts( 1)  := Mux((mcountinhibit( 4) | perfEventscounten( 1)),perfCnts( 1) , (perfCnts( 1) + RegNext(csrio.perf.perfEventsFrontend.perf_events(1 ).incr_step)))
549  perfCnts( 2)  := Mux((mcountinhibit( 5) | perfEventscounten( 2)),perfCnts( 2) , (perfCnts( 2) + RegNext(csrio.perf.perfEventsFrontend.perf_events(2 ).incr_step)))
550  perfCnts( 3)  := Mux((mcountinhibit( 6) | perfEventscounten( 3)),perfCnts( 3) , (perfCnts( 3) + RegNext(csrio.perf.perfEventsFrontend.perf_events(3 ).incr_step)))
551  perfCnts( 4)  := Mux((mcountinhibit( 7) | perfEventscounten( 4)),perfCnts( 4) , (perfCnts( 4) + RegNext(csrio.perf.perfEventsFrontend.perf_events(4 ).incr_step)))
552  perfCnts( 5)  := Mux((mcountinhibit( 8) | perfEventscounten( 5)),perfCnts( 5) , (perfCnts( 5) + RegNext(csrio.perf.perfEventsFrontend.perf_events(5 ).incr_step)))
553  perfCnts( 6)  := Mux((mcountinhibit( 9) | perfEventscounten( 6)),perfCnts( 6) , (perfCnts( 6) + RegNext(csrio.perf.perfEventsFrontend.perf_events(6 ).incr_step)))
554  perfCnts( 7)  := Mux((mcountinhibit(10) | perfEventscounten( 7)),perfCnts( 7) , (perfCnts( 7) + RegNext(csrio.perf.perfEventsFrontend.perf_events(7 ).incr_step)))
555  perfCnts( 8)  := Mux((mcountinhibit(11) | perfEventscounten( 8)),perfCnts( 8) , (perfCnts( 8) + RegNext(csrio.perf.perfEventsCtrl.perf_events(0 ).incr_step)))
556  perfCnts( 9)  := Mux((mcountinhibit(12) | perfEventscounten( 9)),perfCnts( 9) , (perfCnts( 9) + RegNext(csrio.perf.perfEventsCtrl.perf_events(1 ).incr_step)))
557  perfCnts(10)  := Mux((mcountinhibit(13) | perfEventscounten(10)),perfCnts(10) , (perfCnts(10) + RegNext(csrio.perf.perfEventsCtrl.perf_events(2 ).incr_step)))
558  perfCnts(11)  := Mux((mcountinhibit(14) | perfEventscounten(11)),perfCnts(11) , (perfCnts(11) + RegNext(csrio.perf.perfEventsCtrl.perf_events(3 ).incr_step)))
559  perfCnts(12)  := Mux((mcountinhibit(15) | perfEventscounten(12)),perfCnts(12) , (perfCnts(12) + RegNext(csrio.perf.perfEventsCtrl.perf_events(4 ).incr_step)))
560  perfCnts(13)  := Mux((mcountinhibit(16) | perfEventscounten(13)),perfCnts(13) , (perfCnts(13) + RegNext(csrio.perf.perfEventsCtrl.perf_events(5 ).incr_step)))
561  perfCnts(14)  := Mux((mcountinhibit(17) | perfEventscounten(14)),perfCnts(14) , (perfCnts(14) + RegNext(csrio.perf.perfEventsCtrl.perf_events(6 ).incr_step)))
562  perfCnts(15)  := Mux((mcountinhibit(18) | perfEventscounten(15)),perfCnts(15) , (perfCnts(15) + RegNext(csrio.perf.perfEventsCtrl.perf_events(7 ).incr_step)))
563  perfCnts(16)  := Mux((mcountinhibit(19) | perfEventscounten(16)),perfCnts(16) , (perfCnts(16) + RegNext(csrio.perf.perfEventsLsu.perf_events(0 ).incr_step)))
564  perfCnts(17)  := Mux((mcountinhibit(20) | perfEventscounten(17)),perfCnts(17) , (perfCnts(17) + RegNext(csrio.perf.perfEventsLsu.perf_events(1 ).incr_step)))
565  perfCnts(18)  := Mux((mcountinhibit(21) | perfEventscounten(18)),perfCnts(18) , (perfCnts(18) + RegNext(csrio.perf.perfEventsLsu.perf_events(2 ).incr_step)))
566  perfCnts(19)  := Mux((mcountinhibit(22) | perfEventscounten(19)),perfCnts(19) , (perfCnts(19) + RegNext(csrio.perf.perfEventsLsu.perf_events(3 ).incr_step)))
567  perfCnts(20)  := Mux((mcountinhibit(23) | perfEventscounten(20)),perfCnts(20) , (perfCnts(20) + RegNext(csrio.perf.perfEventsLsu.perf_events(4 ).incr_step)))
568  perfCnts(21)  := Mux((mcountinhibit(24) | perfEventscounten(21)),perfCnts(21) , (perfCnts(21) + RegNext(csrio.perf.perfEventsLsu.perf_events(5 ).incr_step)))
569  perfCnts(22)  := Mux((mcountinhibit(25) | perfEventscounten(22)),perfCnts(22) , (perfCnts(22) + RegNext(csrio.perf.perfEventsLsu.perf_events(6 ).incr_step)))
570  perfCnts(23)  := Mux((mcountinhibit(26) | perfEventscounten(23)),perfCnts(23) , (perfCnts(23) + RegNext(csrio.perf.perfEventsLsu.perf_events(7 ).incr_step)))
571  perfCnts(24)  := Mux((mcountinhibit(27) | perfEventscounten(24)),perfCnts(24) , (perfCnts(24) + RegNext(hpm_hc.io.events_selected.perf_events(0 ).incr_step)))
572  perfCnts(25)  := Mux((mcountinhibit(28) | perfEventscounten(25)),perfCnts(25) , (perfCnts(25) + RegNext(hpm_hc.io.events_selected.perf_events(1 ).incr_step)))
573  perfCnts(26)  := Mux((mcountinhibit(29) | perfEventscounten(26)),perfCnts(26) , (perfCnts(26) + RegNext(hpm_hc.io.events_selected.perf_events(2 ).incr_step)))
574  perfCnts(27)  := Mux((mcountinhibit(30) | perfEventscounten(27)),perfCnts(27) , (perfCnts(27) + RegNext(hpm_hc.io.events_selected.perf_events(3 ).incr_step)))
575  perfCnts(28)  := Mux((mcountinhibit(31) | perfEventscounten(28)),perfCnts(28) , (perfCnts(28) + RegNext(hpm_hc.io.events_selected.perf_events(4 ).incr_step)))
576
577  // CSR reg map
578  val basicPrivMapping = Map(
579
580    //--- User Trap Setup ---
581    // MaskedRegMap(Ustatus, ustatus),
582    // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable),
583    // MaskedRegMap(Utvec, utvec),
584
585    //--- User Trap Handling ---
586    // MaskedRegMap(Uscratch, uscratch),
587    // MaskedRegMap(Uepc, uepc),
588    // MaskedRegMap(Ucause, ucause),
589    // MaskedRegMap(Utval, utval),
590    // MaskedRegMap(Uip, uip),
591
592    //--- User Counter/Timers ---
593    // MaskedRegMap(Cycle, cycle),
594    // MaskedRegMap(Time, time),
595    // MaskedRegMap(Instret, instret),
596
597    //--- Supervisor Trap Setup ---
598    MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask),
599    // MaskedRegMap(Sedeleg, Sedeleg),
600    // MaskedRegMap(Sideleg, Sideleg),
601    MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask),
602    MaskedRegMap(Stvec, stvec),
603    MaskedRegMap(Scounteren, scounteren),
604
605    //--- Supervisor Trap Handling ---
606    MaskedRegMap(Sscratch, sscratch),
607    MaskedRegMap(Sepc, sepc),
608    MaskedRegMap(Scause, scause),
609    MaskedRegMap(Stval, stval),
610    MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask),
611
612    //--- Supervisor Protection and Translation ---
613    MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask),
614
615    //--- Supervisor Custom Read/Write Registers
616    MaskedRegMap(Sbpctl, sbpctl),
617    MaskedRegMap(Spfctl, spfctl),
618    MaskedRegMap(Sdsid, sdsid),
619    MaskedRegMap(Slvpredctl, slvpredctl),
620    MaskedRegMap(Smblockctl, smblockctl),
621    MaskedRegMap(Srnctl, srnctl),
622
623    //--- Machine Information Registers ---
624    MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
625    MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
626    MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
627    MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
628
629    //--- Machine Trap Setup ---
630    MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask),
631    MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable
632    MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)),
633    MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)),
634    MaskedRegMap(Mie, mie),
635    MaskedRegMap(Mtvec, mtvec),
636    MaskedRegMap(Mcounteren, mcounteren),
637
638    //--- Machine Trap Handling ---
639    MaskedRegMap(Mscratch, mscratch),
640    MaskedRegMap(Mepc, mepc),
641    MaskedRegMap(Mcause, mcause),
642    MaskedRegMap(Mtval, mtval),
643    MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable),
644
645    //--- Debug Mode ---
646    MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect),
647    MaskedRegMap(Dpc, dpc),
648    MaskedRegMap(Dscratch, dscratch),
649    MaskedRegMap(Dscratch1, dscratch1)
650  )
651
652  var perfCntMapping = Map(
653    MaskedRegMap(Mcountinhibit, mcountinhibit),
654    MaskedRegMap(Mcycle, mcycle),
655    MaskedRegMap(Minstret, minstret),
656    MaskedRegMap(Mhpmevent3 , perfEvents( 0)),
657    MaskedRegMap(Mhpmevent4 , perfEvents( 1)),
658    MaskedRegMap(Mhpmevent5 , perfEvents( 2)),
659    MaskedRegMap(Mhpmevent6 , perfEvents( 3)),
660    MaskedRegMap(Mhpmevent7 , perfEvents( 4)),
661    MaskedRegMap(Mhpmevent8 , perfEvents( 5)),
662    MaskedRegMap(Mhpmevent9 , perfEvents( 6)),
663    MaskedRegMap(Mhpmevent10, perfEvents( 7)),
664    MaskedRegMap(Mhpmevent11, perfEvents( 8)),
665    MaskedRegMap(Mhpmevent12, perfEvents( 9)),
666    MaskedRegMap(Mhpmevent13, perfEvents(10)),
667    MaskedRegMap(Mhpmevent14, perfEvents(11)),
668    MaskedRegMap(Mhpmevent15, perfEvents(12)),
669    MaskedRegMap(Mhpmevent16, perfEvents(13)),
670    MaskedRegMap(Mhpmevent17, perfEvents(14)),
671    MaskedRegMap(Mhpmevent18, perfEvents(15)),
672    MaskedRegMap(Mhpmevent19, perfEvents(16)),
673    MaskedRegMap(Mhpmevent20, perfEvents(17)),
674    MaskedRegMap(Mhpmevent21, perfEvents(18)),
675    MaskedRegMap(Mhpmevent22, perfEvents(19)),
676    MaskedRegMap(Mhpmevent23, perfEvents(20)),
677    MaskedRegMap(Mhpmevent24, perfEvents(21)),
678    MaskedRegMap(Mhpmevent25, perfEvents(22)),
679    MaskedRegMap(Mhpmevent26, perfEvents(23)),
680    MaskedRegMap(Mhpmevent27, perfEvents(24)),
681    MaskedRegMap(Mhpmevent28, perfEvents(25)),
682    MaskedRegMap(Mhpmevent29, perfEvents(26)),
683    MaskedRegMap(Mhpmevent30, perfEvents(27)),
684    MaskedRegMap(Mhpmevent31, perfEvents(28)),
685    MaskedRegMap(Mhpmcounter3 , perfCnts( 0)),
686    MaskedRegMap(Mhpmcounter4 , perfCnts( 1)),
687    MaskedRegMap(Mhpmcounter5 , perfCnts( 2)),
688    MaskedRegMap(Mhpmcounter6 , perfCnts( 3)),
689    MaskedRegMap(Mhpmcounter7 , perfCnts( 4)),
690    MaskedRegMap(Mhpmcounter8 , perfCnts( 5)),
691    MaskedRegMap(Mhpmcounter9 , perfCnts( 6)),
692    MaskedRegMap(Mhpmcounter10, perfCnts( 7)),
693    MaskedRegMap(Mhpmcounter11, perfCnts( 8)),
694    MaskedRegMap(Mhpmcounter12, perfCnts( 9)),
695    MaskedRegMap(Mhpmcounter13, perfCnts(10)),
696    MaskedRegMap(Mhpmcounter14, perfCnts(11)),
697    MaskedRegMap(Mhpmcounter15, perfCnts(12)),
698    MaskedRegMap(Mhpmcounter16, perfCnts(13)),
699    MaskedRegMap(Mhpmcounter17, perfCnts(14)),
700    MaskedRegMap(Mhpmcounter18, perfCnts(15)),
701    MaskedRegMap(Mhpmcounter19, perfCnts(16)),
702    MaskedRegMap(Mhpmcounter20, perfCnts(17)),
703    MaskedRegMap(Mhpmcounter21, perfCnts(18)),
704    MaskedRegMap(Mhpmcounter22, perfCnts(19)),
705    MaskedRegMap(Mhpmcounter23, perfCnts(20)),
706    MaskedRegMap(Mhpmcounter24, perfCnts(21)),
707    MaskedRegMap(Mhpmcounter25, perfCnts(22)),
708    MaskedRegMap(Mhpmcounter26, perfCnts(23)),
709    MaskedRegMap(Mhpmcounter27, perfCnts(24)),
710    MaskedRegMap(Mhpmcounter28, perfCnts(25)),
711    MaskedRegMap(Mhpmcounter29, perfCnts(26)),
712    MaskedRegMap(Mhpmcounter30, perfCnts(27)),
713    MaskedRegMap(Mhpmcounter31, perfCnts(28)),
714  )
715  // TODO: mechanism should be implemented later
716  // val MhpmcounterStart = Mhpmcounter3
717  // val MhpmeventStart   = Mhpmevent3
718  // for (i <- 0 until nrPerfCnts) {
719  //   perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i))
720  //   perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i))
721  // }
722
723  val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
724    name -> RegInit(0.U(attribute("width").toInt.W))
725  }}
726  val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
727    MaskedRegMap(
728      Scachebase + attribute("offset").toInt,
729      cacheopRegs(name)
730    )
731  }}
732
733  val mapping = basicPrivMapping ++
734                perfCntMapping ++
735                pmpMapping ++
736                pmaMapping ++
737                (if (HasFPU) fcsrMapping else Nil) ++
738                (if (HasCustomCSRCacheOp) cacheopMapping else Nil)
739
740  val addr = src2(11, 0)
741  val csri = ZeroExt(src2(16, 12), XLEN)
742  val rdata = Wire(UInt(XLEN.W))
743  val wdata = LookupTree(func, List(
744    CSROpType.wrt  -> src1,
745    CSROpType.set  -> (rdata | src1),
746    CSROpType.clr  -> (rdata & (~src1).asUInt()),
747    CSROpType.wrti -> csri,
748    CSROpType.seti -> (rdata | csri),
749    CSROpType.clri -> (rdata & (~csri).asUInt())
750  ))
751
752  val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U)
753  csrio.isPerfCnt := addrInPerfCnt
754
755  // satp wen check
756  val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U)
757
758  // csr access check, special case
759  val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool)
760  val accessPermitted = !(addr === Satp.U && tvmNotPermit)
761  csrio.disableSfence := tvmNotPermit
762
763  // general CSR wen check
764  val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode)
765  val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode)
766  val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren)
767  val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted
768
769  // Writeable check is ingored.
770  // Currently, write to illegal csr addr will be ignored
771  MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata)
772  io.out.bits.data := rdata
773  io.out.bits.uop := io.in.bits.uop
774  io.out.bits.uop.cf := cfOut
775  io.out.bits.uop.ctrl.flushPipe := flushPipe
776
777  // send distribute csr a w signal
778  csrio.customCtrl.distribute_csr.w.valid := wen && permitted
779  csrio.customCtrl.distribute_csr.w.bits.data := wdata
780  csrio.customCtrl.distribute_csr.w.bits.addr := addr
781
782  // Fix Mip/Sip write
783  val fixMapping = Map(
784    MaskedRegMap(Mip, mipReg.asUInt, mipFixMask),
785    MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask)
786  )
787  val rdataFix = Wire(UInt(XLEN.W))
788  val wdataFix = LookupTree(func, List(
789    CSROpType.wrt  -> src1,
790    CSROpType.set  -> (rdataFix | src1),
791    CSROpType.clr  -> (rdataFix & (~src1).asUInt()),
792    CSROpType.wrti -> csri,
793    CSROpType.seti -> (rdataFix | csri),
794    CSROpType.clri -> (rdataFix & (~csri).asUInt())
795  ))
796  MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix)
797
798  when (csrio.fpu.fflags.valid) {
799    fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits)
800  }
801  // set fs and sd in mstatus
802  when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) {
803    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
804    mstatusNew.fs := "b11".U
805    mstatusNew.sd := true.B
806    mstatus := mstatusNew.asUInt()
807  }
808  csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm
809
810  // CSR inst decode
811  val isEbreak = addr === privEbreak && func === CSROpType.jmp
812  val isEcall  = addr === privEcall  && func === CSROpType.jmp
813  val isMret   = addr === privMret   && func === CSROpType.jmp
814  val isSret   = addr === privSret   && func === CSROpType.jmp
815  val isUret   = addr === privUret   && func === CSROpType.jmp
816  val isDret   = addr === privDret   && func === CSROpType.jmp
817
818  XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func)
819  XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode)
820
821  // Illegal priviledged operation list
822  val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool
823
824  // Illegal priviledged instruction check
825  val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr)
826  val isIllegalAccess = !permitted
827  val isIllegalPrivOp = illegalSModeSret
828
829  // expose several csr bits for tlb
830  tlbBundle.priv.mxr   := mstatusStruct.mxr.asBool
831  tlbBundle.priv.sum   := mstatusStruct.sum.asBool
832  tlbBundle.priv.imode := priviledgeMode
833  tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode)
834
835  // Branch control
836  val retTarget = Wire(UInt(VAddrBits.W))
837  val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed
838  flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall)
839
840  retTarget := DontCare
841  // val illegalEret = TODO
842
843  when (valid && isDret) {
844    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
845    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
846    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
847    val debugModeNew = WireInit(debugMode)
848    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.
849    mstatus := mstatusNew.asUInt
850    priviledgeMode := dcsrNew.prv
851    retTarget := dpc(VAddrBits-1, 0)
852    debugModeNew := false.B
853    debugIntrEnable := true.B
854    debugMode := debugModeNew
855    XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget)
856  }
857
858  when (valid && isMret) {
859    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
860    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
861    mstatusNew.ie.m := mstatusOld.pie.m
862    priviledgeMode := mstatusOld.mpp
863    mstatusNew.pie.m := true.B
864    mstatusNew.mpp := ModeU
865    when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U }
866    mstatus := mstatusNew.asUInt
867    // lr := false.B
868    retTarget := mepc(VAddrBits-1, 0)
869  }
870
871  when (valid && isSret && !illegalSModeSret) {
872    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
873    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
874    mstatusNew.ie.s := mstatusOld.pie.s
875    priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
876    mstatusNew.pie.s := true.B
877    mstatusNew.spp := ModeU
878    mstatus := mstatusNew.asUInt
879    mstatusNew.mprv := 0.U
880    // lr := false.B
881    retTarget := sepc(VAddrBits-1, 0)
882  }
883
884  when (valid && isUret) {
885    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
886    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
887    // mstatusNew.mpp.m := ModeU //TODO: add mode U
888    mstatusNew.ie.u := mstatusOld.pie.u
889    priviledgeMode := ModeU
890    mstatusNew.pie.u := true.B
891    mstatus := mstatusNew.asUInt
892    retTarget := uepc(VAddrBits-1, 0)
893  }
894
895  io.in.ready := true.B
896  io.out.valid := valid
897
898  val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku)
899
900  val csrExceptionVec = WireInit(cfIn.exceptionVec)
901  csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException
902  csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
903  csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
904  csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
905  // Trigger an illegal instr exception when:
906  // * unimplemented csr is being read/written
907  // * csr access is illegal
908  csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
909  cfOut.exceptionVec := csrExceptionVec
910
911  /**
912    * Exception and Intr
913    */
914  val ideleg =  (mideleg & mip.asUInt)
915  def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS),
916    ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM))
917
918  val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable
919  XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!")
920  // send interrupt information to ROB
921  val intrVecEnable = Wire(Vec(12, Bool()))
922  intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)}
923  val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt))
924  val intrBitSet = intrVec.orR()
925  csrio.interrupt := intrBitSet
926  mipWire.t.m := csrio.externalInterrupt.mtip
927  mipWire.s.m := csrio.externalInterrupt.msip
928  mipWire.e.m := csrio.externalInterrupt.meip
929  mipWire.e.s := csrio.externalInterrupt.meip
930
931  // interrupts
932  val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
933  val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt
934  XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO)
935  val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr
936
937  // exceptions
938  val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt
939  val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException
940  val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException
941  val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException
942  val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException
943  val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException
944  val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException
945  val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException
946  val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException
947  val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException
948  val hasSingleStep = csrio.exception.bits.uop.cf.exceptionVec(singleStep) && raiseException
949
950  val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec
951  val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
952  val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
953
954  val raiseExceptionIntr = csrio.exception.valid
955
956  val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep
957  val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ???
958
959  XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
960    csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt
961  )
962  XSDebug(raiseExceptionIntr,
963    "pc %x mstatus %x mideleg %x medeleg %x mode %x\n",
964    csrio.exception.bits.uop.cf.pc,
965    mstatus,
966    mideleg,
967    medeleg,
968    priviledgeMode
969  )
970
971  // mtval write logic
972  val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
973  when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) {
974    val tval = Mux(
975      hasInstrPageFault,
976      Mux(
977        csrio.exception.bits.uop.cf.crossPageIPFFix,
978        SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN),
979        SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
980      ),
981      memExceptionAddr
982    )
983    when (priviledgeMode === ModeM) {
984      mtval := tval
985    }.otherwise {
986      stval := tval
987    }
988  }
989
990  when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) {
991    mtval := memExceptionAddr
992  }
993
994  val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec
995  val deleg = Mux(raiseIntr, mideleg , medeleg)
996  // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM);
997  val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM)
998  val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check
999  val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak
1000
1001  // ctrl block will use theses later for flush
1002  val isXRetFlag = RegInit(false.B)
1003  val retTargetReg = Reg(retTarget.cloneType)
1004  when (io.redirectIn.valid) {
1005    isXRetFlag := false.B
1006  }.elsewhen (isXRet) {
1007    isXRetFlag := true.B
1008    retTargetReg := retTarget
1009  }
1010  csrio.isXRet := isXRetFlag
1011  csrio.trapTarget := Mux(isXRetFlag,
1012    retTargetReg,
1013    Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget,
1014      Mux(delegS, stvec, mtvec))(VAddrBits-1, 0)
1015  )
1016
1017  when (raiseExceptionIntr) {
1018    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
1019    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
1020    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
1021    val debugModeNew = WireInit(debugMode)
1022
1023    when (raiseDebugExceptionIntr) {
1024      when (raiseDebugIntr) {
1025        debugModeNew := true.B
1026        mstatusNew.mprv := false.B
1027        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1028        dcsrNew.cause := 1.U
1029        dcsrNew.prv := priviledgeMode
1030        priviledgeMode := ModeM
1031        XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc)
1032      }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) {
1033        // ebreak or ss in running hart
1034        debugModeNew := true.B
1035        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1036        dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U)
1037        dcsrNew.prv := priviledgeMode // TODO
1038        priviledgeMode := ModeM
1039        mstatusNew.mprv := false.B
1040      }
1041      dcsr := dcsrNew.asUInt
1042      debugIntrEnable := false.B
1043    }.elsewhen (delegS) {
1044      scause := causeNO
1045      sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1046      mstatusNew.spp := priviledgeMode
1047      mstatusNew.pie.s := mstatusOld.ie.s
1048      mstatusNew.ie.s := false.B
1049      priviledgeMode := ModeS
1050      when (tvalWen) { stval := 0.U }
1051    }.otherwise {
1052      mcause := causeNO
1053      mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1054      mstatusNew.mpp := priviledgeMode
1055      mstatusNew.pie.m := mstatusOld.ie.m
1056      mstatusNew.ie.m := false.B
1057      priviledgeMode := ModeM
1058      when (tvalWen) { mtval := 0.U }
1059    }
1060    mstatus := mstatusNew.asUInt
1061    debugMode := debugModeNew
1062  }
1063
1064  XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc)
1065
1066  // Distributed CSR update req
1067  //
1068  // For now we use it to implement customized cache op
1069
1070  when(csrio.distributedUpdate.w.valid){
1071    // cacheopRegs can be distributed updated
1072    CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
1073      when((Scachebase + attribute("offset").toInt).U === csrio.distributedUpdate.w.bits.addr){
1074        cacheopRegs(name) := csrio.distributedUpdate.w.bits.data
1075      }
1076    }}
1077  }
1078
1079  def readWithScala(addr: Int): UInt = mapping(addr)._1
1080
1081  val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
1082
1083  if (env.EnableDifftest) {
1084    val difftest = Module(new DifftestArchEvent)
1085    difftest.io.clock := clock
1086    difftest.io.coreid := hardId.U
1087    difftest.io.intrNO := RegNext(difftestIntrNO)
1088    difftest.io.cause := RegNext(Mux(csrio.exception.valid, causeNO, 0.U))
1089    difftest.io.exceptionPC := RegNext(SignExt(csrio.exception.bits.uop.cf.pc, XLEN))
1090  }
1091
1092  if (env.EnableDifftest) {
1093    val difftest = Module(new DifftestCSRState)
1094    difftest.io.clock := clock
1095    difftest.io.coreid := hardId.U
1096    difftest.io.priviledgeMode := priviledgeMode
1097    difftest.io.mstatus := mstatus
1098    difftest.io.sstatus := mstatus & sstatusRmask
1099    difftest.io.mepc := mepc
1100    difftest.io.sepc := sepc
1101    difftest.io.mtval:= mtval
1102    difftest.io.stval:= stval
1103    difftest.io.mtvec := mtvec
1104    difftest.io.stvec := stvec
1105    difftest.io.mcause := mcause
1106    difftest.io.scause := scause
1107    difftest.io.satp := satp
1108    difftest.io.mip := mipReg
1109    difftest.io.mie := mie
1110    difftest.io.mscratch := mscratch
1111    difftest.io.sscratch := sscratch
1112    difftest.io.mideleg := mideleg
1113    difftest.io.medeleg := medeleg
1114  }
1115}
1116
1117class PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst  {
1118  val io = IO(new Bundle {
1119    val distribute_csr = Flipped(new DistributedCSRIO())
1120    val hpmevent = Output(Vec(29, UInt(XLEN.W)))
1121  })
1122
1123  val w = io.distribute_csr.w
1124
1125  //val csrevents = Vec(29,RegInit(UInt(XLEN.W), 0.U))
1126  val csrevent3  = RegInit(UInt(XLEN.W), 0.U)
1127  val csrevent4  = RegInit(UInt(XLEN.W), 0.U)
1128  val csrevent5  = RegInit(UInt(XLEN.W), 0.U)
1129  val csrevent6  = RegInit(UInt(XLEN.W), 0.U)
1130  val csrevent7  = RegInit(UInt(XLEN.W), 0.U)
1131  val csrevent8  = RegInit(UInt(XLEN.W), 0.U)
1132  val csrevent9  = RegInit(UInt(XLEN.W), 0.U)
1133  val csrevent10 = RegInit(UInt(XLEN.W), 0.U)
1134  val csrevent11 = RegInit(UInt(XLEN.W), 0.U)
1135  val csrevent12 = RegInit(UInt(XLEN.W), 0.U)
1136  val csrevent13 = RegInit(UInt(XLEN.W), 0.U)
1137  val csrevent14 = RegInit(UInt(XLEN.W), 0.U)
1138  val csrevent15 = RegInit(UInt(XLEN.W), 0.U)
1139  val csrevent16 = RegInit(UInt(XLEN.W), 0.U)
1140  val csrevent17 = RegInit(UInt(XLEN.W), 0.U)
1141  val csrevent18 = RegInit(UInt(XLEN.W), 0.U)
1142  val csrevent19 = RegInit(UInt(XLEN.W), 0.U)
1143  val csrevent20 = RegInit(UInt(XLEN.W), 0.U)
1144  val csrevent21 = RegInit(UInt(XLEN.W), 0.U)
1145  val csrevent22 = RegInit(UInt(XLEN.W), 0.U)
1146  val csrevent23 = RegInit(UInt(XLEN.W), 0.U)
1147  val csrevent24 = RegInit(UInt(XLEN.W), 0.U)
1148  val csrevent25 = RegInit(UInt(XLEN.W), 0.U)
1149  val csrevent26 = RegInit(UInt(XLEN.W), 0.U)
1150  val csrevent27 = RegInit(UInt(XLEN.W), 0.U)
1151  val csrevent28 = RegInit(UInt(XLEN.W), 0.U)
1152  val csrevent29 = RegInit(UInt(XLEN.W), 0.U)
1153  val csrevent30 = RegInit(UInt(XLEN.W), 0.U)
1154  val csrevent31 = RegInit(UInt(XLEN.W), 0.U)
1155
1156  var perfEventMapping = Map(
1157    MaskedRegMap(Mhpmevent3, csrevent3 ),
1158    MaskedRegMap(Mhpmevent4, csrevent4 ),
1159    MaskedRegMap(Mhpmevent5, csrevent5 ),
1160    MaskedRegMap(Mhpmevent6, csrevent6 ),
1161    MaskedRegMap(Mhpmevent7, csrevent7 ),
1162    MaskedRegMap(Mhpmevent8, csrevent8 ),
1163    MaskedRegMap(Mhpmevent9, csrevent9 ),
1164    MaskedRegMap(Mhpmevent10,csrevent10),
1165    MaskedRegMap(Mhpmevent11,csrevent11),
1166    MaskedRegMap(Mhpmevent12,csrevent12),
1167    MaskedRegMap(Mhpmevent13,csrevent13),
1168    MaskedRegMap(Mhpmevent14,csrevent14),
1169    MaskedRegMap(Mhpmevent15,csrevent15),
1170    MaskedRegMap(Mhpmevent16,csrevent16),
1171    MaskedRegMap(Mhpmevent17,csrevent17),
1172    MaskedRegMap(Mhpmevent18,csrevent18),
1173    MaskedRegMap(Mhpmevent19,csrevent19),
1174    MaskedRegMap(Mhpmevent20,csrevent20),
1175    MaskedRegMap(Mhpmevent21,csrevent21),
1176    MaskedRegMap(Mhpmevent22,csrevent22),
1177    MaskedRegMap(Mhpmevent23,csrevent23),
1178    MaskedRegMap(Mhpmevent24,csrevent24),
1179    MaskedRegMap(Mhpmevent25,csrevent25),
1180    MaskedRegMap(Mhpmevent26,csrevent26),
1181    MaskedRegMap(Mhpmevent27,csrevent27),
1182    MaskedRegMap(Mhpmevent28,csrevent28),
1183    MaskedRegMap(Mhpmevent29,csrevent29),
1184    MaskedRegMap(Mhpmevent30,csrevent30),
1185    MaskedRegMap(Mhpmevent31,csrevent31),
1186  )
1187
1188  val rdata = Wire(UInt(XLEN.W))
1189  MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data)
1190  io.hpmevent( 0) := csrevent3
1191  io.hpmevent( 1) := csrevent4
1192  io.hpmevent( 2) := csrevent5
1193  io.hpmevent( 3) := csrevent6
1194  io.hpmevent( 4) := csrevent7
1195  io.hpmevent( 5) := csrevent8
1196  io.hpmevent( 6) := csrevent9
1197  io.hpmevent( 7) := csrevent10
1198  io.hpmevent( 8) := csrevent11
1199  io.hpmevent( 9) := csrevent12
1200  io.hpmevent(10) := csrevent13
1201  io.hpmevent(11) := csrevent14
1202  io.hpmevent(12) := csrevent15
1203  io.hpmevent(13) := csrevent16
1204  io.hpmevent(14) := csrevent17
1205  io.hpmevent(15) := csrevent18
1206  io.hpmevent(16) := csrevent19
1207  io.hpmevent(17) := csrevent20
1208  io.hpmevent(18) := csrevent21
1209  io.hpmevent(19) := csrevent22
1210  io.hpmevent(20) := csrevent23
1211  io.hpmevent(21) := csrevent24
1212  io.hpmevent(22) := csrevent25
1213  io.hpmevent(23) := csrevent26
1214  io.hpmevent(24) := csrevent27
1215  io.hpmevent(25) := csrevent28
1216  io.hpmevent(26) := csrevent29
1217  io.hpmevent(27) := csrevent30
1218  io.hpmevent(28) := csrevent31
1219}
1220
1221