xref: /XiangShan/src/main/scala/xiangshan/backend/fu/CSR.scala (revision a4e57ea3a91431261d57a58df4810c0d9f0366ef)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
17c84054caSLinJiaweipackage xiangshan.backend.fu
18c84054caSLinJiawei
192225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters
20c84054caSLinJiaweiimport chisel3._
21c84054caSLinJiaweiimport chisel3.util._
226ab6918fSYinan Xuimport difftest._
23b6982e83SLemoverimport freechips.rocketchip.util._
24b6982e83SLemoverimport utils.MaskedRegMap.WritableMask
25c84054caSLinJiaweiimport utils._
266ab6918fSYinan Xuimport xiangshan.ExceptionNO._
27c84054caSLinJiaweiimport xiangshan._
28db988794Swangkaifanimport xiangshan.backend.fu.util._
296ab6918fSYinan Xuimport xiangshan.cache._
30c84054caSLinJiawei
3172951335SLi Qianruo// Trigger Tdata1 bundles
3272951335SLi Qianruotrait HasTriggerConst {
3372951335SLi Qianruo  def I_Trigger = 0.U
3472951335SLi Qianruo  def S_Trigger = 1.U
3572951335SLi Qianruo  def L_Trigger = 2.U
36bc63e578SLi Qianruo  def GenESL(triggerType: UInt) = Cat((triggerType === I_Trigger), (triggerType === S_Trigger), (triggerType === L_Trigger))
3772951335SLi Qianruo}
3872951335SLi Qianruo
3972951335SLi Qianruoclass TdataBundle extends Bundle {
40716f717fSLi Qianruo  val ttype = UInt(4.W)
41716f717fSLi Qianruo  val dmode = Bool()
42716f717fSLi Qianruo  val maskmax = UInt(6.W)
43716f717fSLi Qianruo  val zero1 = UInt(30.W)
44716f717fSLi Qianruo  val sizehi = UInt(2.W)
45716f717fSLi Qianruo  val hit = Bool()
4672951335SLi Qianruo  val select = Bool()
4772951335SLi Qianruo  val timing = Bool()
48716f717fSLi Qianruo  val sizelo = UInt(2.W)
49716f717fSLi Qianruo  val action = UInt(4.W)
5072951335SLi Qianruo  val chain = Bool()
51716f717fSLi Qianruo  val matchType = UInt(4.W)
5272951335SLi Qianruo  val m = Bool()
53716f717fSLi Qianruo  val zero2 = Bool()
5472951335SLi Qianruo  val s = Bool()
5572951335SLi Qianruo  val u = Bool()
56716f717fSLi Qianruo  val execute = Bool()
57716f717fSLi Qianruo  val store = Bool()
58716f717fSLi Qianruo  val load = Bool()
5972951335SLi Qianruo}
6072951335SLi Qianruo
612225d46eSJiawei Linclass FpuCsrIO extends Bundle {
627f1506e3SLinJiawei  val fflags = Output(Valid(UInt(5.W)))
63c84054caSLinJiawei  val isIllegal = Output(Bool())
64c84054caSLinJiawei  val dirty_fs = Output(Bool())
65c84054caSLinJiawei  val frm = Input(UInt(3.W))
66c84054caSLinJiawei}
67c84054caSLinJiawei
68b2e234ebSLinJiawei
692225d46eSJiawei Linclass PerfCounterIO(implicit p: Parameters) extends XSBundle {
701ca0e4f3SYinan Xu  val perfEventsFrontend  = Vec(numCSRPCntFrontend, new PerfEvent)
711ca0e4f3SYinan Xu  val perfEventsCtrl      = Vec(numCSRPCntCtrl, new PerfEvent)
721ca0e4f3SYinan Xu  val perfEventsLsu       = Vec(numCSRPCntLsu, new PerfEvent)
731ca0e4f3SYinan Xu  val perfEventsHc        = Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)
74edd6ddbcSwakafa  val retiredInstr = UInt(3.W)
75edd6ddbcSwakafa  val frontendInfo = new Bundle {
76edd6ddbcSwakafa    val ibufFull  = Bool()
77e0d9a9f0SLingrui98    val bpuInfo = new Bundle {
78e0d9a9f0SLingrui98      val bpRight = UInt(XLEN.W)
79e0d9a9f0SLingrui98      val bpWrong = UInt(XLEN.W)
80e0d9a9f0SLingrui98    }
81edd6ddbcSwakafa  }
82edd6ddbcSwakafa  val ctrlInfo = new Bundle {
839aca92b9SYinan Xu    val robFull   = Bool()
84edd6ddbcSwakafa    val intdqFull = Bool()
85edd6ddbcSwakafa    val fpdqFull  = Bool()
86edd6ddbcSwakafa    val lsdqFull  = Bool()
87edd6ddbcSwakafa  }
88edd6ddbcSwakafa  val memInfo = new Bundle {
89edd6ddbcSwakafa    val sqFull = Bool()
90edd6ddbcSwakafa    val lqFull = Bool()
91edd6ddbcSwakafa    val dcacheMSHRFull = Bool()
92edd6ddbcSwakafa  }
93e0d9a9f0SLingrui98
94edd6ddbcSwakafa  val cacheInfo = new Bundle {
95edd6ddbcSwakafa    val l2MSHRFull = Bool()
96edd6ddbcSwakafa    val l3MSHRFull = Bool()
97edd6ddbcSwakafa    val l2nAcquire = UInt(XLEN.W)
98edd6ddbcSwakafa    val l2nAcquireMiss = UInt(XLEN.W)
99edd6ddbcSwakafa    val l3nAcquire = UInt(XLEN.W)
100edd6ddbcSwakafa    val l3nAcquireMiss = UInt(XLEN.W)
101edd6ddbcSwakafa  }
10262ab1317SYinan Xu}
10362ab1317SYinan Xu
1042225d46eSJiawei Linclass CSRFileIO(implicit p: Parameters) extends XSBundle {
1055668a921SJiawei Lin  val hartId = Input(UInt(8.W))
106129a273eSYinan Xu  // output (for func === CSROpType.jmp)
107edd6ddbcSwakafa  val perf = Input(new PerfCounterIO)
1088635f18fSwangkaifan  val isPerfCnt = Output(Bool())
109129a273eSYinan Xu  // to FPU
110129a273eSYinan Xu  val fpu = Flipped(new FpuCsrIO)
111bf9968b2SYinan Xu  // from rob
1123a474d38SYinan Xu  val exception = Flipped(ValidIO(new ExceptionInfo))
113129a273eSYinan Xu  // to ROB
114ac5a5d53SLinJiawei  val isXRet = Output(Bool())
115129a273eSYinan Xu  val trapTarget = Output(UInt(VAddrBits.W))
116129a273eSYinan Xu  val interrupt = Output(Bool())
117129a273eSYinan Xu  // from LSQ
118129a273eSYinan Xu  val memExceptionVAddr = Input(UInt(VAddrBits.W))
119129a273eSYinan Xu  // from outside cpu,externalInterrupt
120129a273eSYinan Xu  val externalInterrupt = new ExternalInterruptIO
121129a273eSYinan Xu  // TLB
122129a273eSYinan Xu  val tlb = Output(new TlbCsrBundle)
123d4aca96cSlqre  // Debug Mode
124d4aca96cSlqre  val singleStep = Output(Bool())
125d4aca96cSlqre  val debugMode = Output(Bool())
126e5adbe81SLemover  // to Fence to disable sfence
127e5adbe81SLemover  val disableSfence = Output(Bool())
128e377d77eSWilliam Wang  // Custom microarchiture ctrl signal
129e377d77eSWilliam Wang  val customCtrl = Output(new CustomCSRCtrlIO)
130e377d77eSWilliam Wang  // distributed csr write
13170899835SWilliam Wang  val distributedUpdate = Vec(2, Flipped(new DistributedCSRUpdateReq))
13235a47a38SYinan Xu}
13335a47a38SYinan Xu
13472951335SLi Qianruoclass CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMPMethod with PMAMethod with HasTriggerConst
13535a47a38SYinan Xu{
13635a47a38SYinan Xu  val csrio = IO(new CSRFileIO)
137c84054caSLinJiawei
138e18c367fSLinJiawei  val cfIn = io.in.bits.uop.cf
139e18c367fSLinJiawei  val cfOut = Wire(new CtrlFlow)
140e18c367fSLinJiawei  cfOut := cfIn
141e18c367fSLinJiawei  val flushPipe = Wire(Bool())
142c84054caSLinJiawei
143e18c367fSLinJiawei  val (valid, src1, src2, func) = (
144e18c367fSLinJiawei    io.in.valid,
145e18c367fSLinJiawei    io.in.bits.src(0),
146e18c367fSLinJiawei    io.in.bits.uop.ctrl.imm,
147e18c367fSLinJiawei    io.in.bits.uop.ctrl.fuOpType
148e18c367fSLinJiawei  )
149c84054caSLinJiawei
150c84054caSLinJiawei  // CSR define
151c84054caSLinJiawei
152c84054caSLinJiawei  class Priv extends Bundle {
153c84054caSLinJiawei    val m = Output(Bool())
154c84054caSLinJiawei    val h = Output(Bool())
155c84054caSLinJiawei    val s = Output(Bool())
156c84054caSLinJiawei    val u = Output(Bool())
157c84054caSLinJiawei  }
158c84054caSLinJiawei
159c84054caSLinJiawei  val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U)
160c84054caSLinJiawei
161d4aca96cSlqre  class DcsrStruct extends Bundle {
162d4aca96cSlqre    val xdebugver = Output(UInt(2.W))
163d4aca96cSlqre    val zero4 = Output(UInt(2.W))
164d4aca96cSlqre    val zero3 = Output(UInt(12.W))
165d4aca96cSlqre    val ebreakm = Output(Bool())
166d4aca96cSlqre    val ebreakh = Output(Bool())
167d4aca96cSlqre    val ebreaks = Output(Bool())
168d4aca96cSlqre    val ebreaku = Output(Bool())
169d4aca96cSlqre    val zero2 = Output(Bool())
170d4aca96cSlqre    val stopcycle = Output(Bool())
171d4aca96cSlqre    val stoptime = Output(Bool())
172d4aca96cSlqre    val cause = Output(UInt(3.W))
173d4aca96cSlqre    val zero1 = Output(UInt(3.W))
174d4aca96cSlqre    val step = Output(Bool())
175d4aca96cSlqre    val prv = Output(UInt(2.W))
176d4aca96cSlqre  }
177d4aca96cSlqre
178c84054caSLinJiawei  class MstatusStruct extends Bundle {
179c84054caSLinJiawei    val sd = Output(UInt(1.W))
1808e7b11e5SWilliam Wang
1817d9edc86SLemover    val pad1 = if (XLEN == 64) Output(UInt(25.W)) else null
1827d9edc86SLemover    val mbe  = if (XLEN == 64) Output(UInt(1.W)) else null
1837d9edc86SLemover    val sbe  = if (XLEN == 64) Output(UInt(1.W)) else null
1848e7b11e5SWilliam Wang    val sxl  = if (XLEN == 64) Output(UInt(2.W))  else null
1858e7b11e5SWilliam Wang    val uxl  = if (XLEN == 64) Output(UInt(2.W))  else null
1868e7b11e5SWilliam Wang    val pad0 = if (XLEN == 64) Output(UInt(9.W))  else Output(UInt(8.W))
1878e7b11e5SWilliam Wang
188c84054caSLinJiawei    val tsr = Output(UInt(1.W))
189c84054caSLinJiawei    val tw = Output(UInt(1.W))
1908e7b11e5SWilliam Wang    val tvm = Output(UInt(1.W))
191c84054caSLinJiawei    val mxr = Output(UInt(1.W))
192c84054caSLinJiawei    val sum = Output(UInt(1.W))
193c84054caSLinJiawei    val mprv = Output(UInt(1.W))
194c84054caSLinJiawei    val xs = Output(UInt(2.W))
195c84054caSLinJiawei    val fs = Output(UInt(2.W))
196c84054caSLinJiawei    val mpp = Output(UInt(2.W))
197c84054caSLinJiawei    val hpp = Output(UInt(2.W))
198c84054caSLinJiawei    val spp = Output(UInt(1.W))
199c84054caSLinJiawei    val pie = new Priv
200c84054caSLinJiawei    val ie = new Priv
201c84054caSLinJiawei    assert(this.getWidth == XLEN)
2027d9edc86SLemover
2037d9edc86SLemover    def ube = pie.h // a little ugly
2047d9edc86SLemover    def ube_(r: UInt): Unit = {
2057d9edc86SLemover      pie.h := r(0)
2067d9edc86SLemover    }
207c84054caSLinJiawei  }
208c84054caSLinJiawei
209c84054caSLinJiawei  class Interrupt extends Bundle {
210d4aca96cSlqre//  val d = Output(Bool())    // Debug
211c84054caSLinJiawei    val e = new Priv
212c84054caSLinJiawei    val t = new Priv
213c84054caSLinJiawei    val s = new Priv
214c84054caSLinJiawei  }
215c84054caSLinJiawei
216d4aca96cSlqre  // Debug CSRs
217d4aca96cSlqre  val dcsr = RegInit(UInt(32.W), 0x4000b010.U)
218d4aca96cSlqre  val dpc = Reg(UInt(64.W))
219d4aca96cSlqre  val dscratch = Reg(UInt(64.W))
220d4aca96cSlqre  val dscratch1 = Reg(UInt(64.W))
221d4aca96cSlqre  val debugMode = RegInit(false.B)
222d4aca96cSlqre  val debugIntrEnable = RegInit(true.B)
223d4aca96cSlqre  csrio.debugMode := debugMode
224d4aca96cSlqre
225d4aca96cSlqre  val dpcPrev = RegNext(dpc)
2261097f021SLi Qianruo  XSDebug(dpcPrev =/= dpc, "Debug Mode: dpc is altered! Current is %x, previous is %x\n", dpc, dpcPrev)
227d4aca96cSlqre
228d4aca96cSlqre  // dcsr value table
229d4aca96cSlqre  // | debugver | 0100
230d4aca96cSlqre  // | zero     | 10 bits of 0
231d4aca96cSlqre  // | ebreakvs | 0
232d4aca96cSlqre  // | ebreakvu | 0
233d4aca96cSlqre  // | ebreakm  | 1 if ebreak enters debug
234d4aca96cSlqre  // | zero     | 0
235d4aca96cSlqre  // | ebreaks  |
236d4aca96cSlqre  // | ebreaku  |
237d4aca96cSlqre  // | stepie   | 0 disable interrupts in singlestep
238d4aca96cSlqre  // | stopcount| stop counter, 0
239d4aca96cSlqre  // | stoptime | stop time, 0
240d4aca96cSlqre  // | cause    | 3 bits read only
241d4aca96cSlqre  // | v        | 0
242d4aca96cSlqre  // | mprven   | 1
243d4aca96cSlqre  // | nmip     | read only
244d4aca96cSlqre  // | step     |
245d4aca96cSlqre  // | prv      | 2 bits
246ad3ba452Szhanglinjuan
247d4aca96cSlqre  val dcsrData = Wire(new DcsrStruct)
248d4aca96cSlqre  dcsrData := dcsr.asTypeOf(new DcsrStruct)
2495dabf2dfSYinan Xu  val dcsrMask = ZeroExt(GenMask(15) | GenMask(13, 11) | GenMask(2, 0), XLEN)// Dcsr write mask
250d4aca96cSlqre  def dcsrUpdateSideEffect(dcsr: UInt): UInt = {
251d4aca96cSlqre    val dcsrOld = WireInit(dcsr.asTypeOf(new DcsrStruct))
252d4aca96cSlqre    val dcsrNew = dcsr | (dcsrOld.prv(0) | dcsrOld.prv(1)).asUInt // turn 10 priv into 11
253d4aca96cSlqre    dcsrNew
254d4aca96cSlqre  }
255d4aca96cSlqre  csrio.singleStep := dcsrData.step
256ddb65c47SLi Qianruo  csrio.customCtrl.singlestep := dcsrData.step
257d4aca96cSlqre
25872951335SLi Qianruo  // Trigger CSRs
25972951335SLi Qianruo
260716f717fSLi Qianruo  val type_config = Array(
261716f717fSLi Qianruo    0.U -> I_Trigger, 1.U -> I_Trigger,
262716f717fSLi Qianruo    2.U -> S_Trigger, 3.U -> S_Trigger,
263716f717fSLi Qianruo    4.U -> L_Trigger, 5.U -> L_Trigger, // No.5 Load Trigger
264716f717fSLi Qianruo    6.U -> I_Trigger, 7.U -> S_Trigger,
265716f717fSLi Qianruo    8.U -> I_Trigger, 9.U -> L_Trigger
266716f717fSLi Qianruo  )
267716f717fSLi Qianruo  def TypeLookup(select: UInt) = MuxLookup(select, I_Trigger, type_config)
268716f717fSLi Qianruo
269ddb65c47SLi Qianruo  val tdata1Phy = RegInit(VecInit(List.fill(10) {(2L << 60L).U(64.W)})) // init ttype 2
27072951335SLi Qianruo  val tdata2Phy = Reg(Vec(10, UInt(64.W)))
27172951335SLi Qianruo  val tselectPhy = RegInit(0.U(4.W))
272ddb65c47SLi Qianruo  val tDummy1 = WireInit(0.U(64.W))
273ddb65c47SLi Qianruo  val tDummy2 = WireInit(0.U(64.W))
274716f717fSLi Qianruo  val tdata1Wire = Wire(UInt(64.W))
275716f717fSLi Qianruo  val tdata2Wire = Wire(UInt(64.W))
276716f717fSLi Qianruo  val tinfo = RegInit(2.U(64.W))
27772951335SLi Qianruo  val tControlPhy = RegInit(0.U(64.W))
27884e47f35SLi Qianruo  val triggerAction = RegInit(false.B)
279716f717fSLi Qianruo  tdata1Wire := tdata1Phy(tselectPhy)
280716f717fSLi Qianruo  tdata2Wire := tdata2Phy(tselectPhy)
281ddb65c47SLi Qianruo  tDummy1 := tdata1Phy(tselectPhy)
282ddb65c47SLi Qianruo  tDummy2 := tdata2Phy(tselectPhy)
283716f717fSLi Qianruo
28472951335SLi Qianruo  def ReadTdata1(rdata: UInt) = {
285716f717fSLi Qianruo    val tdata1 = WireInit(tdata1Wire)
286716f717fSLi Qianruo    val read_data = tdata1Wire
287716f717fSLi Qianruo    XSDebug(src2(11, 0) === Tdata1.U && valid, p"\nDebug Mode: tdata1(${tselectPhy})is read, the actual value is ${Binary(tdata1)}\n")
288ddb65c47SLi Qianruo    read_data | (triggerAction << 12) // fix action
28972951335SLi Qianruo  }
29072951335SLi Qianruo  def WriteTdata1(wdata: UInt) = {
291716f717fSLi Qianruo    val tdata1 = WireInit(tdata1Wire.asTypeOf(new TdataBundle))
292716f717fSLi Qianruo    val wdata_wire = WireInit(wdata.asTypeOf(new TdataBundle))
293716f717fSLi Qianruo    val tdata1_new = WireInit(wdata.asTypeOf(new TdataBundle))
294716f717fSLi Qianruo    XSDebug(src2(11, 0) === Tdata1.U && valid && func =/= CSROpType.jmp, p"Debug Mode: tdata1(${tselectPhy})is written, the actual value is ${wdata}\n")
29584e47f35SLi Qianruo//    tdata1_new.hit := wdata(20)
296ddb65c47SLi Qianruo    tdata1_new.ttype := tdata1.ttype
297ddb65c47SLi Qianruo    tdata1_new.dmode := Mux(debugMode, wdata_wire.dmode, tdata1.dmode)
298ddb65c47SLi Qianruo    tdata1_new.maskmax := 0.U
299ddb65c47SLi Qianruo    tdata1_new.hit := 0.U
300716f717fSLi Qianruo    tdata1_new.select := (TypeLookup(tselectPhy) === I_Trigger) && wdata_wire.select
301716f717fSLi Qianruo    when(wdata_wire.action <= 1.U){
302716f717fSLi Qianruo      triggerAction := tdata1_new.action(0)
303716f717fSLi Qianruo    } .otherwise{
304716f717fSLi Qianruo      tdata1_new.action := tdata1.action
305716f717fSLi Qianruo    }
306ddb65c47SLi Qianruo    tdata1_new.timing := false.B // hardwire this because we have singlestep
307716f717fSLi Qianruo    tdata1_new.zero1 := 0.U
308716f717fSLi Qianruo    tdata1_new.zero2 := 0.U
309716f717fSLi Qianruo    tdata1_new.chain := !tselectPhy(0) && wdata_wire.chain
310716f717fSLi Qianruo    when(wdata_wire.matchType =/= 0.U && wdata_wire.matchType =/= 2.U && wdata_wire.matchType =/= 3.U) {
311716f717fSLi Qianruo      tdata1_new.matchType := tdata1.matchType
312716f717fSLi Qianruo    }
313ddb65c47SLi Qianruo    tdata1_new.sizehi := Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 0.U, 1.U)
314ddb65c47SLi Qianruo    tdata1_new.sizelo:= Mux(wdata_wire.select && TypeLookup(tselectPhy) === I_Trigger, 3.U, 1.U)
315716f717fSLi Qianruo    tdata1_new.execute := TypeLookup(tselectPhy) === I_Trigger
316716f717fSLi Qianruo    tdata1_new.store := TypeLookup(tselectPhy) === S_Trigger
317716f717fSLi Qianruo    tdata1_new.load := TypeLookup(tselectPhy) === L_Trigger
318716f717fSLi Qianruo    when(valid && func =/= CSROpType.jmp && addr === Tdata1.U) {
319716f717fSLi Qianruo      tdata1Phy(tselectPhy) := tdata1_new.asUInt()
320716f717fSLi Qianruo    }
32172951335SLi Qianruo    0.U
32272951335SLi Qianruo  }
32372951335SLi Qianruo
32472951335SLi Qianruo  def WriteTselect(wdata: UInt) = {
325716f717fSLi Qianruo    Mux(wdata < 10.U, wdata(3, 0), tselectPhy)
32672951335SLi Qianruo  }
32772951335SLi Qianruo
32872951335SLi Qianruo  def ReadTdata2(tdata: UInt) = tdata2Phy(tselectPhy)
32972951335SLi Qianruo  def WriteTdata2(wdata: UInt) = {
330716f717fSLi Qianruo    when(valid && func =/= CSROpType.jmp && addr === Tdata2.U) {
33172951335SLi Qianruo      tdata2Phy(tselectPhy) := wdata
332716f717fSLi Qianruo    }
33372951335SLi Qianruo    0.U
33472951335SLi Qianruo  }
33572951335SLi Qianruo
33672951335SLi Qianruo
33772951335SLi Qianruo  val tcontrolWriteMask = ZeroExt(GenMask(3) | GenMask(7), XLEN)
33872951335SLi Qianruo
33972951335SLi Qianruo
34072951335SLi Qianruo  def GenTdataDistribute(tdata1: TdataBundle, tdata2: UInt): MatchTriggerIO = {
34172951335SLi Qianruo    val res = Wire(new MatchTriggerIO)
34272951335SLi Qianruo    res.matchType := tdata1.matchType
34372951335SLi Qianruo    res.select := tdata1.select
34472951335SLi Qianruo    res.timing := tdata1.timing
34584e47f35SLi Qianruo    res.action := triggerAction
34672951335SLi Qianruo    res.chain := tdata1.chain
34772951335SLi Qianruo    res.tdata2 := tdata2
34872951335SLi Qianruo    res
34972951335SLi Qianruo  }
35072951335SLi Qianruo
35172951335SLi Qianruo  csrio.customCtrl.frontend_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U, Seq(
35272951335SLi Qianruo    0.U -> 0.U,
35372951335SLi Qianruo    1.U -> 1.U,
35472951335SLi Qianruo    6.U -> 2.U,
35572951335SLi Qianruo    8.U -> 3.U
35672951335SLi Qianruo  ))
35772951335SLi Qianruo  csrio.customCtrl.mem_trigger.t.bits.addr := MuxLookup(tselectPhy, 0.U, Seq(
35872951335SLi Qianruo    2.U -> 0.U,
35972951335SLi Qianruo    3.U -> 1.U,
36072951335SLi Qianruo    4.U -> 2.U,
36172951335SLi Qianruo    5.U -> 3.U,
36272951335SLi Qianruo    7.U -> 4.U,
36372951335SLi Qianruo    9.U -> 5.U
36472951335SLi Qianruo  ))
365716f717fSLi Qianruo  csrio.customCtrl.frontend_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy).asTypeOf(new TdataBundle), tdata2Phy(tselectPhy))
366716f717fSLi Qianruo  csrio.customCtrl.mem_trigger.t.bits.tdata := GenTdataDistribute(tdata1Phy(tselectPhy).asTypeOf(new TdataBundle), tdata2Phy(tselectPhy))
36772951335SLi Qianruo
368c84054caSLinJiawei  // Machine-Level CSRs
369*a4e57ea3SLi Qianruo  // mtvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1
370*a4e57ea3SLi Qianruo  val mtvecMask = ~(0x2.U(XLEN.W))
371c84054caSLinJiawei  val mtvec = RegInit(UInt(XLEN.W), 0.U)
372c84054caSLinJiawei  val mcounteren = RegInit(UInt(XLEN.W), 0.U)
373c84054caSLinJiawei  val mcause = RegInit(UInt(XLEN.W), 0.U)
374c84054caSLinJiawei  val mtval = RegInit(UInt(XLEN.W), 0.U)
375c84054caSLinJiawei  val mepc = Reg(UInt(XLEN.W))
376e30fd06aSYinan Xu  // Page 36 in riscv-priv: The low bit of mepc (mepc[0]) is always zero.
377e30fd06aSYinan Xu  val mepcMask = ~(0x1.U(XLEN.W))
378c84054caSLinJiawei
379c84054caSLinJiawei  val mie = RegInit(0.U(XLEN.W))
380c84054caSLinJiawei  val mipWire = WireInit(0.U.asTypeOf(new Interrupt))
3815dabf2dfSYinan Xu  val mipReg  = RegInit(0.U(XLEN.W))
3825dabf2dfSYinan Xu  val mipFixMask = ZeroExt(GenMask(9) | GenMask(5) | GenMask(1), XLEN)
383c84054caSLinJiawei  val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt)
384c84054caSLinJiawei
385b2e234ebSLinJiawei  def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt()
386b2e234ebSLinJiawei  def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt()
387c84054caSLinJiawei  var extList = List('a', 's', 'i', 'u')
388c84054caSLinJiawei  if (HasMExtension) { extList = extList :+ 'm' }
389c84054caSLinJiawei  if (HasCExtension) { extList = extList :+ 'c' }
390c84054caSLinJiawei  if (HasFPU) { extList = extList ++ List('f', 'd') }
391c84054caSLinJiawei  val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U
392c84054caSLinJiawei  val misa = RegInit(UInt(XLEN.W), misaInitVal)
393bc5ff277Swangkaifan
394c84054caSLinJiawei  // MXL = 2          | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101
395c84054caSLinJiawei  // (XLEN-1, XLEN-2) |   |(25, 0)  ZY XWVU TSRQ PONM LKJI HGFE DCBA
396c84054caSLinJiawei
397c84054caSLinJiawei  val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation
398c84054caSLinJiawei  val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented
399c84054caSLinJiawei  val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation
4007a77cff2SYinan Xu  val mhartid = RegInit(UInt(XLEN.W), csrio.hartId) // the hardware thread running the code
4017d9edc86SLemover  val mconfigptr = RegInit(UInt(XLEN.W), 0.U) // the read-only pointer pointing to the platform config structure, 0 for not supported.
402e30fd06aSYinan Xu  val mstatus = RegInit("ha00000000".U(XLEN.W))
403bc5ff277Swangkaifan
404c84054caSLinJiawei  // mstatus Value Table
405c84054caSLinJiawei  // | sd   |
406c84054caSLinJiawei  // | pad1 |
407c84054caSLinJiawei  // | sxl  | hardlinked to 10, use 00 to pass xv6 test
408e30fd06aSYinan Xu  // | uxl  | hardlinked to 10
409c84054caSLinJiawei  // | pad0 |
410c84054caSLinJiawei  // | tsr  |
411c84054caSLinJiawei  // | tw   |
4128e7b11e5SWilliam Wang  // | tvm  |
413c84054caSLinJiawei  // | mxr  |
414c84054caSLinJiawei  // | sum  |
415c84054caSLinJiawei  // | mprv |
416c84054caSLinJiawei  // | xs   | 00 |
4178e7b11e5SWilliam Wang  // | fs   | 00 |
418c84054caSLinJiawei  // | mpp  | 00 |
419c84054caSLinJiawei  // | hpp  | 00 |
420c84054caSLinJiawei  // | spp  | 0 |
4218e7b11e5SWilliam Wang  // | pie  | 0000 | pie.h is used as UBE
422c84054caSLinJiawei  // | ie   | 0000 | uie hardlinked to 0, as N ext is not implemented
423bc5ff277Swangkaifan
424c84054caSLinJiawei  val mstatusStruct = mstatus.asTypeOf(new MstatusStruct)
425c84054caSLinJiawei  def mstatusUpdateSideEffect(mstatus: UInt): UInt = {
426c84054caSLinJiawei    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
4278e7b11e5SWilliam Wang    val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0))
428c84054caSLinJiawei    mstatusNew
429c84054caSLinJiawei  }
430c84054caSLinJiawei
431e30fd06aSYinan Xu  val mstatusWMask = (~ZeroExt((
432e30fd06aSYinan Xu    GenMask(XLEN - 2, 36) | // WPRI
433e30fd06aSYinan Xu    GenMask(35, 32)       | // SXL and UXL cannot be changed
434e30fd06aSYinan Xu    GenMask(31, 23)       | // WPRI
435705cbec3SLemover    GenMask(16, 15)       | // XS is read-only
436e30fd06aSYinan Xu    GenMask(10, 9)        | // WPRI
437e30fd06aSYinan Xu    GenMask(6)            | // WPRI
438e30fd06aSYinan Xu    GenMask(2)              // WPRI
439e30fd06aSYinan Xu  ), 64)).asUInt()
440b2e234ebSLinJiawei  val mstatusMask = (~ZeroExt((
441e30fd06aSYinan Xu    GenMask(XLEN - 2, 36) | // WPRI
442e30fd06aSYinan Xu    GenMask(31, 23)       | // WPRI
443e30fd06aSYinan Xu    GenMask(10, 9)        | // WPRI
444e30fd06aSYinan Xu    GenMask(6)            | // WPRI
445e30fd06aSYinan Xu    GenMask(2)              // WPRI
446b2e234ebSLinJiawei  ), 64)).asUInt()
4478e7b11e5SWilliam Wang
448c84054caSLinJiawei  val medeleg = RegInit(UInt(XLEN.W), 0.U)
449c84054caSLinJiawei  val mideleg = RegInit(UInt(XLEN.W), 0.U)
450c84054caSLinJiawei  val mscratch = RegInit(UInt(XLEN.W), 0.U)
451c84054caSLinJiawei
452b6982e83SLemover  // PMP Mapping
453ca2f90a6SLemover  val pmp = Wire(Vec(NumPMP, new PMPEntry())) // just used for method parameter
454ca2f90a6SLemover  val pma = Wire(Vec(NumPMA, new PMPEntry())) // just used for method parameter
455ca2f90a6SLemover  val pmpMapping = pmp_gen_mapping(pmp_init, NumPMP, PmpcfgBase, PmpaddrBase, pmp)
456ca2f90a6SLemover  val pmaMapping = pmp_gen_mapping(pma_init, NumPMA, PmacfgBase, PmaaddrBase, pma)
457c84054caSLinJiawei
458c84054caSLinJiawei  // Superviser-Level CSRs
459c84054caSLinJiawei
460c84054caSLinJiawei  // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U)
4615dabf2dfSYinan Xu  val sstatusWmask = "hc6122".U(XLEN.W)
462c84054caSLinJiawei  // Sstatus Write Mask
463c84054caSLinJiawei  // -------------------------------------------------------
464c84054caSLinJiawei  //    19           9   5     2
465c84054caSLinJiawei  // 0  1100 0000 0001 0010 0010
466c84054caSLinJiawei  // 0  c    0    1    2    2
467c84054caSLinJiawei  // -------------------------------------------------------
468c84054caSLinJiawei  val sstatusRmask = sstatusWmask | "h8000000300018000".U
469c84054caSLinJiawei  // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32))
470*a4e57ea3SLi Qianruo  // stvec: {BASE (WARL), MODE (WARL)} where mode is 0 or 1
471*a4e57ea3SLi Qianruo  val stvecMask = ~(0x2.U(XLEN.W))
472c84054caSLinJiawei  val stvec = RegInit(UInt(XLEN.W), 0.U)
473c84054caSLinJiawei  // val sie = RegInit(0.U(XLEN.W))
474c84054caSLinJiawei  val sieMask = "h222".U & mideleg
475c84054caSLinJiawei  val sipMask = "h222".U & mideleg
4765dabf2dfSYinan Xu  val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode
47734230194Sjinyue110  val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W))
478df2b1479SZhangZifei  // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug
47945f497a4Shappy-lx  // val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0
48045f497a4Shappy-lx  // TODO: use config to control the length of asid
48145f497a4Shappy-lx  // val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0
482705cbec3SLemover  val satpMask = Cat("h8".U(Satp_Mode_len.W), satp_part_wmask(Satp_Asid_len, AsidLength), satp_part_wmask(Satp_Addr_len, PAddrBits-12))
483c84054caSLinJiawei  val sepc = RegInit(UInt(XLEN.W), 0.U)
484e30fd06aSYinan Xu  // Page 60 in riscv-priv: The low bit of sepc (sepc[0]) is always zero.
485e30fd06aSYinan Xu  val sepcMask = ~(0x1.U(XLEN.W))
486c84054caSLinJiawei  val scause = RegInit(UInt(XLEN.W), 0.U)
487c84054caSLinJiawei  val stval = Reg(UInt(XLEN.W))
488c84054caSLinJiawei  val sscratch = RegInit(UInt(XLEN.W), 0.U)
489c84054caSLinJiawei  val scounteren = RegInit(UInt(XLEN.W), 0.U)
490fcff7e94SZhangZifei
491eedc2e58SSteve Gou  // sbpctl
492eedc2e58SSteve Gou  // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB}
493eedc2e58SSteve Gou  val sbpctl = RegInit(UInt(XLEN.W), "h7f".U)
494eedc2e58SSteve Gou  csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0)
495eedc2e58SSteve Gou  csrio.customCtrl.bp_ctrl.btb_enable  := sbpctl(1)
496eedc2e58SSteve Gou  csrio.customCtrl.bp_ctrl.bim_enable  := sbpctl(2)
497eedc2e58SSteve Gou  csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3)
498eedc2e58SSteve Gou  csrio.customCtrl.bp_ctrl.sc_enable   := sbpctl(4)
499eedc2e58SSteve Gou  csrio.customCtrl.bp_ctrl.ras_enable  := sbpctl(5)
500eedc2e58SSteve Gou  csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6)
5012b8b2e7aSWilliam Wang
5022b8b2e7aSWilliam Wang  // spfctl Bit 0: L1plusCache Prefetcher Enable
5032b8b2e7aSWilliam Wang  // spfctl Bit 1: L2Cache Prefetcher Enable
5042b8b2e7aSWilliam Wang  val spfctl = RegInit(UInt(XLEN.W), "h3".U)
50535a47a38SYinan Xu  csrio.customCtrl.l1plus_pf_enable := spfctl(0)
50635a47a38SYinan Xu  csrio.customCtrl.l2_pf_enable := spfctl(1)
5072b8b2e7aSWilliam Wang
5082b8b2e7aSWilliam Wang  // sdsid: Differentiated Services ID
5092b8b2e7aSWilliam Wang  val sdsid = RegInit(UInt(XLEN.W), 0.U)
51035a47a38SYinan Xu  csrio.customCtrl.dsid := sdsid
51135a47a38SYinan Xu
5122b8b2e7aSWilliam Wang  // slvpredctl: load violation predict settings
5132b8b2e7aSWilliam Wang  val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17
5142b8b2e7aSWilliam Wang  csrio.customCtrl.lvpred_disable := slvpredctl(0)
5152b8b2e7aSWilliam Wang  csrio.customCtrl.no_spec_load := slvpredctl(1)
516c7160cd3SWilliam Wang  csrio.customCtrl.storeset_wait_store := slvpredctl(2)
517c7160cd3SWilliam Wang  csrio.customCtrl.storeset_no_fast_wakeup := slvpredctl(3)
518c7160cd3SWilliam Wang  csrio.customCtrl.lvpred_timeout := slvpredctl(8, 4)
5192b8b2e7aSWilliam Wang
520f3f22d72SYinan Xu  // smblockctl: memory block configurations
521f3f22d72SYinan Xu  // bits 0-3: store buffer flush threshold (default: 8 entries)
52267682d05SWilliam Wang  val smblockctl_init_val =
52367682d05SWilliam Wang    ("hf".U & StoreBufferThreshold.U) |
524*a4e57ea3SLi Qianruo    (EnableLdVioCheckAfterReset.B.asUInt << 4) |
525*a4e57ea3SLi Qianruo    (EnableSoftPrefetchAfterReset.B.asUInt << 5) |
526*a4e57ea3SLi Qianruo    (EnableCacheErrorAfterReset.B.asUInt << 6)
52767682d05SWilliam Wang  val smblockctl = RegInit(UInt(XLEN.W), smblockctl_init_val)
528f3f22d72SYinan Xu  csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0)
52967682d05SWilliam Wang  // bits 4: enable load load violation check
530*a4e57ea3SLi Qianruo  csrio.customCtrl.ldld_vio_check_enable := smblockctl(4)
531*a4e57ea3SLi Qianruo  csrio.customCtrl.soft_prefetch_enable := smblockctl(5)
532*a4e57ea3SLi Qianruo  csrio.customCtrl.cache_error_enable := smblockctl(6)
533*a4e57ea3SLi Qianruo
534*a4e57ea3SLi Qianruo  println("CSR smblockctl init value:")
535*a4e57ea3SLi Qianruo  println("  Store buffer replace threshold: " + StoreBufferThreshold)
536*a4e57ea3SLi Qianruo  println("  Enable ld-ld vio check after reset: " + EnableLdVioCheckAfterReset)
537*a4e57ea3SLi Qianruo  println("  Enable soft prefetch after reset: " + EnableSoftPrefetchAfterReset)
538*a4e57ea3SLi Qianruo  println("  Enable cache error after reset: " + EnableCacheErrorAfterReset)
539f3f22d72SYinan Xu
540af2f7849Shappy-lx  val srnctl = RegInit(UInt(XLEN.W), "h3".U)
541aac4464eSYinan Xu  csrio.customCtrl.move_elim_enable := srnctl(0)
542af2f7849Shappy-lx  csrio.customCtrl.svinval_enable := srnctl(1)
543aac4464eSYinan Xu
5442b8b2e7aSWilliam Wang  val tlbBundle = Wire(new TlbCsrBundle)
54545f497a4Shappy-lx  tlbBundle.satp.apply(satp)
546b6982e83SLemover
5472b8b2e7aSWilliam Wang  csrio.tlb := tlbBundle
5482b8b2e7aSWilliam Wang
549c84054caSLinJiawei  // User-Level CSRs
550c84054caSLinJiawei  val uepc = Reg(UInt(XLEN.W))
551c84054caSLinJiawei
552c84054caSLinJiawei  // fcsr
553c84054caSLinJiawei  class FcsrStruct extends Bundle {
554c84054caSLinJiawei    val reserved = UInt((XLEN-3-5).W)
555c84054caSLinJiawei    val frm = UInt(3.W)
556c84054caSLinJiawei    val fflags = UInt(5.W)
557c84054caSLinJiawei    assert(this.getWidth == XLEN)
558c84054caSLinJiawei  }
559c84054caSLinJiawei  val fcsr = RegInit(0.U(XLEN.W))
560c84054caSLinJiawei  // set mstatus->sd and mstatus->fs when true
561c84054caSLinJiawei  val csrw_dirty_fp_state = WireInit(false.B)
562c84054caSLinJiawei
563c84054caSLinJiawei  def frm_wfn(wdata: UInt): UInt = {
564c84054caSLinJiawei    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
565c84054caSLinJiawei    csrw_dirty_fp_state := true.B
566c84054caSLinJiawei    fcsrOld.frm := wdata(2,0)
567c84054caSLinJiawei    fcsrOld.asUInt()
568c84054caSLinJiawei  }
569c84054caSLinJiawei  def frm_rfn(rdata: UInt): UInt = rdata(7,5)
570c84054caSLinJiawei
5717132faa5SLinJiawei  def fflags_wfn(update: Boolean)(wdata: UInt): UInt = {
5727132faa5SLinJiawei    val fcsrOld = fcsr.asTypeOf(new FcsrStruct)
5737132faa5SLinJiawei    val fcsrNew = WireInit(fcsrOld)
574c84054caSLinJiawei    csrw_dirty_fp_state := true.B
5757132faa5SLinJiawei    if (update) {
5767132faa5SLinJiawei      fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags
5777132faa5SLinJiawei    } else {
5787132faa5SLinJiawei      fcsrNew.fflags := wdata(4,0)
5797132faa5SLinJiawei    }
5807132faa5SLinJiawei    fcsrNew.asUInt()
581c84054caSLinJiawei  }
582c84054caSLinJiawei  def fflags_rfn(rdata:UInt): UInt = rdata(4,0)
583c84054caSLinJiawei
584c84054caSLinJiawei  def fcsr_wfn(wdata: UInt): UInt = {
585c84054caSLinJiawei    val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct))
586c84054caSLinJiawei    csrw_dirty_fp_state := true.B
587c84054caSLinJiawei    Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags)
588c84054caSLinJiawei  }
589c84054caSLinJiawei
590c84054caSLinJiawei  val fcsrMapping = Map(
5917132faa5SLinJiawei    MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn),
592c84054caSLinJiawei    MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn),
593c84054caSLinJiawei    MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn)
594c84054caSLinJiawei  )
595c84054caSLinJiawei
596c84054caSLinJiawei  // Hart Priviledge Mode
597c84054caSLinJiawei  val priviledgeMode = RegInit(UInt(2.W), ModeM)
598c84054caSLinJiawei
599cd365d4cSrvcoresjw  //val perfEventscounten = List.fill(nrPerfCnts)(RegInit(false(Bool())))
6008635f18fSwangkaifan  // Perf Counter
6018635f18fSwangkaifan  val nrPerfCnts = 29  // 3...31
602cd365d4cSrvcoresjw  val priviledgeModeOH = UIntToOH(priviledgeMode)
603cd365d4cSrvcoresjw  val perfEventscounten = RegInit(0.U.asTypeOf(Vec(nrPerfCnts, Bool())))
6048635f18fSwangkaifan  val perfCnts   = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W)))
6058c7b0b2fSrvcoresjw  val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++
60612c44ce5Srvcoresjw                   List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++
60712c44ce5Srvcoresjw                   List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++
60812c44ce5Srvcoresjw                   List.fill(5)(RegInit("hc0300c0300".U(XLEN.W)))
609cd365d4cSrvcoresjw  for (i <-0 until nrPerfCnts) {
610cd365d4cSrvcoresjw    perfEventscounten(i) := (Cat(perfEvents(i)(62),perfEvents(i)(61),(perfEvents(i)(61,60))) & priviledgeModeOH).orR
611cd365d4cSrvcoresjw  }
612cd365d4cSrvcoresjw
6131ca0e4f3SYinan Xu  val hpmEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
614cd365d4cSrvcoresjw  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
6151ca0e4f3SYinan Xu    hpmEvents(i) := csrio.perf.perfEventsHc(i)
616cd365d4cSrvcoresjw  }
617cd365d4cSrvcoresjw
61812c44ce5Srvcoresjw  val csrevents = perfEvents.slice(24, 29)
6191ca0e4f3SYinan Xu  val hpm_hc = HPerfMonitor(csrevents, hpmEvents)
6208635f18fSwangkaifan  val mcountinhibit = RegInit(0.U(XLEN.W))
621b03ddc86Swangkaifan  val mcycle = RegInit(0.U(XLEN.W))
622b03ddc86Swangkaifan  mcycle := mcycle + 1.U
623b03ddc86Swangkaifan  val minstret = RegInit(0.U(XLEN.W))
6241ca0e4f3SYinan Xu  val perf_events = csrio.perf.perfEventsFrontend ++
6251ca0e4f3SYinan Xu                    csrio.perf.perfEventsCtrl ++
6261ca0e4f3SYinan Xu                    csrio.perf.perfEventsLsu ++
6271ca0e4f3SYinan Xu                    hpm_hc.getPerf
628b03ddc86Swangkaifan  minstret := minstret + RegNext(csrio.perf.retiredInstr)
6295fd90906Srvcoresjw  for(i <- 0 until 29){
6301ca0e4f3SYinan Xu    perfCnts(i) := Mux(mcountinhibit(i+3) | !perfEventscounten(i), perfCnts(i), perfCnts(i) + perf_events(i).value)
6315fd90906Srvcoresjw  }
6328635f18fSwangkaifan
633c84054caSLinJiawei  // CSR reg map
63421fa8708Swangkaifan  val basicPrivMapping = Map(
635c84054caSLinJiawei
63621fa8708Swangkaifan    //--- User Trap Setup ---
637c84054caSLinJiawei    // MaskedRegMap(Ustatus, ustatus),
638c84054caSLinJiawei    // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable),
639c84054caSLinJiawei    // MaskedRegMap(Utvec, utvec),
640c84054caSLinJiawei
64121fa8708Swangkaifan    //--- User Trap Handling ---
642c84054caSLinJiawei    // MaskedRegMap(Uscratch, uscratch),
643c84054caSLinJiawei    // MaskedRegMap(Uepc, uepc),
644c84054caSLinJiawei    // MaskedRegMap(Ucause, ucause),
645c84054caSLinJiawei    // MaskedRegMap(Utval, utval),
646c84054caSLinJiawei    // MaskedRegMap(Uip, uip),
647c84054caSLinJiawei
64821fa8708Swangkaifan    //--- User Counter/Timers ---
649c84054caSLinJiawei    // MaskedRegMap(Cycle, cycle),
650c84054caSLinJiawei    // MaskedRegMap(Time, time),
651c84054caSLinJiawei    // MaskedRegMap(Instret, instret),
652c84054caSLinJiawei
65321fa8708Swangkaifan    //--- Supervisor Trap Setup ---
654c84054caSLinJiawei    MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask),
655c84054caSLinJiawei    // MaskedRegMap(Sedeleg, Sedeleg),
656c84054caSLinJiawei    // MaskedRegMap(Sideleg, Sideleg),
657c84054caSLinJiawei    MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask),
658*a4e57ea3SLi Qianruo    MaskedRegMap(Stvec, stvec, stvecMask, MaskedRegMap.NoSideEffect, stvecMask),
659c84054caSLinJiawei    MaskedRegMap(Scounteren, scounteren),
660c84054caSLinJiawei
66121fa8708Swangkaifan    //--- Supervisor Trap Handling ---
662c84054caSLinJiawei    MaskedRegMap(Sscratch, sscratch),
663e30fd06aSYinan Xu    MaskedRegMap(Sepc, sepc, sepcMask, MaskedRegMap.NoSideEffect, sepcMask),
664c84054caSLinJiawei    MaskedRegMap(Scause, scause),
665c84054caSLinJiawei    MaskedRegMap(Stval, stval),
666ab2d1905SWilliam Wang    MaskedRegMap(Sip, mip.asUInt, sipWMask, MaskedRegMap.Unwritable, sipMask),
667c84054caSLinJiawei
66821fa8708Swangkaifan    //--- Supervisor Protection and Translation ---
669c5334b11SZhangZifei    MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask),
670c84054caSLinJiawei
67135a47a38SYinan Xu    //--- Supervisor Custom Read/Write Registers
672eedc2e58SSteve Gou    MaskedRegMap(Sbpctl, sbpctl),
67335a47a38SYinan Xu    MaskedRegMap(Spfctl, spfctl),
67435a47a38SYinan Xu    MaskedRegMap(Sdsid, sdsid),
6752b8b2e7aSWilliam Wang    MaskedRegMap(Slvpredctl, slvpredctl),
676f3f22d72SYinan Xu    MaskedRegMap(Smblockctl, smblockctl),
677aac4464eSYinan Xu    MaskedRegMap(Srnctl, srnctl),
67835a47a38SYinan Xu
67921fa8708Swangkaifan    //--- Machine Information Registers ---
6805dabf2dfSYinan Xu    MaskedRegMap(Mvendorid, mvendorid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
6815dabf2dfSYinan Xu    MaskedRegMap(Marchid, marchid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
6825dabf2dfSYinan Xu    MaskedRegMap(Mimpid, mimpid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
6835dabf2dfSYinan Xu    MaskedRegMap(Mhartid, mhartid, 0.U(XLEN.W), MaskedRegMap.Unwritable),
6847d9edc86SLemover    MaskedRegMap(Mconfigptr, mconfigptr, 0.U(XLEN.W), MaskedRegMap.Unwritable),
685c84054caSLinJiawei
68621fa8708Swangkaifan    //--- Machine Trap Setup ---
687e30fd06aSYinan Xu    MaskedRegMap(Mstatus, mstatus, mstatusWMask, mstatusUpdateSideEffect, mstatusMask),
688c84054caSLinJiawei    MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable
6895dabf2dfSYinan Xu    MaskedRegMap(Medeleg, medeleg, "hf3ff".U(XLEN.W)),
6905dabf2dfSYinan Xu    MaskedRegMap(Mideleg, mideleg, "h222".U(XLEN.W)),
691c84054caSLinJiawei    MaskedRegMap(Mie, mie),
692*a4e57ea3SLi Qianruo    MaskedRegMap(Mtvec, mtvec, mtvecMask, MaskedRegMap.NoSideEffect, mtvecMask),
693c84054caSLinJiawei    MaskedRegMap(Mcounteren, mcounteren),
694c84054caSLinJiawei
69521fa8708Swangkaifan    //--- Machine Trap Handling ---
696c84054caSLinJiawei    MaskedRegMap(Mscratch, mscratch),
697e30fd06aSYinan Xu    MaskedRegMap(Mepc, mepc, mepcMask, MaskedRegMap.NoSideEffect, mepcMask),
698c84054caSLinJiawei    MaskedRegMap(Mcause, mcause),
699c84054caSLinJiawei    MaskedRegMap(Mtval, mtval),
7005dabf2dfSYinan Xu    MaskedRegMap(Mip, mip.asUInt, 0.U(XLEN.W), MaskedRegMap.Unwritable),
701d4aca96cSlqre
70272951335SLi Qianruo    //--- Trigger ---
703716f717fSLi Qianruo    MaskedRegMap(Tselect, tselectPhy, WritableMask, WriteTselect),
704ddb65c47SLi Qianruo    MaskedRegMap(Tdata1, tDummy1, WritableMask, WriteTdata1, WritableMask, ReadTdata1),
705ddb65c47SLi Qianruo    MaskedRegMap(Tdata2, tDummy2, WritableMask, WriteTdata2, WritableMask, ReadTdata2),
706716f717fSLi Qianruo    MaskedRegMap(Tinfo, tinfo, 0.U(XLEN.W), MaskedRegMap.Unwritable),
70772951335SLi Qianruo    MaskedRegMap(Tcontrol, tControlPhy, tcontrolWriteMask),
70872951335SLi Qianruo
709d4aca96cSlqre    //--- Debug Mode ---
710d4aca96cSlqre    MaskedRegMap(Dcsr, dcsr, dcsrMask, dcsrUpdateSideEffect),
711d4aca96cSlqre    MaskedRegMap(Dpc, dpc),
712d4aca96cSlqre    MaskedRegMap(Dscratch, dscratch),
71312c44ce5Srvcoresjw    MaskedRegMap(Dscratch1, dscratch1),
714b03ddc86Swangkaifan    MaskedRegMap(Mcountinhibit, mcountinhibit),
715b03ddc86Swangkaifan    MaskedRegMap(Mcycle, mcycle),
716b03ddc86Swangkaifan    MaskedRegMap(Minstret, minstret),
717b03ddc86Swangkaifan  )
71812c44ce5Srvcoresjw
71912c44ce5Srvcoresjw  val perfCntMapping = (0 until 29).map(i => {Map(
72012c44ce5Srvcoresjw    MaskedRegMap(addr = Mhpmevent3 +i,
72112c44ce5Srvcoresjw                 reg  = perfEvents(i),
72212c44ce5Srvcoresjw                 wmask = "hf87fff3fcff3fcff".U(XLEN.W)),
72312c44ce5Srvcoresjw    MaskedRegMap(addr = Mhpmcounter3 +i,
72412c44ce5Srvcoresjw                 reg  = perfCnts(i))
72512c44ce5Srvcoresjw  )}).fold(Map())((a,b) => a ++ b)
7266d96ebcdSwakafa  // TODO: mechanism should be implemented later
7276d96ebcdSwakafa  // val MhpmcounterStart = Mhpmcounter3
7286d96ebcdSwakafa  // val MhpmeventStart   = Mhpmevent3
7296d96ebcdSwakafa  // for (i <- 0 until nrPerfCnts) {
7306d96ebcdSwakafa  //   perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i))
7316d96ebcdSwakafa  //   perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i))
7326d96ebcdSwakafa  // }
7338635f18fSwangkaifan
734e19f7967SWilliam Wang  val cacheopRegs = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
735e19f7967SWilliam Wang    name -> RegInit(0.U(attribute("width").toInt.W))
736e19f7967SWilliam Wang  }}
737ad3ba452Szhanglinjuan  val cacheopMapping = CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
738ad3ba452Szhanglinjuan    MaskedRegMap(
739ad3ba452Szhanglinjuan      Scachebase + attribute("offset").toInt,
740e19f7967SWilliam Wang      cacheopRegs(name)
741ad3ba452Szhanglinjuan    )
742ad3ba452Szhanglinjuan  }}
743b6982e83SLemover
74421fa8708Swangkaifan  val mapping = basicPrivMapping ++
7458635f18fSwangkaifan                perfCntMapping ++
74621fa8708Swangkaifan                pmpMapping ++
747ca2f90a6SLemover                pmaMapping ++
748ad3ba452Szhanglinjuan                (if (HasFPU) fcsrMapping else Nil) ++
749ad3ba452Szhanglinjuan                (if (HasCustomCSRCacheOp) cacheopMapping else Nil)
750c84054caSLinJiawei
751c84054caSLinJiawei  val addr = src2(11, 0)
752b1860798SZhangfw  val csri = ZeroExt(src2(16, 12), XLEN)
753c84054caSLinJiawei  val rdata = Wire(UInt(XLEN.W))
754c84054caSLinJiawei  val wdata = LookupTree(func, List(
755c84054caSLinJiawei    CSROpType.wrt  -> src1,
756c84054caSLinJiawei    CSROpType.set  -> (rdata | src1),
757c84054caSLinJiawei    CSROpType.clr  -> (rdata & (~src1).asUInt()),
758b0ae3ac4SLinJiawei    CSROpType.wrti -> csri,
759c84054caSLinJiawei    CSROpType.seti -> (rdata | csri),
760c84054caSLinJiawei    CSROpType.clri -> (rdata & (~csri).asUInt())
761c84054caSLinJiawei  ))
762c84054caSLinJiawei
763e377d77eSWilliam Wang  val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) ||
764e377d77eSWilliam Wang    (addr >= Mcountinhibit.U) && (addr <= Mhpmevent31.U)
765e377d77eSWilliam Wang  csrio.isPerfCnt := addrInPerfCnt && valid && func =/= CSROpType.jmp
7668635f18fSwangkaifan
76747a386bfSZhangZifei  // satp wen check
76847a386bfSZhangZifei  val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U)
7692f5f05fdSWilliam Wang
770e5adbe81SLemover  // csr access check, special case
771e5adbe81SLemover  val tvmNotPermit = (priviledgeMode === ModeS && mstatusStruct.tvm.asBool)
772e5adbe81SLemover  val accessPermitted = !(addr === Satp.U && tvmNotPermit)
773e5adbe81SLemover  csrio.disableSfence := tvmNotPermit
774e5adbe81SLemover
7752f5f05fdSWilliam Wang  // general CSR wen check
7762f5f05fdSWilliam Wang  val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode)
77772951335SLi Qianruo  val dcsrPermitted = dcsrPermissionCheck(addr, false.B, debugMode)
77872951335SLi Qianruo  val triggerPermitted = triggerPermissionCheck(addr, true.B, debugMode) // todo dmode
77972951335SLi Qianruo  val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) && dcsrPermitted && triggerPermitted
78087acdd8eSwangkaifan  val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren)
781e5adbe81SLemover  val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) && accessPermitted
782e5adbe81SLemover
7838e7b11e5SWilliam Wang  MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata)
784ead41f51SLinJiawei  io.out.bits.data := rdata
785ead41f51SLinJiawei  io.out.bits.uop := io.in.bits.uop
786e18c367fSLinJiawei  io.out.bits.uop.cf := cfOut
787e18c367fSLinJiawei  io.out.bits.uop.ctrl.flushPipe := flushPipe
788c84054caSLinJiawei
789b6982e83SLemover  // send distribute csr a w signal
790b6982e83SLemover  csrio.customCtrl.distribute_csr.w.valid := wen && permitted
791b6982e83SLemover  csrio.customCtrl.distribute_csr.w.bits.data := wdata
792b6982e83SLemover  csrio.customCtrl.distribute_csr.w.bits.addr := addr
793b6982e83SLemover
794c84054caSLinJiawei  // Fix Mip/Sip write
795c84054caSLinJiawei  val fixMapping = Map(
796c84054caSLinJiawei    MaskedRegMap(Mip, mipReg.asUInt, mipFixMask),
797ab2d1905SWilliam Wang    MaskedRegMap(Sip, mipReg.asUInt, sipWMask, MaskedRegMap.NoSideEffect, sipMask)
798c84054caSLinJiawei  )
799ab2d1905SWilliam Wang  val rdataFix = Wire(UInt(XLEN.W))
800ab2d1905SWilliam Wang  val wdataFix = LookupTree(func, List(
801ab2d1905SWilliam Wang    CSROpType.wrt  -> src1,
802ab2d1905SWilliam Wang    CSROpType.set  -> (rdataFix | src1),
803ab2d1905SWilliam Wang    CSROpType.clr  -> (rdataFix & (~src1).asUInt()),
804ab2d1905SWilliam Wang    CSROpType.wrti -> csri,
805ab2d1905SWilliam Wang    CSROpType.seti -> (rdataFix | csri),
806ab2d1905SWilliam Wang    CSROpType.clri -> (rdataFix & (~csri).asUInt())
807ab2d1905SWilliam Wang  ))
808ab2d1905SWilliam Wang  MaskedRegMap.generate(fixMapping, addr, rdataFix, wen && permitted, wdataFix)
809c84054caSLinJiawei
810*a4e57ea3SLi Qianruo  when (RegNext(csrio.fpu.fflags.valid)) {
811*a4e57ea3SLi Qianruo    fcsr := fflags_wfn(update = true)(RegNext(csrio.fpu.fflags.bits))
812c84054caSLinJiawei  }
813c84054caSLinJiawei  // set fs and sd in mstatus
814*a4e57ea3SLi Qianruo  when (csrw_dirty_fp_state || RegNext(csrio.fpu.dirty_fs)) {
815c84054caSLinJiawei    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
816c84054caSLinJiawei    mstatusNew.fs := "b11".U
817c84054caSLinJiawei    mstatusNew.sd := true.B
818c84054caSLinJiawei    mstatus := mstatusNew.asUInt()
819c84054caSLinJiawei  }
820129a273eSYinan Xu  csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm
821c84054caSLinJiawei
82272951335SLi Qianruo
82372951335SLi Qianruo  // Trigger Ctrl
824716f717fSLi Qianruo  csrio.customCtrl.trigger_enable := tdata1Phy.map{t =>
825716f717fSLi Qianruo    def tdata1 = t.asTypeOf(new TdataBundle)
826716f717fSLi Qianruo    tdata1.m && priviledgeMode === ModeM ||
82772951335SLi Qianruo    tdata1.s && priviledgeMode === ModeS || tdata1.u && priviledgeMode === ModeU
82872951335SLi Qianruo  }
829ddb65c47SLi Qianruo  csrio.customCtrl.frontend_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) === I_Trigger)
830ddb65c47SLi Qianruo  csrio.customCtrl.mem_trigger.t.valid := RegNext(wen && (addr === Tdata1.U || addr === Tdata2.U) && TypeLookup(tselectPhy) =/= I_Trigger)
831068bf978SLi Qianruo  XSDebug(csrio.customCtrl.trigger_enable.asUInt.orR(), p"Debug Mode: At least 1 trigger is enabled, trigger enable is ${Binary(csrio.customCtrl.trigger_enable.asUInt())}\n")
83272951335SLi Qianruo
833c84054caSLinJiawei  // CSR inst decode
8348e7b11e5SWilliam Wang  val isEbreak = addr === privEbreak && func === CSROpType.jmp
835c84054caSLinJiawei  val isEcall  = addr === privEcall  && func === CSROpType.jmp
836c84054caSLinJiawei  val isMret   = addr === privMret   && func === CSROpType.jmp
837c84054caSLinJiawei  val isSret   = addr === privSret   && func === CSROpType.jmp
838c84054caSLinJiawei  val isUret   = addr === privUret   && func === CSROpType.jmp
839d4aca96cSlqre  val isDret   = addr === privDret   && func === CSROpType.jmp
840c84054caSLinJiawei
841e18c367fSLinJiawei  XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func)
842e18c367fSLinJiawei  XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode)
843bf9968b2SYinan Xu
8448e7b11e5SWilliam Wang  // Illegal priviledged operation list
8458e7b11e5SWilliam Wang  val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool
846c84054caSLinJiawei
8478e7b11e5SWilliam Wang  // Illegal priviledged instruction check
8488e7b11e5SWilliam Wang  val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr)
8498e7b11e5SWilliam Wang  val isIllegalAccess = !permitted
8508e7b11e5SWilliam Wang  val isIllegalPrivOp = illegalSModeSret
851c84054caSLinJiawei
852ad3ba452Szhanglinjuan  // expose several csr bits for tlb
853fcff7e94SZhangZifei  tlbBundle.priv.mxr   := mstatusStruct.mxr.asBool
854fcff7e94SZhangZifei  tlbBundle.priv.sum   := mstatusStruct.sum.asBool
855fcff7e94SZhangZifei  tlbBundle.priv.imode := priviledgeMode
856fcff7e94SZhangZifei  tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode)
857c84054caSLinJiawei
858e9341afdSYinan Xu  // Branch control
859c84054caSLinJiawei  val retTarget = Wire(UInt(VAddrBits.W))
8608e7b11e5SWilliam Wang  val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed
861bc63e578SLi Qianruo  flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall && !isEbreak)
862c84054caSLinJiawei
863c84054caSLinJiawei  retTarget := DontCare
864c84054caSLinJiawei  // val illegalEret = TODO
865c84054caSLinJiawei
866d4aca96cSlqre  when (valid && isDret) {
867d4aca96cSlqre    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
868d4aca96cSlqre    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
869d4aca96cSlqre    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
870d4aca96cSlqre    val debugModeNew = WireInit(debugMode)
871d4aca96cSlqre    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.
872d4aca96cSlqre    mstatus := mstatusNew.asUInt
873d4aca96cSlqre    priviledgeMode := dcsrNew.prv
874d4aca96cSlqre    retTarget := dpc(VAddrBits-1, 0)
875d4aca96cSlqre    debugModeNew := false.B
876d4aca96cSlqre    debugIntrEnable := true.B
877d4aca96cSlqre    debugMode := debugModeNew
878d4aca96cSlqre    XSDebug("Debug Mode: Dret executed, returning to %x.", retTarget)
879d4aca96cSlqre  }
880d4aca96cSlqre
881c84054caSLinJiawei  when (valid && isMret) {
882c84054caSLinJiawei    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
883c84054caSLinJiawei    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
884c84054caSLinJiawei    mstatusNew.ie.m := mstatusOld.pie.m
885c84054caSLinJiawei    priviledgeMode := mstatusOld.mpp
886c84054caSLinJiawei    mstatusNew.pie.m := true.B
887c84054caSLinJiawei    mstatusNew.mpp := ModeU
888c266a93bSLemover    when (mstatusOld.mpp =/= ModeM) { mstatusNew.mprv := 0.U }
889c84054caSLinJiawei    mstatus := mstatusNew.asUInt
890c84054caSLinJiawei    // lr := false.B
891c84054caSLinJiawei    retTarget := mepc(VAddrBits-1, 0)
892c84054caSLinJiawei  }
893c84054caSLinJiawei
8948e7b11e5SWilliam Wang  when (valid && isSret && !illegalSModeSret) {
895c84054caSLinJiawei    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
896c84054caSLinJiawei    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
897c84054caSLinJiawei    mstatusNew.ie.s := mstatusOld.pie.s
898c84054caSLinJiawei    priviledgeMode := Cat(0.U(1.W), mstatusOld.spp)
899c84054caSLinJiawei    mstatusNew.pie.s := true.B
900c84054caSLinJiawei    mstatusNew.spp := ModeU
901c84054caSLinJiawei    mstatus := mstatusNew.asUInt
9027d9edc86SLemover    when (mstatusOld.spp =/= ModeM) { mstatusNew.mprv := 0.U }
903c84054caSLinJiawei    // lr := false.B
904c84054caSLinJiawei    retTarget := sepc(VAddrBits-1, 0)
905c84054caSLinJiawei  }
906c84054caSLinJiawei
907c84054caSLinJiawei  when (valid && isUret) {
908c84054caSLinJiawei    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
909c84054caSLinJiawei    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
910c84054caSLinJiawei    // mstatusNew.mpp.m := ModeU //TODO: add mode U
911c84054caSLinJiawei    mstatusNew.ie.u := mstatusOld.pie.u
912c84054caSLinJiawei    priviledgeMode := ModeU
913c84054caSLinJiawei    mstatusNew.pie.u := true.B
914c84054caSLinJiawei    mstatus := mstatusNew.asUInt
915c84054caSLinJiawei    retTarget := uepc(VAddrBits-1, 0)
916c84054caSLinJiawei  }
917c84054caSLinJiawei
918e9341afdSYinan Xu  io.in.ready := true.B
919e9341afdSYinan Xu  io.out.valid := valid
920e9341afdSYinan Xu
921d4aca96cSlqre  val ebreakCauseException = (priviledgeMode === ModeM && dcsrData.ebreakm) || (priviledgeMode === ModeS && dcsrData.ebreaks) || (priviledgeMode === ModeU && dcsrData.ebreaku)
922d4aca96cSlqre
923baf8def6SYinan Xu  val csrExceptionVec = WireInit(cfIn.exceptionVec)
924d4aca96cSlqre  csrExceptionVec(breakPoint) := io.in.valid && isEbreak && ebreakCauseException
925baf8def6SYinan Xu  csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
926baf8def6SYinan Xu  csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
927baf8def6SYinan Xu  csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
928baf8def6SYinan Xu  // Trigger an illegal instr exception when:
929baf8def6SYinan Xu  // * unimplemented csr is being read/written
930baf8def6SYinan Xu  // * csr access is illegal
931baf8def6SYinan Xu  csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
932baf8def6SYinan Xu  cfOut.exceptionVec := csrExceptionVec
933baf8def6SYinan Xu
93484e47f35SLi Qianruo  XSDebug(io.in.valid && isEbreak, s"Debug Mode: an Ebreak is executed, ebreak cause exception ? ${ebreakCauseException}\n")
93584e47f35SLi Qianruo
936e9341afdSYinan Xu  /**
937e9341afdSYinan Xu    * Exception and Intr
938e9341afdSYinan Xu    */
939e9341afdSYinan Xu  val ideleg =  (mideleg & mip.asUInt)
940e9341afdSYinan Xu  def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS),
941e9341afdSYinan Xu    ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM))
942e9341afdSYinan Xu
943d4aca96cSlqre  val debugIntr = csrio.externalInterrupt.debug & debugIntrEnable
944d4aca96cSlqre  XSDebug(debugIntr, "Debug Mode: debug interrupt is asserted and valid!")
9459aca92b9SYinan Xu  // send interrupt information to ROB
946e9341afdSYinan Xu  val intrVecEnable = Wire(Vec(12, Bool()))
947e9341afdSYinan Xu  intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)}
948d4aca96cSlqre  val intrVec = Cat(debugIntr, (mie(11,0) & mip.asUInt & intrVecEnable.asUInt))
949e9341afdSYinan Xu  val intrBitSet = intrVec.orR()
950e9341afdSYinan Xu  csrio.interrupt := intrBitSet
951e9341afdSYinan Xu  mipWire.t.m := csrio.externalInterrupt.mtip
952e9341afdSYinan Xu  mipWire.s.m := csrio.externalInterrupt.msip
953e9341afdSYinan Xu  mipWire.e.m := csrio.externalInterrupt.meip
954b3d79b37SYinan Xu  mipWire.e.s := csrio.externalInterrupt.seip
955e9341afdSYinan Xu
956e9341afdSYinan Xu  // interrupts
957e9341afdSYinan Xu  val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
9582d7c7105SYinan Xu  val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt
959*a4e57ea3SLi Qianruo  val ivmEnable = tlbBundle.priv.imode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U
960*a4e57ea3SLi Qianruo  val iexceptionPC = Mux(ivmEnable, SignExt(csrio.exception.bits.uop.cf.pc, XLEN), csrio.exception.bits.uop.cf.pc)
961*a4e57ea3SLi Qianruo  val dvmEnable = tlbBundle.priv.dmode < ModeM && satp.asTypeOf(new SatpStruct).mode === 8.U
962*a4e57ea3SLi Qianruo  val dexceptionPC = Mux(dvmEnable, SignExt(csrio.exception.bits.uop.cf.pc, XLEN), csrio.exception.bits.uop.cf.pc)
963*a4e57ea3SLi Qianruo  XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", dexceptionPC, intrNO)
964d4aca96cSlqre  val raiseDebugIntr = intrNO === IRQ_DEBUG.U && raiseIntr
965e9341afdSYinan Xu
966e9341afdSYinan Xu  // exceptions
9672d7c7105SYinan Xu  val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt
9682d7c7105SYinan Xu  val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException
9692d7c7105SYinan Xu  val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException
9702d7c7105SYinan Xu  val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException
9712d7c7105SYinan Xu  val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException
9722d7c7105SYinan Xu  val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException
9732d7c7105SYinan Xu  val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException
9742d7c7105SYinan Xu  val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException
9752d7c7105SYinan Xu  val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException
976d4aca96cSlqre  val hasbreakPoint = csrio.exception.bits.uop.cf.exceptionVec(breakPoint) && raiseException
97772951335SLi Qianruo  val hasSingleStep = csrio.exception.bits.uop.ctrl.singleStep && raiseException
978ddb65c47SLi Qianruo  val hasTriggerHit = (csrio.exception.bits.uop.cf.trigger.hit) && raiseException
97984e47f35SLi Qianruo
98084e47f35SLi Qianruo  XSDebug(hasSingleStep, "Debug Mode: single step exception\n")
981ddb65c47SLi Qianruo  XSDebug(hasTriggerHit, p"Debug Mode: trigger hit, is frontend? ${Binary(csrio.exception.bits.uop.cf.trigger.frontendHit.asUInt)} " +
982068bf978SLi Qianruo    p"backend hit vec ${Binary(csrio.exception.bits.uop.cf.trigger.backendHit.asUInt)}\n")
983e9341afdSYinan Xu
9842d7c7105SYinan Xu  val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec
9856ab6918fSYinan Xu  val regularExceptionNO = ExceptionNO.priorities.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
98672951335SLi Qianruo  val exceptionNO = Mux(hasSingleStep || hasTriggerHit, 3.U, regularExceptionNO)
987e9341afdSYinan Xu  val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
988e9341afdSYinan Xu
989e9341afdSYinan Xu  val raiseExceptionIntr = csrio.exception.valid
990d4aca96cSlqre
99184e47f35SLi Qianruo  val raiseDebugExceptionIntr = !debugMode && (hasbreakPoint || raiseDebugIntr || hasSingleStep || hasTriggerHit && triggerAction) // TODO
9921097f021SLi Qianruo  val ebreakEnterParkLoop = debugMode && raiseExceptionIntr
993d4aca96cSlqre
994e9341afdSYinan Xu  XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",
995*a4e57ea3SLi Qianruo    dexceptionPC, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt
996e9341afdSYinan Xu  )
997e9341afdSYinan Xu  XSDebug(raiseExceptionIntr,
998e9341afdSYinan Xu    "pc %x mstatus %x mideleg %x medeleg %x mode %x\n",
999*a4e57ea3SLi Qianruo    dexceptionPC,
1000e9341afdSYinan Xu    mstatus,
1001e9341afdSYinan Xu    mideleg,
1002e9341afdSYinan Xu    medeleg,
1003e9341afdSYinan Xu    priviledgeMode
1004e9341afdSYinan Xu  )
1005e9341afdSYinan Xu
1006e9341afdSYinan Xu  // mtval write logic
10078a33de1fSYinan Xu  // Due to timing reasons of memExceptionVAddr, we delay the write of mtval and stval
1008e9341afdSYinan Xu  val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN)
1009*a4e57ea3SLi Qianruo  val updateTval = VecInit(Seq(
1010*a4e57ea3SLi Qianruo    hasInstrPageFault,
1011*a4e57ea3SLi Qianruo    hasLoadPageFault,
1012*a4e57ea3SLi Qianruo    hasStorePageFault,
1013*a4e57ea3SLi Qianruo    hasInstrAccessFault,
1014*a4e57ea3SLi Qianruo    hasLoadAccessFault,
1015*a4e57ea3SLi Qianruo    hasStoreAccessFault,
1016*a4e57ea3SLi Qianruo    hasLoadAddrMisaligned,
1017*a4e57ea3SLi Qianruo    hasStoreAddrMisaligned
1018*a4e57ea3SLi Qianruo  )).asUInt.orR
1019*a4e57ea3SLi Qianruo  when (RegNext(RegNext(updateTval))) {
10208a33de1fSYinan Xu      val tval = RegNext(Mux(
1021*a4e57ea3SLi Qianruo      RegNext(hasInstrPageFault || hasInstrAccessFault),
10228a33de1fSYinan Xu      RegNext(Mux(
10232d7c7105SYinan Xu        csrio.exception.bits.uop.cf.crossPageIPFFix,
10242d7c7105SYinan Xu        SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN),
1025*a4e57ea3SLi Qianruo        iexceptionPC
10268a33de1fSYinan Xu      )),
1027e9341afdSYinan Xu      memExceptionAddr
10288a33de1fSYinan Xu    ))
1029*a4e57ea3SLi Qianruo    when (RegNext(priviledgeMode === ModeM)) {
1030e9341afdSYinan Xu      mtval := tval
1031e9341afdSYinan Xu    }.otherwise {
1032e9341afdSYinan Xu      stval := tval
1033e9341afdSYinan Xu    }
1034e9341afdSYinan Xu  }
1035e9341afdSYinan Xu
1036d4aca96cSlqre  val debugTrapTarget = Mux(!isEbreak && debugMode, 0x38020808.U, 0x38020800.U) // 0x808 is when an exception occurs in debug mode prog buf exec
1037e9341afdSYinan Xu  val deleg = Mux(raiseIntr, mideleg , medeleg)
1038e9341afdSYinan Xu  // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM);
1039ac5a5d53SLinJiawei  val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM)
1040*a4e57ea3SLi Qianruo  val clearTval = !updateTval || raiseIntr
1041d4aca96cSlqre  val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall && !isEbreak
104213096f7eSYinan Xu
104313096f7eSYinan Xu  // ctrl block will use theses later for flush
104413096f7eSYinan Xu  val isXRetFlag = RegInit(false.B)
1045*a4e57ea3SLi Qianruo  when (DelayN(io.redirectIn.valid, 5)) {
104613096f7eSYinan Xu    isXRetFlag := false.B
104713096f7eSYinan Xu  }.elsewhen (isXRet) {
104813096f7eSYinan Xu    isXRetFlag := true.B
104913096f7eSYinan Xu  }
105013096f7eSYinan Xu  csrio.isXRet := isXRetFlag
1051*a4e57ea3SLi Qianruo  val retTargetReg = RegEnable(retTarget, isXRet)
1052*a4e57ea3SLi Qianruo
1053*a4e57ea3SLi Qianruo  val tvec = Mux(delegS, stvec, mtvec)
1054*a4e57ea3SLi Qianruo  val tvecBase = tvec(VAddrBits - 1, 2)
1055*a4e57ea3SLi Qianruo  // XRet sends redirect instead of Flush and isXRetFlag is true.B before redirect.valid.
1056*a4e57ea3SLi Qianruo  // ROB sends exception at T0 while CSR receives at T2.
1057*a4e57ea3SLi Qianruo  // We add a RegNext here and trapTarget is valid at T3.
1058*a4e57ea3SLi Qianruo  csrio.trapTarget := RegEnable(Mux(isXRetFlag,
105913096f7eSYinan Xu    retTargetReg,
1060d4aca96cSlqre    Mux(raiseDebugExceptionIntr || ebreakEnterParkLoop, debugTrapTarget,
1061*a4e57ea3SLi Qianruo      // When MODE=Vectored, all synchronous exceptions into M/S mode
1062*a4e57ea3SLi Qianruo      // cause the pc to be set to the address in the BASE field, whereas
1063*a4e57ea3SLi Qianruo      // interrupts cause the pc to be set to the address in the BASE field
1064*a4e57ea3SLi Qianruo      // plus four times the interrupt cause number.
1065*a4e57ea3SLi Qianruo      Cat(tvecBase + Mux(tvec(0) && raiseIntr, causeNO(3, 0), 0.U), 0.U(2.W))
1066*a4e57ea3SLi Qianruo  )), isXRetFlag || csrio.exception.valid)
1067e9341afdSYinan Xu
1068c84054caSLinJiawei  when (raiseExceptionIntr) {
1069c84054caSLinJiawei    val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct))
1070c84054caSLinJiawei    val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct))
1071d4aca96cSlqre    val dcsrNew = WireInit(dcsr.asTypeOf(new DcsrStruct))
1072d4aca96cSlqre    val debugModeNew = WireInit(debugMode)
1073c84054caSLinJiawei
1074d4aca96cSlqre    when (raiseDebugExceptionIntr) {
1075d4aca96cSlqre      when (raiseDebugIntr) {
1076d4aca96cSlqre        debugModeNew := true.B
1077d4aca96cSlqre        mstatusNew.mprv := false.B
1078*a4e57ea3SLi Qianruo        dpc := iexceptionPC
1079d4aca96cSlqre        dcsrNew.cause := 1.U
1080d4aca96cSlqre        dcsrNew.prv := priviledgeMode
1081d4aca96cSlqre        priviledgeMode := ModeM
1082d4aca96cSlqre        XSDebug(raiseDebugIntr, "Debug Mode: Trap to %x at pc %x\n", debugTrapTarget, dpc)
1083d4aca96cSlqre      }.elsewhen ((hasbreakPoint || hasSingleStep) && !debugMode) {
1084d4aca96cSlqre        // ebreak or ss in running hart
1085d4aca96cSlqre        debugModeNew := true.B
1086*a4e57ea3SLi Qianruo        dpc := iexceptionPC
1087d4aca96cSlqre        dcsrNew.cause := Mux(hasbreakPoint, 3.U, 0.U)
1088d4aca96cSlqre        dcsrNew.prv := priviledgeMode // TODO
1089d4aca96cSlqre        priviledgeMode := ModeM
1090d4aca96cSlqre        mstatusNew.mprv := false.B
1091d4aca96cSlqre      }
1092d4aca96cSlqre      dcsr := dcsrNew.asUInt
1093d4aca96cSlqre      debugIntrEnable := false.B
1094d4aca96cSlqre    }.elsewhen (delegS) {
1095c84054caSLinJiawei      scause := causeNO
1096*a4e57ea3SLi Qianruo      sepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC)
1097c84054caSLinJiawei      mstatusNew.spp := priviledgeMode
1098c84054caSLinJiawei      mstatusNew.pie.s := mstatusOld.ie.s
1099c84054caSLinJiawei      mstatusNew.ie.s := false.B
1100c84054caSLinJiawei      priviledgeMode := ModeS
1101*a4e57ea3SLi Qianruo      when (clearTval) { stval := 0.U }
1102c84054caSLinJiawei    }.otherwise {
1103c84054caSLinJiawei      mcause := causeNO
1104*a4e57ea3SLi Qianruo      mepc := Mux(hasInstrPageFault || hasInstrAccessFault, iexceptionPC, dexceptionPC)
1105c84054caSLinJiawei      mstatusNew.mpp := priviledgeMode
1106c84054caSLinJiawei      mstatusNew.pie.m := mstatusOld.ie.m
1107c84054caSLinJiawei      mstatusNew.ie.m := false.B
1108c84054caSLinJiawei      priviledgeMode := ModeM
1109*a4e57ea3SLi Qianruo      when (clearTval) { mtval := 0.U }
1110c84054caSLinJiawei    }
1111c84054caSLinJiawei    mstatus := mstatusNew.asUInt
1112d4aca96cSlqre    debugMode := debugModeNew
1113c84054caSLinJiawei  }
1114c84054caSLinJiawei
1115e18c367fSLinJiawei  XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc)
1116bf9968b2SYinan Xu
1117e19f7967SWilliam Wang  // Distributed CSR update req
1118e19f7967SWilliam Wang  //
1119e19f7967SWilliam Wang  // For now we use it to implement customized cache op
112070899835SWilliam Wang  // It can be delayed if necessary
1121e19f7967SWilliam Wang
112270899835SWilliam Wang  val delayedUpdate0 = DelayN(csrio.distributedUpdate(0), 2)
112370899835SWilliam Wang  val delayedUpdate1 = DelayN(csrio.distributedUpdate(1), 2)
112470899835SWilliam Wang  val distributedUpdateValid = delayedUpdate0.w.valid || delayedUpdate1.w.valid
112570899835SWilliam Wang  val distributedUpdateAddr = Mux(delayedUpdate0.w.valid,
112670899835SWilliam Wang    delayedUpdate0.w.bits.addr,
112770899835SWilliam Wang    delayedUpdate1.w.bits.addr
112870899835SWilliam Wang  )
112970899835SWilliam Wang  val distributedUpdateData = Mux(delayedUpdate0.w.valid,
113070899835SWilliam Wang    delayedUpdate0.w.bits.data,
113170899835SWilliam Wang    delayedUpdate1.w.bits.data
113270899835SWilliam Wang  )
113370899835SWilliam Wang
113470899835SWilliam Wang  assert(!(delayedUpdate0.w.valid && delayedUpdate1.w.valid))
113570899835SWilliam Wang
113670899835SWilliam Wang  when(distributedUpdateValid){
1137e19f7967SWilliam Wang    // cacheopRegs can be distributed updated
1138e19f7967SWilliam Wang    CacheInstrucion.CacheInsRegisterList.map{case (name, attribute) => {
113970899835SWilliam Wang      when((Scachebase + attribute("offset").toInt).U === distributedUpdateAddr){
114070899835SWilliam Wang        cacheopRegs(name) := distributedUpdateData
1141e19f7967SWilliam Wang      }
1142e19f7967SWilliam Wang    }}
1143e19f7967SWilliam Wang  }
1144e19f7967SWilliam Wang
1145e30fd06aSYinan Xu  // Implicit add reset values for mepc[0] and sepc[0]
1146e30fd06aSYinan Xu  // TODO: rewrite mepc and sepc using a struct-like style with the LSB always being 0
1147e30fd06aSYinan Xu  when (reset.asBool) {
1148e30fd06aSYinan Xu    mepc := Cat(mepc(XLEN - 1, 1), 0.U(1.W))
1149e30fd06aSYinan Xu    sepc := Cat(sepc(XLEN - 1, 1), 0.U(1.W))
1150e30fd06aSYinan Xu  }
1151e30fd06aSYinan Xu
1152c84054caSLinJiawei  def readWithScala(addr: Int): UInt = mapping(addr)._1
1153c84054caSLinJiawei
1154a165bd69Swangkaifan  val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
1155a165bd69Swangkaifan
1156cbe9a847SYinan Xu  // Always instantiate basic difftest modules.
1157cbe9a847SYinan Xu  if (env.AlwaysBasicDiff || env.EnableDifftest) {
11582225d46eSJiawei Lin    val difftest = Module(new DifftestArchEvent)
11592225d46eSJiawei Lin    difftest.io.clock := clock
11605668a921SJiawei Lin    difftest.io.coreid := csrio.hartId
11618a33de1fSYinan Xu    difftest.io.intrNO := RegNext(RegNext(RegNext(difftestIntrNO)))
11628a33de1fSYinan Xu    difftest.io.cause  := RegNext(RegNext(RegNext(Mux(csrio.exception.valid, causeNO, 0.U))))
1163*a4e57ea3SLi Qianruo    difftest.io.exceptionPC := RegNext(RegNext(RegNext(dexceptionPC)))
1164*a4e57ea3SLi Qianruo    if (env.EnableDifftest) {
1165*a4e57ea3SLi Qianruo      difftest.io.exceptionInst := RegNext(RegNext(RegNext(csrio.exception.bits.uop.cf.instr)))
1166*a4e57ea3SLi Qianruo    }
11672225d46eSJiawei Lin  }
11682225d46eSJiawei Lin
1169cbe9a847SYinan Xu  // Always instantiate basic difftest modules.
1170cbe9a847SYinan Xu  if (env.AlwaysBasicDiff || env.EnableDifftest) {
11712225d46eSJiawei Lin    val difftest = Module(new DifftestCSRState)
11722225d46eSJiawei Lin    difftest.io.clock := clock
11735668a921SJiawei Lin    difftest.io.coreid := csrio.hartId
11742225d46eSJiawei Lin    difftest.io.priviledgeMode := priviledgeMode
11752225d46eSJiawei Lin    difftest.io.mstatus := mstatus
11762225d46eSJiawei Lin    difftest.io.sstatus := mstatus & sstatusRmask
11772225d46eSJiawei Lin    difftest.io.mepc := mepc
11782225d46eSJiawei Lin    difftest.io.sepc := sepc
11792225d46eSJiawei Lin    difftest.io.mtval:= mtval
11802225d46eSJiawei Lin    difftest.io.stval:= stval
11812225d46eSJiawei Lin    difftest.io.mtvec := mtvec
11822225d46eSJiawei Lin    difftest.io.stvec := stvec
11832225d46eSJiawei Lin    difftest.io.mcause := mcause
11842225d46eSJiawei Lin    difftest.io.scause := scause
11852225d46eSJiawei Lin    difftest.io.satp := satp
11862225d46eSJiawei Lin    difftest.io.mip := mipReg
11872225d46eSJiawei Lin    difftest.io.mie := mie
11882225d46eSJiawei Lin    difftest.io.mscratch := mscratch
11892225d46eSJiawei Lin    difftest.io.sscratch := sscratch
11902225d46eSJiawei Lin    difftest.io.mideleg := mideleg
11912225d46eSJiawei Lin    difftest.io.medeleg := medeleg
1192a165bd69Swangkaifan  }
1193*a4e57ea3SLi Qianruo
1194*a4e57ea3SLi Qianruo  if(env.AlwaysBasicDiff || env.EnableDifftest) {
1195*a4e57ea3SLi Qianruo    val difftest = Module(new DifftestDebugMode)
1196*a4e57ea3SLi Qianruo    difftest.io.clock := clock
1197*a4e57ea3SLi Qianruo    difftest.io.coreid := csrio.hartId
1198*a4e57ea3SLi Qianruo    difftest.io.debugMode := debugMode
1199*a4e57ea3SLi Qianruo    difftest.io.dcsr := dcsr
1200*a4e57ea3SLi Qianruo    difftest.io.dpc := dpc
1201*a4e57ea3SLi Qianruo    difftest.io.dscratch0 := dscratch
1202*a4e57ea3SLi Qianruo    difftest.io.dscratch1 := dscratch1
1203*a4e57ea3SLi Qianruo  }
1204c84054caSLinJiawei}
12051545277aSYinan Xu
1206cd365d4cSrvcoresjwclass PFEvent(implicit p: Parameters) extends XSModule with HasCSRConst  {
1207cd365d4cSrvcoresjw  val io = IO(new Bundle {
1208cd365d4cSrvcoresjw    val distribute_csr = Flipped(new DistributedCSRIO())
1209cd365d4cSrvcoresjw    val hpmevent = Output(Vec(29, UInt(XLEN.W)))
1210cd365d4cSrvcoresjw  })
1211cd365d4cSrvcoresjw
1212cd365d4cSrvcoresjw  val w = io.distribute_csr.w
1213cd365d4cSrvcoresjw
12145fd90906Srvcoresjw  val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++
12155fd90906Srvcoresjw                   List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++
12165fd90906Srvcoresjw                   List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++
12175fd90906Srvcoresjw                   List.fill(5)(RegInit("hc0300c0300".U(XLEN.W)))
1218cd365d4cSrvcoresjw
121912c44ce5Srvcoresjw  val perfEventMapping = (0 until 29).map(i => {Map(
122012c44ce5Srvcoresjw    MaskedRegMap(addr = Mhpmevent3 +i,
122112c44ce5Srvcoresjw                 reg  = perfEvents(i),
122212c44ce5Srvcoresjw                 wmask = "hf87fff3fcff3fcff".U(XLEN.W))
122312c44ce5Srvcoresjw  )}).fold(Map())((a,b) => a ++ b)
1224cd365d4cSrvcoresjw
1225cd365d4cSrvcoresjw  val rdata = Wire(UInt(XLEN.W))
1226cd365d4cSrvcoresjw  MaskedRegMap.generate(perfEventMapping, w.bits.addr, rdata, w.valid, w.bits.data)
12275fd90906Srvcoresjw  for(i <- 0 until 29){
12285fd90906Srvcoresjw    io.hpmevent(i) := perfEvents(i)
12295fd90906Srvcoresjw  }
1230cd365d4cSrvcoresjw}
1231cd365d4cSrvcoresjw
1232