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