xref: /XiangShan/src/main/scala/xiangshan/backend/fu/CSR.scala (revision 066ac8a465b27b54ba22458ff1a67bcd28215d73)
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  // to Fence to disable sfence
194  val disableSfence = Output(Bool())
195  // Custom microarchiture ctrl signal
196  val customCtrl = Output(new CustomCSRCtrlIO)
197  // distributed csr write
198  val distributedUpdate = Flipped(new DistributedCSRUpdateReq)
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    (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U)
754  csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp
755
756  // satp wen check
757  val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U)
758
759  // csr access check, special case
760  val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool)
761  val accessPermitted = !(addr === Satp.U && tvmNotPermit)
762  csrio.disableSfence := tvmNotPermit
763
764  // general CSR wen check
765  val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode)
766  val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode)
767  val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren)
768  val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted
769
770  MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata)
771  io.out.bits.data := rdata
772  io.out.bits.uop := io.in.bits.uop
773  io.out.bits.uop.cf := cfOut
774  io.out.bits.uop.ctrl.flushPipe := flushPipe
775
776  // send distribute csr a w signal
777  csrio.customCtrl.distribute_csr.w.valid := wen && permitted
778  csrio.customCtrl.distribute_csr.w.bits.data := wdata
779  csrio.customCtrl.distribute_csr.w.bits.addr := addr
780
781  // Fix Mip/Sip write
782  val fixMapping = Map(
783    MaskedRegMap(Mip, mipReg.asUInt, mipFixMask),
784    MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask)
785  )
786  val rdataFix = Wire(UInt(XLEN.W))
787  val wdataFix = LookupTree(func, List(
788    CSROpType.wrt  -> src1,
789    CSROpType.set  -> (rdataFix | src1),
790    CSROpType.clr  -> (rdataFix & (~src1).asUInt()),
791    CSROpType.wrti -> csri,
792    CSROpType.seti -> (rdataFix | csri),
793    CSROpType.clri -> (rdataFix & (~csri).asUInt())
794  ))
795  MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix)
796
797  when (csrio.fpu.fflags.valid) {
798    fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits)
799  }
800  // set fs and sd in mstatus
801  when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) {
802    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
803    mstatusNew.fs := "b11".U
804    mstatusNew.sd := true.B
805    mstatus := mstatusNew.asUInt()
806  }
807  csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm
808
809  // CSR inst decode
810  val isEbreak = addr === privEbreak && func === CSROpType.jmp
811  val isEcall  = addr === privEcall  && func === CSROpType.jmp
812  val isMret   = addr === privMret   && func === CSROpType.jmp
813  val isSret   = addr === privSret   && func === CSROpType.jmp
814  val isUret   = addr === privUret   && func === CSROpType.jmp
815  val isDret   = addr === privDret   && func === CSROpType.jmp
816
817  XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func)
818  XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode)
819
820  // Illegal priviledged operation list
821  val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool
822
823  // Illegal priviledged instruction check
824  val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr)
825  val isIllegalAccess = !permitted
826  val isIllegalPrivOp = illegalSModeSret
827
828  // expose several csr bits for tlb
829  tlbBundle.priv.mxr   := mstatusStruct.mxr.asBool
830  tlbBundle.priv.sum   := mstatusStruct.sum.asBool
831  tlbBundle.priv.imode := priviledgeMode
832  tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode)
833
834  // Branch control
835  val retTarget = Wire(UInt(VAddrBits.W))
836  val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed
837  flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall)
838
839  retTarget := DontCare
840  // val illegalEret = TODO
841
842  when (valid && isDret) {
843    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
844    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
845    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
846    val debugModeNew = WireInit(debugMode)
847    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.
848    mstatus := mstatusNew.asUInt
849    priviledgeMode := dcsrNew.prv
850    retTarget := dpc(VAddrBits-1, 0)
851    debugModeNew := false.B
852    debugIntrEnable := true.B
853    debugMode := debugModeNew
854    XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget)
855  }
856
857  when (valid && isMret) {
858    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
859    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
860    mstatusNew.ie.m := mstatusOld.pie.m
861    priviledgeMode := mstatusOld.mpp
862    mstatusNew.pie.m := true.B
863    mstatusNew.mpp := ModeU
864    when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U }
865    mstatus := mstatusNew.asUInt
866    // lr := false.B
867    retTarget := mepc(VAddrBits-1, 0)
868  }
869
870  when (valid && isSret && !illegalSModeSret) {
871    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
872    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
873    mstatusNew.ie.s := mstatusOld.pie.s
874    priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
875    mstatusNew.pie.s := true.B
876    mstatusNew.spp := ModeU
877    mstatus := mstatusNew.asUInt
878    mstatusNew.mprv := 0.U
879    // lr := false.B
880    retTarget := sepc(VAddrBits-1, 0)
881  }
882
883  when (valid && isUret) {
884    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
885    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
886    // mstatusNew.mpp.m := ModeU //TODO: add mode U
887    mstatusNew.ie.u := mstatusOld.pie.u
888    priviledgeMode := ModeU
889    mstatusNew.pie.u := true.B
890    mstatus := mstatusNew.asUInt
891    retTarget := uepc(VAddrBits-1, 0)
892  }
893
894  io.in.ready := true.B
895  io.out.valid := valid
896
897  val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku)
898
899  val csrExceptionVec = WireInit(cfIn.exceptionVec)
900  csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException
901  csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
902  csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
903  csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
904  // Trigger an illegal instr exception when:
905  // * unimplemented csr is being read/written
906  // * csr access is illegal
907  csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
908  cfOut.exceptionVec := csrExceptionVec
909
910  /**
911    * Exception and Intr
912    */
913  val ideleg =  (mideleg & mip.asUInt)
914  def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS),
915    ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM))
916
917  val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable
918  XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!")
919  // send interrupt information to ROB
920  val intrVecEnable = Wire(Vec(12, Bool()))
921  intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)}
922  val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt))
923  val intrBitSet = intrVec.orR()
924  csrio.interrupt := intrBitSet
925  mipWire.t.m := csrio.externalInterrupt.mtip
926  mipWire.s.m := csrio.externalInterrupt.msip
927  mipWire.e.m := csrio.externalInterrupt.meip
928  mipWire.e.s := csrio.externalInterrupt.seip
929
930  // interrupts
931  val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
932  val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt
933  XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO)
934  val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr
935
936  // exceptions
937  val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt
938  val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException
939  val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException
940  val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException
941  val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException
942  val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException
943  val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException
944  val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException
945  val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException
946  val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException
947  val hasSingleStep = csrio.exception.bits.uop.cf.exceptionVec(singleStep) && raiseException
948
949  val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec
950  val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
951  val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
952
953  val raiseExceptionIntr = csrio.exception.valid
954
955  val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep
956  val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ???
957
958  XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
959    csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt
960  )
961  XSDebug(raiseExceptionIntr,
962    "pc %x mstatus %x mideleg %x medeleg %x mode %x\n",
963    csrio.exception.bits.uop.cf.pc,
964    mstatus,
965    mideleg,
966    medeleg,
967    priviledgeMode
968  )
969
970  // mtval write logic
971  val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
972  when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) {
973    val tval = Mux(
974      hasInstrPageFault,
975      Mux(
976        csrio.exception.bits.uop.cf.crossPageIPFFix,
977        SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN),
978        SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
979      ),
980      memExceptionAddr
981    )
982    when (priviledgeMode === ModeM) {
983      mtval := tval
984    }.otherwise {
985      stval := tval
986    }
987  }
988
989  when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) {
990    mtval := memExceptionAddr
991  }
992
993  val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec
994  val deleg = Mux(raiseIntr, mideleg , medeleg)
995  // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM);
996  val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM)
997  val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check
998  val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak
999
1000  // ctrl block will use theses later for flush
1001  val isXRetFlag = RegInit(false.B)
1002  val retTargetReg = Reg(retTarget.cloneType)
1003  when (io.redirectIn.valid) {
1004    isXRetFlag := false.B
1005  }.elsewhen (isXRet) {
1006    isXRetFlag := true.B
1007    retTargetReg := retTarget
1008  }
1009  csrio.isXRet := isXRetFlag
1010  csrio.trapTarget := Mux(isXRetFlag,
1011    retTargetReg,
1012    Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget,
1013      Mux(delegS, stvec, mtvec))(VAddrBits-1, 0)
1014  )
1015
1016  when (raiseExceptionIntr) {
1017    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
1018    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
1019    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
1020    val debugModeNew = WireInit(debugMode)
1021
1022    when (raiseDebugExceptionIntr) {
1023      when (raiseDebugIntr) {
1024        debugModeNew := true.B
1025        mstatusNew.mprv := false.B
1026        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1027        dcsrNew.cause := 1.U
1028        dcsrNew.prv := priviledgeMode
1029        priviledgeMode := ModeM
1030        XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc)
1031      }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) {
1032        // ebreak or ss in running hart
1033        debugModeNew := true.B
1034        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1035        dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U)
1036        dcsrNew.prv := priviledgeMode // TODO
1037        priviledgeMode := ModeM
1038        mstatusNew.mprv := false.B
1039      }
1040      dcsr := dcsrNew.asUInt
1041      debugIntrEnable := false.B
1042    }.elsewhen (delegS) {
1043      scause := causeNO
1044      sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1045      mstatusNew.spp := priviledgeMode
1046      mstatusNew.pie.s := mstatusOld.ie.s
1047      mstatusNew.ie.s := false.B
1048      priviledgeMode := ModeS
1049      when (tvalWen) { stval := 0.U }
1050    }.otherwise {
1051      mcause := causeNO
1052      mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1053      mstatusNew.mpp := priviledgeMode
1054      mstatusNew.pie.m := mstatusOld.ie.m
1055      mstatusNew.ie.m := false.B
1056      priviledgeMode := ModeM
1057      when (tvalWen) { mtval := 0.U }
1058    }
1059    mstatus := mstatusNew.asUInt
1060    debugMode := debugModeNew
1061  }
1062
1063  XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc)
1064
1065  // Distributed CSR update req
1066  //
1067  // For now we use it to implement customized cache op
1068
1069  when(csrio.distributedUpdate.w.valid){
1070    // cacheopRegs can be distributed updated
1071    CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
1072      when((Scachebase + attribute("offset").toInt).U === csrio.distributedUpdate.w.bits.addr){
1073        cacheopRegs(name) := csrio.distributedUpdate.w.bits.data
1074      }
1075    }}
1076  }
1077
1078  def readWithScala(addr: Int): UInt = mapping(addr)._1
1079
1080  val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
1081
1082  // Always instantiate basic difftest modules.
1083  if (env.AlwaysBasicDiff || 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  // Always instantiate basic difftest modules.
1093  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1094    val difftest = Module(new DifftestCSRState)
1095    difftest.io.clock := clock
1096    difftest.io.coreid := hardId.U
1097    difftest.io.priviledgeMode := priviledgeMode
1098    difftest.io.mstatus := mstatus
1099    difftest.io.sstatus := mstatus & sstatusRmask
1100    difftest.io.mepc := mepc
1101    difftest.io.sepc := sepc
1102    difftest.io.mtval:= mtval
1103    difftest.io.stval:= stval
1104    difftest.io.mtvec := mtvec
1105    difftest.io.stvec := stvec
1106    difftest.io.mcause := mcause
1107    difftest.io.scause := scause
1108    difftest.io.satp := satp
1109    difftest.io.mip := mipReg
1110    difftest.io.mie := mie
1111    difftest.io.mscratch := mscratch
1112    difftest.io.sscratch := sscratch
1113    difftest.io.mideleg := mideleg
1114    difftest.io.medeleg := medeleg
1115  }
1116}
1117
1118class PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst  {
1119  val io = IO(new Bundle {
1120    val distribute_csr = Flipped(new DistributedCSRIO())
1121    val hpmevent = Output(Vec(29, UInt(XLEN.W)))
1122  })
1123
1124  val w = io.distribute_csr.w
1125
1126  //val csrevents = Vec(29,RegInit(UInt(XLEN.W), 0.U))
1127  val csrevent3  = RegInit(UInt(XLEN.W), 0.U)
1128  val csrevent4  = RegInit(UInt(XLEN.W), 0.U)
1129  val csrevent5  = RegInit(UInt(XLEN.W), 0.U)
1130  val csrevent6  = RegInit(UInt(XLEN.W), 0.U)
1131  val csrevent7  = RegInit(UInt(XLEN.W), 0.U)
1132  val csrevent8  = RegInit(UInt(XLEN.W), 0.U)
1133  val csrevent9  = RegInit(UInt(XLEN.W), 0.U)
1134  val csrevent10 = RegInit(UInt(XLEN.W), 0.U)
1135  val csrevent11 = RegInit(UInt(XLEN.W), 0.U)
1136  val csrevent12 = RegInit(UInt(XLEN.W), 0.U)
1137  val csrevent13 = RegInit(UInt(XLEN.W), 0.U)
1138  val csrevent14 = RegInit(UInt(XLEN.W), 0.U)
1139  val csrevent15 = RegInit(UInt(XLEN.W), 0.U)
1140  val csrevent16 = RegInit(UInt(XLEN.W), 0.U)
1141  val csrevent17 = RegInit(UInt(XLEN.W), 0.U)
1142  val csrevent18 = RegInit(UInt(XLEN.W), 0.U)
1143  val csrevent19 = RegInit(UInt(XLEN.W), 0.U)
1144  val csrevent20 = RegInit(UInt(XLEN.W), 0.U)
1145  val csrevent21 = RegInit(UInt(XLEN.W), 0.U)
1146  val csrevent22 = RegInit(UInt(XLEN.W), 0.U)
1147  val csrevent23 = RegInit(UInt(XLEN.W), 0.U)
1148  val csrevent24 = RegInit(UInt(XLEN.W), 0.U)
1149  val csrevent25 = RegInit(UInt(XLEN.W), 0.U)
1150  val csrevent26 = RegInit(UInt(XLEN.W), 0.U)
1151  val csrevent27 = RegInit(UInt(XLEN.W), 0.U)
1152  val csrevent28 = RegInit(UInt(XLEN.W), 0.U)
1153  val csrevent29 = RegInit(UInt(XLEN.W), 0.U)
1154  val csrevent30 = RegInit(UInt(XLEN.W), 0.U)
1155  val csrevent31 = RegInit(UInt(XLEN.W), 0.U)
1156
1157  var perfEventMapping = Map(
1158    MaskedRegMap(Mhpmevent3, csrevent3 ),
1159    MaskedRegMap(Mhpmevent4, csrevent4 ),
1160    MaskedRegMap(Mhpmevent5, csrevent5 ),
1161    MaskedRegMap(Mhpmevent6, csrevent6 ),
1162    MaskedRegMap(Mhpmevent7, csrevent7 ),
1163    MaskedRegMap(Mhpmevent8, csrevent8 ),
1164    MaskedRegMap(Mhpmevent9, csrevent9 ),
1165    MaskedRegMap(Mhpmevent10,csrevent10),
1166    MaskedRegMap(Mhpmevent11,csrevent11),
1167    MaskedRegMap(Mhpmevent12,csrevent12),
1168    MaskedRegMap(Mhpmevent13,csrevent13),
1169    MaskedRegMap(Mhpmevent14,csrevent14),
1170    MaskedRegMap(Mhpmevent15,csrevent15),
1171    MaskedRegMap(Mhpmevent16,csrevent16),
1172    MaskedRegMap(Mhpmevent17,csrevent17),
1173    MaskedRegMap(Mhpmevent18,csrevent18),
1174    MaskedRegMap(Mhpmevent19,csrevent19),
1175    MaskedRegMap(Mhpmevent20,csrevent20),
1176    MaskedRegMap(Mhpmevent21,csrevent21),
1177    MaskedRegMap(Mhpmevent22,csrevent22),
1178    MaskedRegMap(Mhpmevent23,csrevent23),
1179    MaskedRegMap(Mhpmevent24,csrevent24),
1180    MaskedRegMap(Mhpmevent25,csrevent25),
1181    MaskedRegMap(Mhpmevent26,csrevent26),
1182    MaskedRegMap(Mhpmevent27,csrevent27),
1183    MaskedRegMap(Mhpmevent28,csrevent28),
1184    MaskedRegMap(Mhpmevent29,csrevent29),
1185    MaskedRegMap(Mhpmevent30,csrevent30),
1186    MaskedRegMap(Mhpmevent31,csrevent31),
1187  )
1188
1189  val rdata = Wire(UInt(XLEN.W))
1190  MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data)
1191  io.hpmevent( 0) := csrevent3
1192  io.hpmevent( 1) := csrevent4
1193  io.hpmevent( 2) := csrevent5
1194  io.hpmevent( 3) := csrevent6
1195  io.hpmevent( 4) := csrevent7
1196  io.hpmevent( 5) := csrevent8
1197  io.hpmevent( 6) := csrevent9
1198  io.hpmevent( 7) := csrevent10
1199  io.hpmevent( 8) := csrevent11
1200  io.hpmevent( 9) := csrevent12
1201  io.hpmevent(10) := csrevent13
1202  io.hpmevent(11) := csrevent14
1203  io.hpmevent(12) := csrevent15
1204  io.hpmevent(13) := csrevent16
1205  io.hpmevent(14) := csrevent17
1206  io.hpmevent(15) := csrevent18
1207  io.hpmevent(16) := csrevent19
1208  io.hpmevent(17) := csrevent20
1209  io.hpmevent(18) := csrevent21
1210  io.hpmevent(19) := csrevent22
1211  io.hpmevent(20) := csrevent23
1212  io.hpmevent(21) := csrevent24
1213  io.hpmevent(22) := csrevent25
1214  io.hpmevent(23) := csrevent26
1215  io.hpmevent(24) := csrevent27
1216  io.hpmevent(25) := csrevent28
1217  io.hpmevent(26) := csrevent29
1218  io.hpmevent(27) := csrevent30
1219  io.hpmevent(28) := csrevent31
1220}
1221
1222