xref: /XiangShan/src/main/scala/xiangshan/backend/fu/CSR.scala (revision cd365d4ca1205723617d915c8588e09b1ecb1819)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package xiangshan.backend.fu
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import freechips.rocketchip.util._
23import utils.MaskedRegMap.WritableMask
24import utils._
25import xiangshan._
26import xiangshan.backend._
27import xiangshan.cache._
28import xiangshan.frontend.BPUCtrl
29import xiangshan.backend.fu.util._
30import difftest._
31
32trait HasExceptionNO {
33  def instrAddrMisaligned = 0
34  def instrAccessFault    = 1
35  def illegalInstr        = 2
36  def breakPoint          = 3
37  def loadAddrMisaligned  = 4
38  def loadAccessFault     = 5
39  def storeAddrMisaligned = 6
40  def storeAccessFault    = 7
41  def ecallU              = 8
42  def ecallS              = 9
43  def ecallM              = 11
44  def instrPageFault      = 12
45  def loadPageFault       = 13
46  def storePageFault      = 15
47
48  def singleStep          = 14
49
50  val ExcPriority = Seq(
51    breakPoint, // TODO: different BP has different priority
52    singleStep,
53    instrPageFault,
54    instrAccessFault,
55    illegalInstr,
56    instrAddrMisaligned,
57    ecallM, ecallS, ecallU,
58    storePageFault,
59    loadPageFault,
60    storeAccessFault,
61    loadAccessFault,
62    storeAddrMisaligned,
63    loadAddrMisaligned
64  )
65  val frontendSet = List(
66    // instrAddrMisaligned,
67    instrAccessFault,
68    illegalInstr,
69    instrPageFault
70  )
71  val csrSet = List(
72    illegalInstr,
73    breakPoint,
74    ecallU,
75    ecallS,
76    ecallM
77  )
78  val loadUnitSet = List(
79    loadAddrMisaligned,
80    loadAccessFault,
81    loadPageFault
82  )
83  val storeUnitSet = List(
84    storeAddrMisaligned,
85    storeAccessFault,
86    storePageFault
87  )
88  val atomicsUnitSet = (loadUnitSet ++ storeUnitSet).distinct
89  val allPossibleSet = (frontendSet ++ csrSet ++ loadUnitSet ++ storeUnitSet).distinct
90  val csrWbCount = (0 until 16).map(i => if (csrSet.contains(i)) 1 else 0)
91  val loadWbCount = (0 until 16).map(i => if (loadUnitSet.contains(i)) 1 else 0)
92  val storeWbCount = (0 until 16).map(i => if (storeUnitSet.contains(i)) 1 else 0)
93  val atomicsWbCount = (0 until 16).map(i => if (atomicsUnitSet.contains(i)) 1 else 0)
94  val writebackCount = (0 until 16).map(i => csrWbCount(i) + atomicsWbCount(i) + loadWbCount(i) + 2 * storeWbCount(i))
95  def partialSelect(vec: Vec[Bool], select: Seq[Int], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = {
96    if (dontCareBits) {
97      val new_vec = Wire(ExceptionVec())
98      new_vec := DontCare
99      select.map(i => new_vec(i) := vec(i))
100      return new_vec
101    }
102    else if (falseBits) {
103      val new_vec = Wire(ExceptionVec())
104      new_vec.map(_ := false.B)
105      select.map(i => new_vec(i) := vec(i))
106      return new_vec
107    }
108    else {
109      val new_vec = Wire(Vec(select.length, Bool()))
110      select.zipWithIndex.map{ case(s, i) => new_vec(i) := vec(s) }
111      return new_vec
112    }
113  }
114  def selectFrontend(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
115    partialSelect(vec, frontendSet, dontCareBits, falseBits)
116  def selectCSR(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
117    partialSelect(vec, csrSet, dontCareBits, falseBits)
118  def selectLoad(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
119    partialSelect(vec, loadUnitSet, dontCareBits, falseBits)
120  def selectStore(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
121    partialSelect(vec, storeUnitSet, dontCareBits, falseBits)
122  def selectAtomics(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
123    partialSelect(vec, atomicsUnitSet, dontCareBits, falseBits)
124  def selectAll(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
125    partialSelect(vec, allPossibleSet, dontCareBits, falseBits)
126}
127
128class FpuCsrIO extends Bundle {
129  val fflags = Output(Valid(UInt(5.W)))
130  val isIllegal = Output(Bool())
131  val dirty_fs = Output(Bool())
132  val frm = Input(UInt(3.W))
133}
134
135
136class PerfCounterIO(implicit p: Parameters) extends XSBundle {
137  val perfEventsFrontend  = (new PerfEventsBundle(numCSRPCntFrontend ))
138  val perfEventsCtrl      = (new PerfEventsBundle(numCSRPCntCtrl     ))
139  val perfEventsLsu       = (new PerfEventsBundle(numCSRPCntLsu      ))
140  val perfEventsHc        = Vec(numPCntHc * coreParams.L2NBanks,(UInt(6.W)))
141  val retiredInstr = UInt(3.W)
142  val frontendInfo = new Bundle {
143    val ibufFull  = Bool()
144    val bpuInfo = new Bundle {
145      val bpRight = UInt(XLEN.W)
146      val bpWrong = UInt(XLEN.W)
147    }
148  }
149  val ctrlInfo = new Bundle {
150    val robFull   = Bool()
151    val intdqFull = Bool()
152    val fpdqFull  = Bool()
153    val lsdqFull  = Bool()
154  }
155  val memInfo = new Bundle {
156    val sqFull = Bool()
157    val lqFull = Bool()
158    val dcacheMSHRFull = Bool()
159  }
160
161  val cacheInfo = new Bundle {
162    val l2MSHRFull = Bool()
163    val l3MSHRFull = Bool()
164    val l2nAcquire = UInt(XLEN.W)
165    val l2nAcquireMiss = UInt(XLEN.W)
166    val l3nAcquire = UInt(XLEN.W)
167    val l3nAcquireMiss = UInt(XLEN.W)
168  }
169}
170
171class CSRFileIO(implicit p: Parameters) extends XSBundle {
172  val hartId = Input(UInt(64.W))
173  // output (for func === CSROpType.jmp)
174  val perf = Input(new PerfCounterIO)
175  val isPerfCnt = Output(Bool())
176  // to FPU
177  val fpu = Flipped(new FpuCsrIO)
178  // from rob
179  val exception = Flipped(ValidIO(new ExceptionInfo))
180  // to ROB
181  val isXRet = Output(Bool())
182  val trapTarget = Output(UInt(VAddrBits.W))
183  val interrupt = Output(Bool())
184  // from LSQ
185  val memExceptionVAddr = Input(UInt(VAddrBits.W))
186  // from outside cpu,externalInterrupt
187  val externalInterrupt = new ExternalInterruptIO
188  // TLB
189  val tlb = Output(new TlbCsrBundle)
190  // Debug Mode
191  val singleStep = Output(Bool())
192  val debugMode = Output(Bool())
193  // Custom microarchiture ctrl signal
194  val customCtrl = Output(new CustomCSRCtrlIO)
195  val distributedUpdate = Flipped(new DistributedCSRUpdateReq)
196  // to Fence to disable sfence
197  val disableSfence = Output(Bool())
198  // distributed csr w
199}
200
201class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMPConst
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 PMPBase()))
389  val pmpMapping = if (NumPMP > 0) { // TODO: remove duplicate codes
390    val pmpCfgPerCSR = XLEN / new PMPConfig().getWidth
391    def pmpCfgIndex(i: Int) = (XLEN / 32) * (i / pmpCfgPerCSR)
392
393    /** to fit MaskedRegMap's write, declare cfgs as Merged CSRs and split them into each pmp */
394    val cfgMerged = RegInit(VecInit(Seq.fill(NumPMP / pmpCfgPerCSR)(0.U(XLEN.W))))
395    val cfgs = WireInit(cfgMerged).asTypeOf(Vec(NumPMP, new PMPConfig()))
396    val addr = Reg(Vec(NumPMP, UInt((PAddrBits-PMPOffBits).W)))
397    for (i <- pmp.indices) {
398      pmp(i).gen(cfgs(i), addr(i))
399    }
400
401    val cfg_mapping = (0 until NumPMP by pmpCfgPerCSR).map(i => {Map(
402      MaskedRegMap(
403        addr = PmpcfgBase + pmpCfgIndex(i),
404        reg = cfgMerged(i/pmpCfgPerCSR),
405        wmask = WritableMask,
406        wfn = new PMPConfig().write_cfg_vec
407      ))
408    }).fold(Map())((a, b) => a ++ b) // ugly code, hit me if u have better codes
409    val addr_mapping = (0 until NumPMP).map(i => {Map(
410      MaskedRegMap(
411        addr = PmpaddrBase + i,
412        reg = addr(i),
413        wmask = WritableMask,
414        wfn = { if (i != NumPMP-1) pmp(i).write_addr(pmp(i+1)) else pmp(i).write_addr },
415        rmask = WritableMask,
416        rfn = new PMPBase().read_addr(pmp(i).cfg)
417      ))
418    }).fold(Map())((a, b) => a ++ b) // ugly code, hit me if u have better codes.
419    cfg_mapping ++ addr_mapping
420  } else {
421    Map()
422  }
423  // Superviser-Level CSRs
424
425  // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U)
426  val sstatusWmask = "hc6122".U(XLEN.W)
427  // Sstatus Write Mask
428  // -------------------------------------------------------
429  //    19           9   5     2
430  // 0  1100 0000 0001 0010 0010
431  // 0  c    0    1    2    2
432  // -------------------------------------------------------
433  val sstatusRmask = sstatusWmask | "h8000000300018000".U
434  // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32))
435  val stvec = RegInit(UInt(XLEN.W), 0.U)
436  // val sie = RegInit(0.U(XLEN.W))
437  val sieMask = "h222".U & mideleg
438  val sipMask = "h222".U & mideleg
439  val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode
440  val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W))
441  // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug
442  // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0
443  // TODO: use config to control the length of asid
444  // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0
445  val satpMask = Cat("h8".U(4.W),Asid_true_mask(AsidLength),"hfffffffffff".U((XLEN - 4 - 16).W))
446  val sepc = RegInit(UInt(XLEN.W), 0.U)
447  val scause = RegInit(UInt(XLEN.W), 0.U)
448  val stval = Reg(UInt(XLEN.W))
449  val sscratch = RegInit(UInt(XLEN.W), 0.U)
450  val scounteren = RegInit(UInt(XLEN.W), 0.U)
451
452  // sbpctl
453  // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB}
454  val sbpctl = RegInit(UInt(XLEN.W), "h7f".U)
455  csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0)
456  csrio.customCtrl.bp_ctrl.btb_enable  := sbpctl(1)
457  csrio.customCtrl.bp_ctrl.bim_enable  := sbpctl(2)
458  csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3)
459  csrio.customCtrl.bp_ctrl.sc_enable   := sbpctl(4)
460  csrio.customCtrl.bp_ctrl.ras_enable  := sbpctl(5)
461  csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6)
462
463  // spfctl Bit 0: L1plusCache Prefetcher Enable
464  // spfctl Bit 1: L2Cache Prefetcher Enable
465  val spfctl = RegInit(UInt(XLEN.W), "h3".U)
466  csrio.customCtrl.l1plus_pf_enable := spfctl(0)
467  csrio.customCtrl.l2_pf_enable := spfctl(1)
468
469  // sdsid: Differentiated Services ID
470  val sdsid = RegInit(UInt(XLEN.W), 0.U)
471  csrio.customCtrl.dsid := sdsid
472
473  // slvpredctl: load violation predict settings
474  val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17
475  csrio.customCtrl.lvpred_disable := slvpredctl(0)
476  csrio.customCtrl.no_spec_load := slvpredctl(1)
477  csrio.customCtrl.storeset_wait_store := slvpredctl(2)
478  csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3)
479  csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4)
480
481  // smblockctl: memory block configurations
482  // bits 0-3: store buffer flush threshold (default: 8 entries)
483  val smblockctl_init_val =
484    ("hf".U & StoreBufferThreshold.U) |
485    (EnableLdVioCheckAfterReset.B.asUInt << 4)
486  val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val)
487  csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0)
488  // bits 4: enable load load violation check
489  csrio.customCtrl.ldld_vio_check := smblockctl(4)
490
491  val srnctl = RegInit(UInt(XLEN.W), "h1".U)
492  csrio.customCtrl.move_elim_enable := srnctl(0)
493
494  val tlbBundle = Wire(new TlbCsrBundle)
495  tlbBundle.satp.apply(satp)
496
497  csrio.tlb := tlbBundle
498
499  // User-Level CSRs
500  val uepc = Reg(UInt(XLEN.W))
501
502  // fcsr
503  class FcsrStruct extends Bundle {
504    val reserved = UInt((XLEN-3-5).W)
505    val frm = UInt(3.W)
506    val fflags = UInt(5.W)
507    assert(this.getWidth == XLEN)
508  }
509  val fcsr = RegInit(0.U(XLEN.W))
510  // set mstatus->sd and mstatus->fs when true
511  val csrw_dirty_fp_state = WireInit(false.B)
512
513  def frm_wfn(wdata: UInt): UInt = {
514    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
515    csrw_dirty_fp_state := true.B
516    fcsrOld.frm := wdata(2,0)
517    fcsrOld.asUInt()
518  }
519  def frm_rfn(rdata: UInt): UInt = rdata(7,5)
520
521  def fflags_wfn(update: Boolean)(wdata: UInt): UInt = {
522    val fcsrOld = fcsr.asTypeOf(new FcsrStruct)
523    val fcsrNew = WireInit(fcsrOld)
524    csrw_dirty_fp_state := true.B
525    if (update) {
526      fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags
527    } else {
528      fcsrNew.fflags := wdata(4,0)
529    }
530    fcsrNew.asUInt()
531  }
532  def fflags_rfn(rdata:UInt): UInt = rdata(4,0)
533
534  def fcsr_wfn(wdata: UInt): UInt = {
535    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
536    csrw_dirty_fp_state := true.B
537    Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags)
538  }
539
540  val fcsrMapping = Map(
541    MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn),
542    MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn),
543    MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn)
544  )
545
546  // Hart Priviledge Mode
547  val priviledgeMode = RegInit(UInt(2.W), ModeM)
548
549  // Emu perfcnt
550  val hasEmuPerfCnt = !env.FPGAPlatform
551  val nrEmuPerfCnts = if (hasEmuPerfCnt) 0x80 else 0x3
552
553  val emuPerfCnts    = List.fill(nrEmuPerfCnts)(RegInit(0.U(XLEN.W)))
554  val emuPerfCntCond = List.fill(nrEmuPerfCnts)(WireInit(false.B))
555  (emuPerfCnts zip emuPerfCntCond).map { case (c, e) => when (e) { c := c + 1.U } }
556
557  val emuPerfCntsLoMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1000 + i, emuPerfCnts(i)))
558  val emuPerfCntsHiMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1080 + i, emuPerfCnts(i)(63, 32)))
559  println(s"CSR: hasEmuPerfCnt:${hasEmuPerfCnt}")
560
561  //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool())))
562  // Perf Counter
563  val nrPerfCnts = 29  // 3...31
564  val priviledgeModeOH = UIntToOH(priviledgeMode)
565  val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool())))
566  val perfCnts   = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W)))
567  val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W)))
568  for (i <-0 until nrPerfCnts) {
569    perfEventscounten(i) := (Cat(perfEvents(i)(62),perfEvents(i)(61),(perfEvents(i)(61,60))) & priviledgeModeOH).orR
570  }
571
572  val hpmEvents = Wire(new PerfEventsBundle(numPCntHc * coreParams.L2NBanks))
573  val pfevent = Module(new PFEvent)
574  pfevent.io.distribute_csr := csrio.customCtrl.distribute_csr
575  for(i <- 0 until numPCntHc * coreParams.L2NBanks) {
576    hpmEvents.perf_events(i).incr_step := csrio.perf.perfEventsHc(i)
577  }
578
579  val hpm_hc = Module(new HPerfmonitor(numPCntHc * coreParams.L2NBanks,numCSRPCntHc))
580  val csrevents = pfevent.io.hpmevent.slice(24,29)
581  hpm_hc.io.hpm_event := csrevents
582  hpm_hc.io.events_sets := hpmEvents
583  val mcountinhibit = RegInit(0.U(XLEN.W))
584  val mcycle = RegInit(0.U(XLEN.W))
585  mcycle := mcycle + 1.U
586  val minstret = RegInit(0.U(XLEN.W))
587  minstret := minstret + RegNext(csrio.perf.retiredInstr)
588  perfCnts( 0)  := Mux((mcountinhibit( 3) | perfEventscounten( 0)),perfCnts( 0) , (perfCnts( 0) + RegNext(csrio.perf.perfEventsFrontend.perf_events(0 ).incr_step)))
589  perfCnts( 1)  := Mux((mcountinhibit( 4) | perfEventscounten( 1)),perfCnts( 1) , (perfCnts( 1) + RegNext(csrio.perf.perfEventsFrontend.perf_events(1 ).incr_step)))
590  perfCnts( 2)  := Mux((mcountinhibit( 5) | perfEventscounten( 2)),perfCnts( 2) , (perfCnts( 2) + RegNext(csrio.perf.perfEventsFrontend.perf_events(2 ).incr_step)))
591  perfCnts( 3)  := Mux((mcountinhibit( 6) | perfEventscounten( 3)),perfCnts( 3) , (perfCnts( 3) + RegNext(csrio.perf.perfEventsFrontend.perf_events(3 ).incr_step)))
592  perfCnts( 4)  := Mux((mcountinhibit( 7) | perfEventscounten( 4)),perfCnts( 4) , (perfCnts( 4) + RegNext(csrio.perf.perfEventsFrontend.perf_events(4 ).incr_step)))
593  perfCnts( 5)  := Mux((mcountinhibit( 8) | perfEventscounten( 5)),perfCnts( 5) , (perfCnts( 5) + RegNext(csrio.perf.perfEventsFrontend.perf_events(5 ).incr_step)))
594  perfCnts( 6)  := Mux((mcountinhibit( 9) | perfEventscounten( 6)),perfCnts( 6) , (perfCnts( 6) + RegNext(csrio.perf.perfEventsFrontend.perf_events(6 ).incr_step)))
595  perfCnts( 7)  := Mux((mcountinhibit(10) | perfEventscounten( 7)),perfCnts( 7) , (perfCnts( 7) + RegNext(csrio.perf.perfEventsFrontend.perf_events(7 ).incr_step)))
596  perfCnts( 8)  := Mux((mcountinhibit(11) | perfEventscounten( 8)),perfCnts( 8) , (perfCnts( 8) + RegNext(csrio.perf.perfEventsCtrl.perf_events(0 ).incr_step)))
597  perfCnts( 9)  := Mux((mcountinhibit(12) | perfEventscounten( 9)),perfCnts( 9) , (perfCnts( 9) + RegNext(csrio.perf.perfEventsCtrl.perf_events(1 ).incr_step)))
598  perfCnts(10)  := Mux((mcountinhibit(13) | perfEventscounten(10)),perfCnts(10) , (perfCnts(10) + RegNext(csrio.perf.perfEventsCtrl.perf_events(2 ).incr_step)))
599  perfCnts(11)  := Mux((mcountinhibit(14) | perfEventscounten(11)),perfCnts(11) , (perfCnts(11) + RegNext(csrio.perf.perfEventsCtrl.perf_events(3 ).incr_step)))
600  perfCnts(12)  := Mux((mcountinhibit(15) | perfEventscounten(12)),perfCnts(12) , (perfCnts(12) + RegNext(csrio.perf.perfEventsCtrl.perf_events(4 ).incr_step)))
601  perfCnts(13)  := Mux((mcountinhibit(16) | perfEventscounten(13)),perfCnts(13) , (perfCnts(13) + RegNext(csrio.perf.perfEventsCtrl.perf_events(5 ).incr_step)))
602  perfCnts(14)  := Mux((mcountinhibit(17) | perfEventscounten(14)),perfCnts(14) , (perfCnts(14) + RegNext(csrio.perf.perfEventsCtrl.perf_events(6 ).incr_step)))
603  perfCnts(15)  := Mux((mcountinhibit(18) | perfEventscounten(15)),perfCnts(15) , (perfCnts(15) + RegNext(csrio.perf.perfEventsCtrl.perf_events(7 ).incr_step)))
604  perfCnts(16)  := Mux((mcountinhibit(19) | perfEventscounten(16)),perfCnts(16) , (perfCnts(16) + RegNext(csrio.perf.perfEventsLsu.perf_events(0 ).incr_step)))
605  perfCnts(17)  := Mux((mcountinhibit(20) | perfEventscounten(17)),perfCnts(17) , (perfCnts(17) + RegNext(csrio.perf.perfEventsLsu.perf_events(1 ).incr_step)))
606  perfCnts(18)  := Mux((mcountinhibit(21) | perfEventscounten(18)),perfCnts(18) , (perfCnts(18) + RegNext(csrio.perf.perfEventsLsu.perf_events(2 ).incr_step)))
607  perfCnts(19)  := Mux((mcountinhibit(22) | perfEventscounten(19)),perfCnts(19) , (perfCnts(19) + RegNext(csrio.perf.perfEventsLsu.perf_events(3 ).incr_step)))
608  perfCnts(20)  := Mux((mcountinhibit(23) | perfEventscounten(20)),perfCnts(20) , (perfCnts(20) + RegNext(csrio.perf.perfEventsLsu.perf_events(4 ).incr_step)))
609  perfCnts(21)  := Mux((mcountinhibit(24) | perfEventscounten(21)),perfCnts(21) , (perfCnts(21) + RegNext(csrio.perf.perfEventsLsu.perf_events(5 ).incr_step)))
610  perfCnts(22)  := Mux((mcountinhibit(25) | perfEventscounten(22)),perfCnts(22) , (perfCnts(22) + RegNext(csrio.perf.perfEventsLsu.perf_events(6 ).incr_step)))
611  perfCnts(23)  := Mux((mcountinhibit(26) | perfEventscounten(23)),perfCnts(23) , (perfCnts(23) + RegNext(csrio.perf.perfEventsLsu.perf_events(7 ).incr_step)))
612  perfCnts(24)  := Mux((mcountinhibit(27) | perfEventscounten(24)),perfCnts(24) , (perfCnts(24) + RegNext(hpm_hc.io.events_selected.perf_events(0 ).incr_step)))
613  perfCnts(25)  := Mux((mcountinhibit(28) | perfEventscounten(25)),perfCnts(25) , (perfCnts(25) + RegNext(hpm_hc.io.events_selected.perf_events(1 ).incr_step)))
614  perfCnts(26)  := Mux((mcountinhibit(29) | perfEventscounten(26)),perfCnts(26) , (perfCnts(26) + RegNext(hpm_hc.io.events_selected.perf_events(2 ).incr_step)))
615  perfCnts(27)  := Mux((mcountinhibit(30) | perfEventscounten(27)),perfCnts(27) , (perfCnts(27) + RegNext(hpm_hc.io.events_selected.perf_events(3 ).incr_step)))
616  perfCnts(28)  := Mux((mcountinhibit(31) | perfEventscounten(28)),perfCnts(28) , (perfCnts(28) + RegNext(hpm_hc.io.events_selected.perf_events(4 ).incr_step)))
617
618  // CSR reg map
619  val basicPrivMapping = Map(
620
621    //--- User Trap Setup ---
622    // MaskedRegMap(Ustatus, ustatus),
623    // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable),
624    // MaskedRegMap(Utvec, utvec),
625
626    //--- User Trap Handling ---
627    // MaskedRegMap(Uscratch, uscratch),
628    // MaskedRegMap(Uepc, uepc),
629    // MaskedRegMap(Ucause, ucause),
630    // MaskedRegMap(Utval, utval),
631    // MaskedRegMap(Uip, uip),
632
633    //--- User Counter/Timers ---
634    // MaskedRegMap(Cycle, cycle),
635    // MaskedRegMap(Time, time),
636    // MaskedRegMap(Instret, instret),
637
638    //--- Supervisor Trap Setup ---
639    MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask),
640    // MaskedRegMap(Sedeleg, Sedeleg),
641    // MaskedRegMap(Sideleg, Sideleg),
642    MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask),
643    MaskedRegMap(Stvec, stvec),
644    MaskedRegMap(Scounteren, scounteren),
645
646    //--- Supervisor Trap Handling ---
647    MaskedRegMap(Sscratch, sscratch),
648    MaskedRegMap(Sepc, sepc),
649    MaskedRegMap(Scause, scause),
650    MaskedRegMap(Stval, stval),
651    MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask),
652
653    //--- Supervisor Protection and Translation ---
654    MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask),
655
656    //--- Supervisor Custom Read/Write Registers
657    MaskedRegMap(Sbpctl, sbpctl),
658    MaskedRegMap(Spfctl, spfctl),
659    MaskedRegMap(Sdsid, sdsid),
660    MaskedRegMap(Slvpredctl, slvpredctl),
661    MaskedRegMap(Smblockctl, smblockctl),
662    MaskedRegMap(Srnctl, srnctl),
663
664    //--- Machine Information Registers ---
665    MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
666    MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
667    MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
668    MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
669
670    //--- Machine Trap Setup ---
671    MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask),
672    MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable
673    MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)),
674    MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)),
675    MaskedRegMap(Mie, mie),
676    MaskedRegMap(Mtvec, mtvec),
677    MaskedRegMap(Mcounteren, mcounteren),
678
679    //--- Machine Trap Handling ---
680    MaskedRegMap(Mscratch, mscratch),
681    MaskedRegMap(Mepc, mepc),
682    MaskedRegMap(Mcause, mcause),
683    MaskedRegMap(Mtval, mtval),
684    MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable),
685
686    //--- Debug Mode ---
687    MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect),
688    MaskedRegMap(Dpc, dpc),
689    MaskedRegMap(Dscratch, dscratch),
690    MaskedRegMap(Dscratch1, dscratch1)
691  )
692
693  var perfCntMapping = Map(
694    MaskedRegMap(Mcountinhibit, mcountinhibit),
695    MaskedRegMap(Mcycle, mcycle),
696    MaskedRegMap(Minstret, minstret),
697    MaskedRegMap(Mhpmevent3 , perfEvents( 0)),
698    MaskedRegMap(Mhpmevent4 , perfEvents( 1)),
699    MaskedRegMap(Mhpmevent5 , perfEvents( 2)),
700    MaskedRegMap(Mhpmevent6 , perfEvents( 3)),
701    MaskedRegMap(Mhpmevent7 , perfEvents( 4)),
702    MaskedRegMap(Mhpmevent8 , perfEvents( 5)),
703    MaskedRegMap(Mhpmevent9 , perfEvents( 6)),
704    MaskedRegMap(Mhpmevent10, perfEvents( 7)),
705    MaskedRegMap(Mhpmevent11, perfEvents( 8)),
706    MaskedRegMap(Mhpmevent12, perfEvents( 9)),
707    MaskedRegMap(Mhpmevent13, perfEvents(10)),
708    MaskedRegMap(Mhpmevent14, perfEvents(11)),
709    MaskedRegMap(Mhpmevent15, perfEvents(12)),
710    MaskedRegMap(Mhpmevent16, perfEvents(13)),
711    MaskedRegMap(Mhpmevent17, perfEvents(14)),
712    MaskedRegMap(Mhpmevent18, perfEvents(15)),
713    MaskedRegMap(Mhpmevent19, perfEvents(16)),
714    MaskedRegMap(Mhpmevent20, perfEvents(17)),
715    MaskedRegMap(Mhpmevent21, perfEvents(18)),
716    MaskedRegMap(Mhpmevent22, perfEvents(19)),
717    MaskedRegMap(Mhpmevent23, perfEvents(20)),
718    MaskedRegMap(Mhpmevent24, perfEvents(21)),
719    MaskedRegMap(Mhpmevent25, perfEvents(22)),
720    MaskedRegMap(Mhpmevent26, perfEvents(23)),
721    MaskedRegMap(Mhpmevent27, perfEvents(24)),
722    MaskedRegMap(Mhpmevent28, perfEvents(25)),
723    MaskedRegMap(Mhpmevent29, perfEvents(26)),
724    MaskedRegMap(Mhpmevent30, perfEvents(27)),
725    MaskedRegMap(Mhpmevent31, perfEvents(28)),
726    MaskedRegMap(Mhpmcounter3 , perfCnts( 0)),
727    MaskedRegMap(Mhpmcounter4 , perfCnts( 1)),
728    MaskedRegMap(Mhpmcounter5 , perfCnts( 2)),
729    MaskedRegMap(Mhpmcounter6 , perfCnts( 3)),
730    MaskedRegMap(Mhpmcounter7 , perfCnts( 4)),
731    MaskedRegMap(Mhpmcounter8 , perfCnts( 5)),
732    MaskedRegMap(Mhpmcounter9 , perfCnts( 6)),
733    MaskedRegMap(Mhpmcounter10, perfCnts( 7)),
734    MaskedRegMap(Mhpmcounter11, perfCnts( 8)),
735    MaskedRegMap(Mhpmcounter12, perfCnts( 9)),
736    MaskedRegMap(Mhpmcounter13, perfCnts(10)),
737    MaskedRegMap(Mhpmcounter14, perfCnts(11)),
738    MaskedRegMap(Mhpmcounter15, perfCnts(12)),
739    MaskedRegMap(Mhpmcounter16, perfCnts(13)),
740    MaskedRegMap(Mhpmcounter17, perfCnts(14)),
741    MaskedRegMap(Mhpmcounter18, perfCnts(15)),
742    MaskedRegMap(Mhpmcounter19, perfCnts(16)),
743    MaskedRegMap(Mhpmcounter20, perfCnts(17)),
744    MaskedRegMap(Mhpmcounter21, perfCnts(18)),
745    MaskedRegMap(Mhpmcounter22, perfCnts(19)),
746    MaskedRegMap(Mhpmcounter23, perfCnts(20)),
747    MaskedRegMap(Mhpmcounter24, perfCnts(21)),
748    MaskedRegMap(Mhpmcounter25, perfCnts(22)),
749    MaskedRegMap(Mhpmcounter26, perfCnts(23)),
750    MaskedRegMap(Mhpmcounter27, perfCnts(24)),
751    MaskedRegMap(Mhpmcounter28, perfCnts(25)),
752    MaskedRegMap(Mhpmcounter29, perfCnts(26)),
753    MaskedRegMap(Mhpmcounter30, perfCnts(27)),
754    MaskedRegMap(Mhpmcounter31, perfCnts(28)),
755  )
756  // TODO: mechanism should be implemented later
757  // val MhpmcounterStart = Mhpmcounter3
758  // val MhpmeventStart   = Mhpmevent3
759  // for (i <- 0 until nrPerfCnts) {
760  //   perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i))
761  //   perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i))
762  // }
763
764  val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
765    name -> RegInit(0.U(attribute("width").toInt.W))
766  }}
767  val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
768    MaskedRegMap(
769      Scachebase + attribute("offset").toInt,
770      cacheopRegs(name)
771    )
772  }}
773
774  val mapping = basicPrivMapping ++
775                perfCntMapping ++
776                pmpMapping ++
777                emuPerfCntsLoMapping ++
778                (if (XLEN == 32) emuPerfCntsHiMapping else Nil) ++
779                (if (HasFPU) fcsrMapping else Nil) ++
780                (if (HasCustomCSRCacheOp) cacheopMapping else Nil)
781
782  val addr = src2(11, 0)
783  val csri = ZeroExt(src2(16, 12), XLEN)
784  val rdata = Wire(UInt(XLEN.W))
785  val wdata = LookupTree(func, List(
786    CSROpType.wrt  -> src1,
787    CSROpType.set  -> (rdata | src1),
788    CSROpType.clr  -> (rdata & (~src1).asUInt()),
789    CSROpType.wrti -> csri,
790    CSROpType.seti -> (rdata | csri),
791    CSROpType.clri -> (rdata & (~csri).asUInt())
792  ))
793
794  val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U)
795  csrio.isPerfCnt := addrInPerfCnt
796
797  // satp wen check
798  val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U)
799
800  // csr access check, special case
801  val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool)
802  val accessPermitted = !(addr === Satp.U && tvmNotPermit)
803  csrio.disableSfence := tvmNotPermit
804
805  // general CSR wen check
806  val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode)
807  val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode)
808  val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren)
809  val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted
810
811  // Writeable check is ingored.
812  // Currently, write to illegal csr addr will be ignored
813  MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata)
814  io.out.bits.data := rdata
815  io.out.bits.uop := io.in.bits.uop
816  io.out.bits.uop.cf := cfOut
817  io.out.bits.uop.ctrl.flushPipe := flushPipe
818
819  // send distribute csr a w signal
820  csrio.customCtrl.distribute_csr.w.valid := wen && permitted
821  csrio.customCtrl.distribute_csr.w.bits.data := wdata
822  csrio.customCtrl.distribute_csr.w.bits.addr := addr
823
824  // Fix Mip/Sip write
825  val fixMapping = Map(
826    MaskedRegMap(Mip, mipReg.asUInt, mipFixMask),
827    MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask)
828  )
829  val rdataFix = Wire(UInt(XLEN.W))
830  val wdataFix = LookupTree(func, List(
831    CSROpType.wrt  -> src1,
832    CSROpType.set  -> (rdataFix | src1),
833    CSROpType.clr  -> (rdataFix & (~src1).asUInt()),
834    CSROpType.wrti -> csri,
835    CSROpType.seti -> (rdataFix | csri),
836    CSROpType.clri -> (rdataFix & (~csri).asUInt())
837  ))
838  MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix)
839
840  when (csrio.fpu.fflags.valid) {
841    fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits)
842  }
843  // set fs and sd in mstatus
844  when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) {
845    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
846    mstatusNew.fs := "b11".U
847    mstatusNew.sd := true.B
848    mstatus := mstatusNew.asUInt()
849  }
850  csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm
851
852  // CSR inst decode
853  val isEbreak = addr === privEbreak && func === CSROpType.jmp
854  val isEcall  = addr === privEcall  && func === CSROpType.jmp
855  val isMret   = addr === privMret   && func === CSROpType.jmp
856  val isSret   = addr === privSret   && func === CSROpType.jmp
857  val isUret   = addr === privUret   && func === CSROpType.jmp
858  val isDret   = addr === privDret   && func === CSROpType.jmp
859
860  XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func)
861  XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode)
862
863  // Illegal priviledged operation list
864  val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool
865
866  // Illegal priviledged instruction check
867  val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr)
868  val isIllegalAccess = !permitted
869  val isIllegalPrivOp = illegalSModeSret
870
871  // expose several csr bits for tlb
872  tlbBundle.priv.mxr   := mstatusStruct.mxr.asBool
873  tlbBundle.priv.sum   := mstatusStruct.sum.asBool
874  tlbBundle.priv.imode := priviledgeMode
875  tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode)
876
877  // Branch control
878  val retTarget = Wire(UInt(VAddrBits.W))
879  val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed
880  flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall)
881
882  retTarget := DontCare
883  // val illegalEret = TODO
884
885  when (valid && isDret) {
886    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
887    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
888    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
889    val debugModeNew = WireInit(debugMode)
890    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.
891    mstatus := mstatusNew.asUInt
892    priviledgeMode := dcsrNew.prv
893    retTarget := dpc(VAddrBits-1, 0)
894    debugModeNew := false.B
895    debugIntrEnable := true.B
896    debugMode := debugModeNew
897    XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget)
898  }
899
900  when (valid && isMret) {
901    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
902    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
903    mstatusNew.ie.m := mstatusOld.pie.m
904    priviledgeMode := mstatusOld.mpp
905    mstatusNew.pie.m := true.B
906    mstatusNew.mpp := ModeU
907    when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U }
908    mstatus := mstatusNew.asUInt
909    // lr := false.B
910    retTarget := mepc(VAddrBits-1, 0)
911  }
912
913  when (valid && isSret && !illegalSModeSret) {
914    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
915    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
916    mstatusNew.ie.s := mstatusOld.pie.s
917    priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
918    mstatusNew.pie.s := true.B
919    mstatusNew.spp := ModeU
920    mstatus := mstatusNew.asUInt
921    mstatusNew.mprv := 0.U
922    // lr := false.B
923    retTarget := sepc(VAddrBits-1, 0)
924  }
925
926  when (valid && isUret) {
927    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
928    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
929    // mstatusNew.mpp.m := ModeU //TODO: add mode U
930    mstatusNew.ie.u := mstatusOld.pie.u
931    priviledgeMode := ModeU
932    mstatusNew.pie.u := true.B
933    mstatus := mstatusNew.asUInt
934    retTarget := uepc(VAddrBits-1, 0)
935  }
936
937  io.in.ready := true.B
938  io.out.valid := valid
939
940  val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku)
941
942  val csrExceptionVec = WireInit(cfIn.exceptionVec)
943  csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException
944  csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
945  csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
946  csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
947  // Trigger an illegal instr exception when:
948  // * unimplemented csr is being read/written
949  // * csr access is illegal
950  csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
951  cfOut.exceptionVec := csrExceptionVec
952
953  /**
954    * Exception and Intr
955    */
956  val ideleg =  (mideleg & mip.asUInt)
957  def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS),
958    ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM))
959
960  val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable
961  XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!")
962  // send interrupt information to ROB
963  val intrVecEnable = Wire(Vec(12, Bool()))
964  intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)}
965  val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt))
966  val intrBitSet = intrVec.orR()
967  csrio.interrupt := intrBitSet
968  mipWire.t.m := csrio.externalInterrupt.mtip
969  mipWire.s.m := csrio.externalInterrupt.msip
970  mipWire.e.m := csrio.externalInterrupt.meip
971  mipWire.e.s := csrio.externalInterrupt.meip
972
973  // interrupts
974  val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
975  val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt
976  XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO)
977  val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr
978
979  // exceptions
980  val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt
981  val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException
982  val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException
983  val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException
984  val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException
985  val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException
986  val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException
987  val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException
988  val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException
989  val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException
990  val hasSingleStep = csrio.exception.bits.uop.cf.exceptionVec(singleStep) && raiseException
991
992  val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec
993  val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
994  val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
995
996  val raiseExceptionIntr = csrio.exception.valid
997
998  val raiseDebugExceptionIntr = !debugMode && hasbreakPoint || raiseDebugIntr || hasSingleStep
999  val ebreakEnterParkLoop = debugMode && raiseExceptionIntr // exception in debug mode (except ebrk) changes cmderr. how ???
1000
1001  XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
1002    csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt
1003  )
1004  XSDebug(raiseExceptionIntr,
1005    "pc %x mstatus %x mideleg %x medeleg %x mode %x\n",
1006    csrio.exception.bits.uop.cf.pc,
1007    mstatus,
1008    mideleg,
1009    medeleg,
1010    priviledgeMode
1011  )
1012
1013  // mtval write logic
1014  val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
1015  when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) {
1016    val tval = Mux(
1017      hasInstrPageFault,
1018      Mux(
1019        csrio.exception.bits.uop.cf.crossPageIPFFix,
1020        SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN),
1021        SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1022      ),
1023      memExceptionAddr
1024    )
1025    when (priviledgeMode === ModeM) {
1026      mtval := tval
1027    }.otherwise {
1028      stval := tval
1029    }
1030  }
1031
1032  when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) {
1033    mtval := memExceptionAddr
1034  }
1035
1036  val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec
1037  val deleg = Mux(raiseIntr, mideleg , medeleg)
1038  // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM);
1039  val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM)
1040  val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check
1041  val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak
1042
1043  // ctrl block will use theses later for flush
1044  val isXRetFlag = RegInit(false.B)
1045  val retTargetReg = Reg(retTarget.cloneType)
1046  when (io.redirectIn.valid) {
1047    isXRetFlag := false.B
1048  }.elsewhen (isXRet) {
1049    isXRetFlag := true.B
1050    retTargetReg := retTarget
1051  }
1052  csrio.isXRet := isXRetFlag
1053  csrio.trapTarget := Mux(isXRetFlag,
1054    retTargetReg,
1055    Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget,
1056      Mux(delegS, stvec, mtvec))(VAddrBits-1, 0)
1057  )
1058
1059  when (raiseExceptionIntr) {
1060    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
1061    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
1062    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
1063    val debugModeNew = WireInit(debugMode)
1064
1065    when (raiseDebugExceptionIntr) {
1066      when (raiseDebugIntr) {
1067        debugModeNew := true.B
1068        mstatusNew.mprv := false.B
1069        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1070        dcsrNew.cause := 1.U
1071        dcsrNew.prv := priviledgeMode
1072        priviledgeMode := ModeM
1073        XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc)
1074      }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) {
1075        // ebreak or ss in running hart
1076        debugModeNew := true.B
1077        dpc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1078        dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U)
1079        dcsrNew.prv := priviledgeMode // TODO
1080        priviledgeMode := ModeM
1081        mstatusNew.mprv := false.B
1082      }
1083      dcsr := dcsrNew.asUInt
1084      debugIntrEnable := false.B
1085    }.elsewhen (delegS) {
1086      scause := causeNO
1087      sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1088      mstatusNew.spp := priviledgeMode
1089      mstatusNew.pie.s := mstatusOld.ie.s
1090      mstatusNew.ie.s := false.B
1091      priviledgeMode := ModeS
1092      when (tvalWen) { stval := 0.U }
1093    }.otherwise {
1094      mcause := causeNO
1095      mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN)
1096      mstatusNew.mpp := priviledgeMode
1097      mstatusNew.pie.m := mstatusOld.ie.m
1098      mstatusNew.ie.m := false.B
1099      priviledgeMode := ModeM
1100      when (tvalWen) { mtval := 0.U }
1101    }
1102    mstatus := mstatusNew.asUInt
1103    debugMode := debugModeNew
1104  }
1105
1106  XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc)
1107
1108  // Distributed CSR update req
1109  //
1110  // For now we use it to implement customized cache op
1111
1112  when(csrio.distributedUpdate.w.valid){
1113    // cacheopRegs can be distributed updated
1114    CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
1115      when((Scachebase + attribute("offset").toInt).U === csrio.distributedUpdate.w.bits.addr){
1116        cacheopRegs(name) := csrio.distributedUpdate.w.bits.data
1117      }
1118    }}
1119  }
1120
1121  def readWithScala(addr: Int): UInt = mapping(addr)._1
1122
1123  val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
1124
1125  if (!env.FPGAPlatform) {
1126    val difftest = Module(new DifftestArchEvent)
1127    difftest.io.clock := clock
1128    difftest.io.coreid := hardId.U
1129    difftest.io.intrNO := RegNext(difftestIntrNO)
1130    difftest.io.cause := RegNext(Mux(csrio.exception.valid, causeNO, 0.U))
1131    difftest.io.exceptionPC := RegNext(SignExt(csrio.exception.bits.uop.cf.pc, XLEN))
1132  }
1133
1134  if (!env.FPGAPlatform) {
1135    val difftest = Module(new DifftestCSRState)
1136    difftest.io.clock := clock
1137    difftest.io.coreid := hardId.U
1138    difftest.io.priviledgeMode := priviledgeMode
1139    difftest.io.mstatus := mstatus
1140    difftest.io.sstatus := mstatus & sstatusRmask
1141    difftest.io.mepc := mepc
1142    difftest.io.sepc := sepc
1143    difftest.io.mtval:= mtval
1144    difftest.io.stval:= stval
1145    difftest.io.mtvec := mtvec
1146    difftest.io.stvec := stvec
1147    difftest.io.mcause := mcause
1148    difftest.io.scause := scause
1149    difftest.io.satp := satp
1150    difftest.io.mip := mipReg
1151    difftest.io.mie := mie
1152    difftest.io.mscratch := mscratch
1153    difftest.io.sscratch := sscratch
1154    difftest.io.mideleg := mideleg
1155    difftest.io.medeleg := medeleg
1156  }
1157}
1158class PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst  {
1159  val io = IO(new Bundle {
1160    val distribute_csr = Flipped(new DistributedCSRIO())
1161    val hpmevent = Output(Vec(29, UInt(XLEN.W)))
1162  })
1163
1164  val w = io.distribute_csr.w
1165
1166  //val csrevents = Vec(29,RegInit(UInt(XLEN.W), 0.U))
1167  val csrevent3  = RegInit(UInt(XLEN.W), 0.U)
1168  val csrevent4  = RegInit(UInt(XLEN.W), 0.U)
1169  val csrevent5  = RegInit(UInt(XLEN.W), 0.U)
1170  val csrevent6  = RegInit(UInt(XLEN.W), 0.U)
1171  val csrevent7  = RegInit(UInt(XLEN.W), 0.U)
1172  val csrevent8  = RegInit(UInt(XLEN.W), 0.U)
1173  val csrevent9  = RegInit(UInt(XLEN.W), 0.U)
1174  val csrevent10 = RegInit(UInt(XLEN.W), 0.U)
1175  val csrevent11 = RegInit(UInt(XLEN.W), 0.U)
1176  val csrevent12 = RegInit(UInt(XLEN.W), 0.U)
1177  val csrevent13 = RegInit(UInt(XLEN.W), 0.U)
1178  val csrevent14 = RegInit(UInt(XLEN.W), 0.U)
1179  val csrevent15 = RegInit(UInt(XLEN.W), 0.U)
1180  val csrevent16 = RegInit(UInt(XLEN.W), 0.U)
1181  val csrevent17 = RegInit(UInt(XLEN.W), 0.U)
1182  val csrevent18 = RegInit(UInt(XLEN.W), 0.U)
1183  val csrevent19 = RegInit(UInt(XLEN.W), 0.U)
1184  val csrevent20 = RegInit(UInt(XLEN.W), 0.U)
1185  val csrevent21 = RegInit(UInt(XLEN.W), 0.U)
1186  val csrevent22 = RegInit(UInt(XLEN.W), 0.U)
1187  val csrevent23 = RegInit(UInt(XLEN.W), 0.U)
1188  val csrevent24 = RegInit(UInt(XLEN.W), 0.U)
1189  val csrevent25 = RegInit(UInt(XLEN.W), 0.U)
1190  val csrevent26 = RegInit(UInt(XLEN.W), 0.U)
1191  val csrevent27 = RegInit(UInt(XLEN.W), 0.U)
1192  val csrevent28 = RegInit(UInt(XLEN.W), 0.U)
1193  val csrevent29 = RegInit(UInt(XLEN.W), 0.U)
1194  val csrevent30 = RegInit(UInt(XLEN.W), 0.U)
1195  val csrevent31 = RegInit(UInt(XLEN.W), 0.U)
1196
1197  var perfEventMapping = Map(
1198    MaskedRegMap(Mhpmevent3, csrevent3 ),
1199    MaskedRegMap(Mhpmevent4, csrevent4 ),
1200    MaskedRegMap(Mhpmevent5, csrevent5 ),
1201    MaskedRegMap(Mhpmevent6, csrevent6 ),
1202    MaskedRegMap(Mhpmevent7, csrevent7 ),
1203    MaskedRegMap(Mhpmevent8, csrevent8 ),
1204    MaskedRegMap(Mhpmevent9, csrevent9 ),
1205    MaskedRegMap(Mhpmevent10,csrevent10),
1206    MaskedRegMap(Mhpmevent11,csrevent11),
1207    MaskedRegMap(Mhpmevent12,csrevent12),
1208    MaskedRegMap(Mhpmevent13,csrevent13),
1209    MaskedRegMap(Mhpmevent14,csrevent14),
1210    MaskedRegMap(Mhpmevent15,csrevent15),
1211    MaskedRegMap(Mhpmevent16,csrevent16),
1212    MaskedRegMap(Mhpmevent17,csrevent17),
1213    MaskedRegMap(Mhpmevent18,csrevent18),
1214    MaskedRegMap(Mhpmevent19,csrevent19),
1215    MaskedRegMap(Mhpmevent20,csrevent20),
1216    MaskedRegMap(Mhpmevent21,csrevent21),
1217    MaskedRegMap(Mhpmevent22,csrevent22),
1218    MaskedRegMap(Mhpmevent23,csrevent23),
1219    MaskedRegMap(Mhpmevent24,csrevent24),
1220    MaskedRegMap(Mhpmevent25,csrevent25),
1221    MaskedRegMap(Mhpmevent26,csrevent26),
1222    MaskedRegMap(Mhpmevent27,csrevent27),
1223    MaskedRegMap(Mhpmevent28,csrevent28),
1224    MaskedRegMap(Mhpmevent29,csrevent29),
1225    MaskedRegMap(Mhpmevent30,csrevent30),
1226    MaskedRegMap(Mhpmevent31,csrevent31),
1227  )
1228
1229  val rdata = Wire(UInt(XLEN.W))
1230  MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data)
1231  io.hpmevent( 0) := csrevent3
1232  io.hpmevent( 1) := csrevent4
1233  io.hpmevent( 2) := csrevent5
1234  io.hpmevent( 3) := csrevent6
1235  io.hpmevent( 4) := csrevent7
1236  io.hpmevent( 5) := csrevent8
1237  io.hpmevent( 6) := csrevent9
1238  io.hpmevent( 7) := csrevent10
1239  io.hpmevent( 8) := csrevent11
1240  io.hpmevent( 9) := csrevent12
1241  io.hpmevent(10) := csrevent13
1242  io.hpmevent(11) := csrevent14
1243  io.hpmevent(12) := csrevent15
1244  io.hpmevent(13) := csrevent16
1245  io.hpmevent(14) := csrevent17
1246  io.hpmevent(15) := csrevent18
1247  io.hpmevent(16) := csrevent19
1248  io.hpmevent(17) := csrevent20
1249  io.hpmevent(18) := csrevent21
1250  io.hpmevent(19) := csrevent22
1251  io.hpmevent(20) := csrevent23
1252  io.hpmevent(21) := csrevent24
1253  io.hpmevent(22) := csrevent25
1254  io.hpmevent(23) := csrevent26
1255  io.hpmevent(24) := csrevent27
1256  io.hpmevent(25) := csrevent28
1257  io.hpmevent(26) := csrevent29
1258  io.hpmevent(27) := csrevent30
1259  io.hpmevent(28) := csrevent31
1260}
1261
1262