xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision 6683fc49ec7b83860c24b77ed5d96eb0bee19928)
1039cdc35SXuan Hupackage xiangshan.backend.fu.NewCSR
2039cdc35SXuan Hu
3039cdc35SXuan Huimport chisel3._
4039cdc35SXuan Huimport chisel3.util._
5881eb731SXuan Huimport difftest._
6d0b87b97SXuan Huimport freechips.rocketchip.rocket.CSRs
7237d4cfdSXuan Huimport org.chipsalliance.cde.config.Parameters
8039cdc35SXuan Huimport top.{ArgParser, Generator}
985a8d7caSZehao Liuimport utility._
1044f2941bSJiru Sunimport utils.OptionWrapper
118419d406SXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles.{CSRCustomState, PrivState, RobCommitCSR}
12e9f7c490SXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines._
1301cdded8SXuan Huimport xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
14eca6983fSZehao Liuimport xiangshan.backend.fu.NewCSR.CSREvents.{CSREvents, DretEventSinkBundle, EventUpdatePrivStateOutput, MNretEventSinkBundle, MretEventSinkBundle, SretEventSinkBundle, SretEventSDTSinkBundle,  TargetPCBundle, TrapEntryDEventSinkBundle, TrapEntryEventInput, TrapEntryHSEventSinkBundle, TrapEntryMEventSinkBundle, TrapEntryMNEventSinkBundle, TrapEntryVSEventSinkBundle}
1501cdded8SXuan Huimport xiangshan.backend.fu.fpu.Bundles.Frm
1602a84a36SXuan Huimport xiangshan.backend.fu.vector.Bundles.{Vl, Vstart, Vxrm, Vxsat}
1715ed99a7SXuan Huimport xiangshan.backend.fu.wrapper.CSRToDecode
18c1b28b66STang Haojinimport xiangshan.backend.rob.RobPtr
19a7a6d0a6Schengguanghuiimport xiangshan._
20b51a1abdSchengguanghuiimport xiangshan.backend.fu.PerfCounterIO
21011d262cSZhaoyang Youimport xiangshan.backend.fu.util.CSRConst
22fa16cf81Slewislzhimport xiangshan.ExceptionNO._
234907ec88Schengguanghuiimport xiangshan.backend.trace._
24039cdc35SXuan Hu
25760398d7SXuan Huimport scala.collection.immutable.SeqMap
26760398d7SXuan Hu
27039cdc35SXuan Huobject CSRConfig {
28039cdc35SXuan Hu  final val ASIDLEN = 16 // the length of ASID of XS implementation
29039cdc35SXuan Hu
30039cdc35SXuan Hu  final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec
31039cdc35SXuan Hu
32039cdc35SXuan Hu  final val HIIDWidth = 12 // support Hvictl[27:16](IID)
33039cdc35SXuan Hu
34039cdc35SXuan Hu  final val VMIDLEN = 14 // the length of VMID of XS implementation
35039cdc35SXuan Hu
36039cdc35SXuan Hu  final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec
37039cdc35SXuan Hu
383ea4388cSHaoyuan Feng  final val VaddrMaxWidth = 48 + 2 // support Sv39/Sv48/Sv39x4/Sv48x4
39039cdc35SXuan Hu
40fa16cf81Slewislzh  final val InstWidth = 32
41fa16cf81Slewislzh
42237d4cfdSXuan Hu  final val XLEN = 64 // Todo: use XSParams
4301cdded8SXuan Hu
4401cdded8SXuan Hu  final val VLEN = 128
4501cdded8SXuan Hu
4601cdded8SXuan Hu  // Since we need macro to compute the width of CSR field, the input of macro should be the value that can be computed
4701cdded8SXuan Hu  // at compile time. The log2Up function cannot be used as meta-programming function, so we use litral value here
4801cdded8SXuan Hu  // log2Up(128 + 1), hold 0~128
4901cdded8SXuan Hu  final val VlWidth = 8
509ff1c68fSsinceforYy
513ea4388cSHaoyuan Feng  final val PAddrWidth = 48
5247556e0cSXuan Hu
5347556e0cSXuan Hu  final val AddrWidthInPage = 12
5447556e0cSXuan Hu
553ea4388cSHaoyuan Feng  final val PMPAddrWidth = 48
569ff1c68fSsinceforYy
579ff1c68fSsinceforYy  final val PMPOffBits = 2
589ff1c68fSsinceforYy
599ff1c68fSsinceforYy  final val PMPAddrBits = PMPAddrWidth - PMPOffBits
60a7a6d0a6Schengguanghui
61b51a1abdSchengguanghui  // perf
62b51a1abdSchengguanghui  final val perfCntNum = 29       // in Spec
63b51a1abdSchengguanghui
640b4c00ffSXuan Hu  final val EXT_SSTC = true
659c0fd28fSXuan Hu
666808b803SZehao Liu  final val EXT_DBLTRP = true
676808b803SZehao Liu
689c0fd28fSXuan Hu  final val PPNLength = 44
696808b803SZehao Liu  // TODO: as current test not support clean mdt , we set mstatus->mdt = 0 to allow exception in m-mode
706808b803SZehao Liu  final val mdtInit = 0
716808b803SZehao Liu
72039cdc35SXuan Hu}
73039cdc35SXuan Hu
749d9b0bfaSjunxiong-jiclass NewCSRInput(implicit p: Parameters) extends Bundle {
759d9b0bfaSjunxiong-ji  val wen = Bool()
769d9b0bfaSjunxiong-ji  val ren = Bool()
779d9b0bfaSjunxiong-ji  val op = UInt(2.W)
789d9b0bfaSjunxiong-ji  val addr = UInt(12.W)
799d9b0bfaSjunxiong-ji  val src = UInt(64.W)
809d9b0bfaSjunxiong-ji  val wdata = UInt(64.W)
819d9b0bfaSjunxiong-ji  val mnret = Input(Bool())
829d9b0bfaSjunxiong-ji  val mret = Input(Bool())
839d9b0bfaSjunxiong-ji  val sret = Input(Bool())
849d9b0bfaSjunxiong-ji  val dret = Input(Bool())
85c559bb17SZhaoyang You  val redirectFlush = Input(Bool())
869d9b0bfaSjunxiong-ji}
879d9b0bfaSjunxiong-ji
889d9b0bfaSjunxiong-jiclass NewCSROutput(implicit p: Parameters) extends Bundle {
899d9b0bfaSjunxiong-ji  val EX_II = Bool()
909d9b0bfaSjunxiong-ji  val EX_VI = Bool()
919d9b0bfaSjunxiong-ji  val flushPipe = Bool()
929d9b0bfaSjunxiong-ji  val rData = UInt(64.W)
939d9b0bfaSjunxiong-ji  val targetPcUpdate = Bool()
949d9b0bfaSjunxiong-ji  val targetPc = new TargetPCBundle
959d9b0bfaSjunxiong-ji  val regOut = UInt(64.W)
969d9b0bfaSjunxiong-ji  // perf
979d9b0bfaSjunxiong-ji  val isPerfCnt = Bool()
989d9b0bfaSjunxiong-ji}
999d9b0bfaSjunxiong-ji
100237d4cfdSXuan Huclass NewCSR(implicit val p: Parameters) extends Module
101237d4cfdSXuan Hu  with HasXSParameter
102039cdc35SXuan Hu  with MachineLevel
103039cdc35SXuan Hu  with SupervisorLevel
104039cdc35SXuan Hu  with HypervisorLevel
105039cdc35SXuan Hu  with VirtualSupervisorLevel
106039cdc35SXuan Hu  with Unprivileged
1079681ffb2SXuan Hu  with CSRAIA
108039cdc35SXuan Hu  with HasExternalInterruptBundle
109c2a2229dSlewislzh  with HasNonMaskableIRPBundle
110237d4cfdSXuan Hu  with CSREvents
111223cba9dSXuan Hu  with DebugLevel
112036cdc74SsinceforYy  with CSRCustom
1139ff1c68fSsinceforYy  with CSRPMP
114011d262cSZhaoyang You  with CSRPMA
11585a8d7caSZehao Liu  with HasCriticalErrors
1161d192ad8SXuan Hu  with IpIeAliasConnect
117237d4cfdSXuan Hu{
118237d4cfdSXuan Hu
119237d4cfdSXuan Hu  import CSRConfig._
120039cdc35SXuan Hu
121039cdc35SXuan Hu  val io = IO(new Bundle {
122cb4fe84bSXuan Hu    val fromTop = Input(new Bundle {
123cb4fe84bSXuan Hu      val hartId = UInt(hartIdLen.W)
1243bf5eac7SXuan Hu      val clintTime = Input(ValidIO(UInt(64.W)))
125b7a63495SNewPaulWalker      val l2FlushDone = Input(Bool())
126a751b11aSchengguanghui      val criticalErrorState = Input(Bool())
127cb4fe84bSXuan Hu    })
1289d9b0bfaSjunxiong-ji    val in = Flipped(DecoupledIO(new NewCSRInput))
12992c61038SXuan Hu    val trapInst = Input(ValidIO(UInt(InstWidth.W)))
130237d4cfdSXuan Hu    val fromMem = Input(new Bundle {
131db6cfb5aSHaoyuan Feng      val excpVA  = UInt(XLEN.W)
132ad415ae0SXiaokun-Pei      val excpGPA = UInt(XLEN.W)
133ad415ae0SXiaokun-Pei      val excpIsForVSnonLeafPTE = Bool()
134237d4cfdSXuan Hu    })
135e877d8bfSXuan Hu    val fromRob = Input(new Bundle {
136e877d8bfSXuan Hu      val trap = ValidIO(new Bundle {
137e877d8bfSXuan Hu        val pc = UInt(VaddrMaxWidth.W)
138dd980d61SXu, Zefan        val pcGPA = UInt(PAddrBitsMax.W)
139fa16cf81Slewislzh        val instr = UInt(InstWidth.W)
140007f6122SXuan Hu        val trapVec = UInt(64.W)
141fe52823cSXuan Hu        val isFetchBkpt = Bool()
142e877d8bfSXuan Hu        val singleStep = Bool()
1437e0f64b0SGuanghui Cheng        val trigger = TriggerAction()
144e877d8bfSXuan Hu        val crossPageIPFFix = Bool()
145e877d8bfSXuan Hu        val isInterrupt = Bool()
146f60da58cSXuan Hu        val isHls = Bool()
147c1b28b66STang Haojin        val isFetchMalAddr = Bool()
148ad415ae0SXiaokun-Pei        val isForVSnonLeafPTE = Bool()
149e877d8bfSXuan Hu      })
15001cdded8SXuan Hu      val commit = Input(new RobCommitCSR)
151c1b28b66STang Haojin      val robDeqPtr = Input(new RobPtr)
152039cdc35SXuan Hu    })
153e877d8bfSXuan Hu
154e43bb916SXuan Hu    val fromVecExcpMod = Input(new Bundle {
155e43bb916SXuan Hu      val busy = Bool()
156e43bb916SXuan Hu    })
157e43bb916SXuan Hu
158b51a1abdSchengguanghui    val perf = Input(new PerfCounterIO)
159b51a1abdSchengguanghui
1609d9b0bfaSjunxiong-ji    /** Output should be a DecoupledIO, since now CSR writing to integer register file might be blocked (by arbiter) */
1619d9b0bfaSjunxiong-ji    val out = DecoupledIO(new NewCSROutput)
162f7c21cb5SXuan Hu    val status = Output(new Bundle {
163007f6122SXuan Hu      val privState = new PrivState
164007f6122SXuan Hu      val interrupt = Bool()
16576330f73SXuan Hu      val wfiEvent = Bool()
166e877d8bfSXuan Hu      // fp
16701cdded8SXuan Hu      val fpState = new Bundle {
16801cdded8SXuan Hu        val off = Bool()
169e877d8bfSXuan Hu        val frm = Frm()
17001cdded8SXuan Hu      }
171e877d8bfSXuan Hu      // vec
17201cdded8SXuan Hu      val vecState = new Bundle {
17302a84a36SXuan Hu        val vstart = Vstart()
174007f6122SXuan Hu        val vxsat = Vxsat()
175e877d8bfSXuan Hu        val vxrm = Vxrm()
176007f6122SXuan Hu        val vcsr = UInt(XLEN.W)
17701cdded8SXuan Hu        val vl = Vl()
178007f6122SXuan Hu        val vtype = UInt(XLEN.W)
179007f6122SXuan Hu        val vlenb = UInt(XLEN.W)
18001cdded8SXuan Hu        val off = Bool()
18101cdded8SXuan Hu      }
1821e7040baSsinceforYy      // debug
1831e7040baSsinceforYy      val debugMode = Bool()
18401cdded8SXuan Hu      val singleStepFlag = Bool()
185a7a6d0a6Schengguanghui      // trigger
186a7a6d0a6Schengguanghui      val frontendTrigger = new FrontendTdataDistributeIO()
187a7a6d0a6Schengguanghui      val memTrigger = new MemTdataDistributeIO()
188c1b28b66STang Haojin      // Instruction fetch address translation type
189c1b28b66STang Haojin      val instrAddrTransType = new AddrTransType
1904907ec88Schengguanghui      // trace
191c308d936Schengguanghui      val traceCSR = Output(new TraceCSR)
1928419d406SXuan Hu      // custom
1938419d406SXuan Hu      val custom = new CSRCustomState
194a751b11aSchengguanghui      val criticalErrorState = Bool()
195e877d8bfSXuan Hu    })
19694c2cc17SsinceforYy    // tlb
19794c2cc17SsinceforYy    val tlb = Output(new Bundle {
1989a4a4f17SXuan Hu      val satpASIDChanged = Bool()
199c577d933SXuan Hu      val vsatpASIDChanged = Bool()
200c577d933SXuan Hu      val hgatpVMIDChanged = Bool()
2019a4a4f17SXuan Hu      val satp = new SatpBundle
202c577d933SXuan Hu      val vsatp = new SatpBundle
203c577d933SXuan Hu      val hgatp = new HgatpBundle
2048882eb68SXin Tian      val mbmc = new MbmcBundle
20594c2cc17SsinceforYy      val mxr = Bool()
20694c2cc17SsinceforYy      val sum = Bool()
207c577d933SXuan Hu      val vmxr = Bool()
208c577d933SXuan Hu      val vsum = Bool()
209c577d933SXuan Hu      val spvp = Bool()
21094c2cc17SsinceforYy      val imode = UInt(2.W)
21194c2cc17SsinceforYy      val dmode = UInt(2.W)
212e92e298cSXuan Hu      val dvirt = Bool()
213dd286b6aSYanqin Li      val mPBMTE = Bool()
214dd286b6aSYanqin Li      val hPBMTE = Bool()
215189833a1SHaoyuan Feng      val pmm = new Bundle {
216189833a1SHaoyuan Feng        val mseccfg = UInt(2.W)
217189833a1SHaoyuan Feng        val menvcfg = UInt(2.W)
218189833a1SHaoyuan Feng        val henvcfg = UInt(2.W)
219189833a1SHaoyuan Feng        val hstatus = UInt(2.W)
220189833a1SHaoyuan Feng        val senvcfg = UInt(2.W)
221189833a1SHaoyuan Feng      }
22294c2cc17SsinceforYy    })
22315ed99a7SXuan Hu
22415ed99a7SXuan Hu    val toDecode = new CSRToDecode
225c1b28b66STang Haojin
226c1b28b66STang Haojin    val fetchMalTval = Input(UInt(XLEN.W))
227676ddb73SXuan Hu
228676ddb73SXuan Hu    val distributedWenLegal = Output(Bool())
229e877d8bfSXuan Hu  })
230039cdc35SXuan Hu
2319681ffb2SXuan Hu  val toAIA   = IO(Output(new CSRToAIABundle))
2329681ffb2SXuan Hu  val fromAIA = IO(Flipped(Output(new AIAToCSRBundle)))
2339681ffb2SXuan Hu
2349681ffb2SXuan Hu  dontTouch(toAIA)
2359681ffb2SXuan Hu  dontTouch(fromAIA)
2363bf5eac7SXuan Hu  dontTouch(io.fromTop.clintTime)
2379681ffb2SXuan Hu
2389d9b0bfaSjunxiong-ji  /* Alias of input valid/ready */
239f7c21cb5SXuan Hu  val valid = io.in.valid
240e877d8bfSXuan Hu
2419d9b0bfaSjunxiong-ji  /* Alias of input signals */
242f7c21cb5SXuan Hu  val wen   = io.in.bits.wen && valid
243f7c21cb5SXuan Hu  val addr  = io.in.bits.addr
24432fe4d47SsinceforYy  val wdata = io.in.bits.wdata
245f7c21cb5SXuan Hu
246f7c21cb5SXuan Hu  val ren   = io.in.bits.ren && valid
247f7c21cb5SXuan Hu  val raddr = io.in.bits.addr
248e877d8bfSXuan Hu
249c559bb17SZhaoyang You  // flush
250c559bb17SZhaoyang You  val redirectFlush = io.in.bits.redirectFlush
251c559bb17SZhaoyang You
252e877d8bfSXuan Hu  val hasTrap = io.fromRob.trap.valid
253e877d8bfSXuan Hu  val trapVec = io.fromRob.trap.bits.trapVec
254e877d8bfSXuan Hu  val trapPC = io.fromRob.trap.bits.pc
255bfac3305Speixiaokun  val trapPCGPA = io.fromRob.trap.bits.pcGPA
256e877d8bfSXuan Hu  val trapIsInterrupt = io.fromRob.trap.bits.isInterrupt
257e877d8bfSXuan Hu  val trapIsCrossPageIPF = io.fromRob.trap.bits.crossPageIPFFix
2587e0f64b0SGuanghui Cheng  val trigger = io.fromRob.trap.bits.trigger
2594ac3bf33Schengguanghui  val singleStep = io.fromRob.trap.bits.singleStep
260f60da58cSXuan Hu  val trapIsHls = io.fromRob.trap.bits.isHls
261c1b28b66STang Haojin  val trapIsFetchMalAddr = io.fromRob.trap.bits.isFetchMalAddr
262fe52823cSXuan Hu  val trapIsFetchBkpt = io.fromRob.trap.bits.isFetchBkpt
263ad415ae0SXiaokun-Pei  val trapIsForVSnonLeafPTE = io.fromRob.trap.bits.isForVSnonLeafPTE
264a7a6d0a6Schengguanghui
265a7a6d0a6Schengguanghui  // debug_intrrupt
266a7a6d0a6Schengguanghui  val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable
267a7a6d0a6Schengguanghui  val debugIntr = platformIRP.debugIP && debugIntrEnable
268039cdc35SXuan Hu
26901cdded8SXuan Hu  // CSR Privilege State
270f60da58cSXuan Hu  val PRVM = RegInit(PrivMode(1, 0), PrivMode.M)
271237d4cfdSXuan Hu  val V = RegInit(VirtMode(0), VirtMode.Off)
27201cdded8SXuan Hu  val debugMode = RegInit(false.B)
2732e25304fSXu, Zefan  private val nextV = WireInit(VirtMode(0), VirtMode.Off)
2742e25304fSXu, Zefan  V := nextV
2751e49aeedSchengguanghui  // dcsr stopcount
2761e49aeedSchengguanghui  val debugModeStopCountNext = debugMode && dcsr.regOut.STOPCOUNT
2771e49aeedSchengguanghui  val debugModeStopTimeNext  = debugMode && dcsr.regOut.STOPTIME
2781e49aeedSchengguanghui  val debugModeStopCount = RegNext(debugModeStopCountNext)
2791e49aeedSchengguanghui  val unprivCountUpdate  = !debugModeStopCount && debugModeStopCountNext
2801e49aeedSchengguanghui
281a751b11aSchengguanghui  val criticalErrorStateInCSR = Wire(Bool())
282a751b11aSchengguanghui  val criticalErrorState = RegEnable(true.B, false.B, io.fromTop.criticalErrorState || criticalErrorStateInCSR)
283a751b11aSchengguanghui
284881eb731SXuan Hu  private val privState = Wire(new PrivState)
285881eb731SXuan Hu  privState.PRVM := PRVM
286881eb731SXuan Hu  privState.V := V
28701cdded8SXuan Hu
288760398d7SXuan Hu  private val isModeM              = privState.isModeM
289760398d7SXuan Hu  private val (isModeHS, isModeHU) = (privState.isModeHS, privState.isModeHU)
290760398d7SXuan Hu  private val (isModeVS, isModeVU) = (privState.isModeVS, privState.isModeVU)
291760398d7SXuan Hu
29201cdded8SXuan Hu  val permitMod = Module(new CSRPermitModule)
2930b4c00ffSXuan Hu  val sstcIRGen = Module(new SstcInterruptGen)
294844fba5bSXuan Hu  val commidIdMod = Module(new CommitIDModule(40))
295844fba5bSXuan Hu
296844fba5bSXuan Hu  val gitCommitSHA = WireInit(commidIdMod.io.commitID)
297844fba5bSXuan Hu  val gitDirty     = WireInit(commidIdMod.io.dirty)
298844fba5bSXuan Hu  dontTouch(gitCommitSHA)
299844fba5bSXuan Hu  dontTouch(gitDirty)
30001cdded8SXuan Hu
30152abe1cbSXuan Hu  private val wenLegal = permitMod.io.out.hasLegalWen
302039cdc35SXuan Hu
303f1b77b5eSXuan Hu  val legalSret  = permitMod.io.out.hasLegalSret
304f1b77b5eSXuan Hu  val legalMret  = permitMod.io.out.hasLegalMret
305c2a2229dSlewislzh  val legalMNret = permitMod.io.out.hasLegalMNret
306be37cd3aSsinceforYy  val legalDret  = permitMod.io.out.hasLegalDret
307039cdc35SXuan Hu
3087071df62SZhaoyang You  private val wenLegalReg = GatedValidRegNext(wenLegal)
3097071df62SZhaoyang You
31094895e77SXuan Hu  var csrRwMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] =
311223cba9dSXuan Hu    machineLevelCSRMap ++
312223cba9dSXuan Hu    supervisorLevelCSRMap ++
313223cba9dSXuan Hu    hypervisorCSRMap ++
314223cba9dSXuan Hu    virtualSupervisorCSRMap ++
315223cba9dSXuan Hu    unprivilegedCSRMap ++
316223cba9dSXuan Hu    debugCSRMap ++
317223cba9dSXuan Hu    aiaCSRMap ++
3189ff1c68fSsinceforYy    customCSRMap ++
319011d262cSZhaoyang You    pmpCSRMap ++
320011d262cSZhaoyang You    pmaCSRMap
321039cdc35SXuan Hu
322760398d7SXuan Hu  val csrMods: Seq[CSRModule[_]] =
323223cba9dSXuan Hu    machineLevelCSRMods ++
324223cba9dSXuan Hu    supervisorLevelCSRMods ++
325223cba9dSXuan Hu    hypervisorCSRMods ++
326223cba9dSXuan Hu    virtualSupervisorCSRMods ++
327223cba9dSXuan Hu    unprivilegedCSRMods ++
328223cba9dSXuan Hu    debugCSRMods ++
329223cba9dSXuan Hu    aiaCSRMods ++
3309ff1c68fSsinceforYy    customCSRMods ++
331011d262cSZhaoyang You    pmpCSRMods ++
332011d262cSZhaoyang You    pmaCSRMods
333039cdc35SXuan Hu
334760398d7SXuan Hu  var csrOutMap: SeqMap[Int, UInt] =
335223cba9dSXuan Hu    machineLevelCSROutMap ++
336223cba9dSXuan Hu    supervisorLevelCSROutMap ++
337223cba9dSXuan Hu    hypervisorCSROutMap ++
338223cba9dSXuan Hu    virtualSupervisorCSROutMap ++
339223cba9dSXuan Hu    unprivilegedCSROutMap ++
340223cba9dSXuan Hu    debugCSROutMap ++
341223cba9dSXuan Hu    aiaCSROutMap ++
3429ff1c68fSsinceforYy    customCSROutMap ++
343011d262cSZhaoyang You    pmpCSROutMap ++
344011d262cSZhaoyang You    pmaCSROutMap
345e877d8bfSXuan Hu
3464016eee8SsinceforYy  // interrupt
3478bc90631SZehao Liu  val nmip = RegInit(new NonMaskableIRPendingBundle, (new NonMaskableIRPendingBundle).init)
3488bc90631SZehao Liu  when(nonMaskableIRP.NMI_43) {
3498bc90631SZehao Liu    nmip.NMI_43 := true.B
3508bc90631SZehao Liu  }
3518bc90631SZehao Liu  when(nonMaskableIRP.NMI_31) {
3528bc90631SZehao Liu    nmip.NMI_31 := true.B
3538bc90631SZehao Liu  }
3548bc90631SZehao Liu
3554016eee8SsinceforYy  val intrMod = Module(new InterruptFilter)
356760398d7SXuan Hu  intrMod.io.in.privState := privState
3578aa89407SXuan Hu  intrMod.io.in.mstatusMIE := mstatus.regOut.MIE.asBool
3588aa89407SXuan Hu  intrMod.io.in.sstatusSIE := mstatus.regOut.SIE.asBool
3598aa89407SXuan Hu  intrMod.io.in.vsstatusSIE := vsstatus.regOut.SIE.asBool
360e2216ecaSXuan Hu  intrMod.io.in.mip := mip.rdataFields
3617e1c6071SXuan Hu  intrMod.io.in.mie := mie.regOut
3627e1c6071SXuan Hu  intrMod.io.in.mideleg := mideleg.regOut
3637e1c6071SXuan Hu  intrMod.io.in.sip := sip.regOut
3647e1c6071SXuan Hu  intrMod.io.in.sie := sie.regOut
3657e1c6071SXuan Hu  intrMod.io.in.hip := hip.regOut
3667e1c6071SXuan Hu  intrMod.io.in.hie := hie.regOut
3677e1c6071SXuan Hu  intrMod.io.in.hideleg := hideleg.regOut
3687e1c6071SXuan Hu  intrMod.io.in.vsip := vsip.regOut
3697e1c6071SXuan Hu  intrMod.io.in.vsie := vsie.regOut
3707e1c6071SXuan Hu  intrMod.io.in.hvictl := hvictl.regOut
3717e1c6071SXuan Hu  intrMod.io.in.hstatus := hstatus.regOut
3727e1c6071SXuan Hu  intrMod.io.in.mtopei := mtopei.regOut
3737e1c6071SXuan Hu  intrMod.io.in.stopei := stopei.regOut
3747e1c6071SXuan Hu  intrMod.io.in.vstopei := vstopei.regOut
3757e1c6071SXuan Hu  intrMod.io.in.hviprio1 := hviprio1.regOut
3767e1c6071SXuan Hu  intrMod.io.in.hviprio2 := hviprio2.regOut
3778aa89407SXuan Hu  intrMod.io.in.miprios := Cat(miregiprios.map(_.rdata).reverse)
3788aa89407SXuan Hu  intrMod.io.in.hsiprios := Cat(siregiprios.map(_.rdata).reverse)
379c2a2229dSlewislzh  intrMod.io.in.mnstatusNMIE := mnstatus.regOut.NMIE.asBool
380c2a2229dSlewislzh  intrMod.io.in.nmi := nmip.asUInt.orR
381c2a2229dSlewislzh  intrMod.io.in.nmiVec := nmip.asUInt
382a751b11aSchengguanghui  intrMod.io.in.debugMode := debugMode
383a751b11aSchengguanghui  intrMod.io.in.debugIntr := debugIntr
384a751b11aSchengguanghui  intrMod.io.in.dcsr      := dcsr.regOut
38550ccead4SsinceforYy  intrMod.io.in.platform.meip := platformIRP.MEIP
38650ccead4SsinceforYy  intrMod.io.in.platform.seip := platformIRP.SEIP
38750ccead4SsinceforYy  intrMod.io.in.fromAIA.meip := fromAIA.meip
38850ccead4SsinceforYy  intrMod.io.in.fromAIA.seip := fromAIA.seip
389c2a2229dSlewislzh
390c2a2229dSlewislzh  when(intrMod.io.out.nmi && intrMod.io.out.interruptVec.valid) {
39122872cfdSsinceforYy    nmip.NMI_31 := nmip.NMI_31 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_31)
39222872cfdSsinceforYy    nmip.NMI_43 := nmip.NMI_43 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_43)
393c2a2229dSlewislzh  }
394d5f305ceSsinceforYy  val intrVec = RegEnable(intrMod.io.out.interruptVec.bits, 0.U, intrMod.io.out.interruptVec.valid)
39522872cfdSsinceforYy  val debug = RegEnable(intrMod.io.out.debug, false.B, intrMod.io.out.interruptVec.valid)
396c2a2229dSlewislzh  val nmi = RegEnable(intrMod.io.out.nmi, false.B, intrMod.io.out.interruptVec.valid)
3979205730dSsinceforYy  val virtualInterruptIsHvictlInject = RegEnable(intrMod.io.out.virtualInterruptIsHvictlInject, false.B, intrMod.io.out.interruptVec.valid)
398a5cb9e82SsinceforYy  val irToHS = RegEnable(intrMod.io.out.irToHS, false.B, intrMod.io.out.interruptVec.valid)
399a5cb9e82SsinceforYy  val irToVS = RegEnable(intrMod.io.out.irToVS, false.B, intrMod.io.out.interruptVec.valid)
400d5f305ceSsinceforYy
401d5f305ceSsinceforYy  val trapHandleMod = Module(new TrapHandleModule)
402d5f305ceSsinceforYy
403d5f305ceSsinceforYy  trapHandleMod.io.in.trapInfo.valid := hasTrap
404d5f305ceSsinceforYy  trapHandleMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt
405c2a2229dSlewislzh  trapHandleMod.io.in.trapInfo.bits.nmi := nmi
406d5f305ceSsinceforYy  trapHandleMod.io.in.trapInfo.bits.intrVec := intrVec
407d5f305ceSsinceforYy  trapHandleMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
408a5cb9e82SsinceforYy  trapHandleMod.io.in.trapInfo.bits.irToHS := irToHS
409a5cb9e82SsinceforYy  trapHandleMod.io.in.trapInfo.bits.irToVS := irToVS
410d5f305ceSsinceforYy  trapHandleMod.io.in.privState := privState
4116808b803SZehao Liu  trapHandleMod.io.in.mstatus  := mstatus.regOut
4126808b803SZehao Liu  trapHandleMod.io.in.vsstatus := vsstatus.regOut
4136808b803SZehao Liu  trapHandleMod.io.in.mnstatus := mnstatus.regOut
414d5f305ceSsinceforYy  trapHandleMod.io.in.mideleg  := mideleg.regOut
415d5f305ceSsinceforYy  trapHandleMod.io.in.medeleg  := medeleg.regOut
416d5f305ceSsinceforYy  trapHandleMod.io.in.hideleg  := hideleg.regOut
417d5f305ceSsinceforYy  trapHandleMod.io.in.hedeleg  := hedeleg.regOut
418a3dd7166SXuan Hu  trapHandleMod.io.in.mvien := mvien.regOut
419a3dd7166SXuan Hu  trapHandleMod.io.in.hvien := hvien.regOut
420d5f305ceSsinceforYy  trapHandleMod.io.in.mtvec := mtvec.regOut
421d5f305ceSsinceforYy  trapHandleMod.io.in.stvec := stvec.regOut
422d5f305ceSsinceforYy  trapHandleMod.io.in.vstvec := vstvec.regOut
4239205730dSsinceforYy  trapHandleMod.io.in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
424a751b11aSchengguanghui  trapHandleMod.io.in.trapInfo.bits.singleStep  := hasTrap && !trapIsInterrupt && singleStep
425d5f305ceSsinceforYy
426d5f305ceSsinceforYy  val entryPrivState = trapHandleMod.io.out.entryPrivState
4277e0f64b0SGuanghui Cheng  val entryDebugMode = WireInit(false.B)
4286808b803SZehao Liu  val dbltrpToMN     = trapHandleMod.io.out.dbltrpToMN
4296808b803SZehao Liu  val hasDTExcp      = trapHandleMod.io.out.hasDTExcp
430d5f305ceSsinceforYy
4319ff1c68fSsinceforYy  // PMP
4329ff1c68fSsinceforYy  val pmpEntryMod = Module(new PMPEntryHandleModule)
433011d262cSZhaoyang You  pmpEntryMod.io.in.pmpCfg  := pmpcfgs.map(_.regOut.asInstanceOf[PMPCfgBundle])
43416214c85SsinceforYy  pmpEntryMod.io.in.pmpAddr := pmpaddr.map(_.regOut.asInstanceOf[PMPAddrBundle])
4359ff1c68fSsinceforYy  pmpEntryMod.io.in.ren   := ren
4367071df62SZhaoyang You  pmpEntryMod.io.in.wen   := wenLegalReg
4379ff1c68fSsinceforYy  pmpEntryMod.io.in.addr  := addr
43832fe4d47SsinceforYy  pmpEntryMod.io.in.wdata := wdata
4399ff1c68fSsinceforYy
440011d262cSZhaoyang You  // PMA
441011d262cSZhaoyang You  val pmaEntryMod = Module(new PMAEntryHandleModule)
442011d262cSZhaoyang You  pmaEntryMod.io.in.pmaCfg  := pmacfgs.map(_.regOut.asInstanceOf[PMACfgBundle])
443011d262cSZhaoyang You  pmaEntryMod.io.in.ren   := ren
444011d262cSZhaoyang You  pmaEntryMod.io.in.wen   := wenLegalReg
445011d262cSZhaoyang You  pmaEntryMod.io.in.addr  := addr
446011d262cSZhaoyang You  pmaEntryMod.io.in.wdata := wdata
447011d262cSZhaoyang You
4489c5487c4SXuan Hu  // Todo: all wen and wdata of CSRModule assigned in this for loop
449039cdc35SXuan Hu  for ((id, (wBundle, _)) <- csrRwMap) {
450760398d7SXuan Hu    if (vsMapS.contains(id)) {
451760398d7SXuan Hu      // VS access CSR by S: privState.isModeVS && addrMappedToVS === sMapVS(id).U
45232fe4d47SsinceforYy      wBundle.wen := wenLegalReg && ((isModeVS && addr === vsMapS(id).U) || (!isModeVS && addr === id.U))
45332fe4d47SsinceforYy      wBundle.wdata := wdata
454760398d7SXuan Hu    } else if (sMapVS.contains(id)) {
45532fe4d47SsinceforYy      wBundle.wen := wenLegalReg && !isModeVS && addr === id.U
45632fe4d47SsinceforYy      wBundle.wdata := wdata
457760398d7SXuan Hu    } else {
45832fe4d47SsinceforYy      wBundle.wen := wenLegalReg && addr === id.U
45932fe4d47SsinceforYy      wBundle.wdata := wdata
460039cdc35SXuan Hu    }
461760398d7SXuan Hu  }
462039cdc35SXuan Hu
46388857889SXuan Hu  private val writeFpLegal  = permitMod.io.out.hasLegalWriteFcsr
46488857889SXuan Hu  private val writeVecLegal = permitMod.io.out.hasLegalWriteVcsr
46501cdded8SXuan Hu
466f7c21cb5SXuan Hu  permitMod.io.in.csrAccess.ren := ren && valid
46752abe1cbSXuan Hu  permitMod.io.in.csrAccess.wen := wen
46852abe1cbSXuan Hu  permitMod.io.in.csrAccess.addr := addr
46901cdded8SXuan Hu
470760398d7SXuan Hu  permitMod.io.in.privState := privState
471a7a6d0a6Schengguanghui  permitMod.io.in.debugMode := debugMode
47201cdded8SXuan Hu
47337748a0bSNewPaulWalker  permitMod.io.in.xRet.mnret := io.in.bits.mnret && valid
47437748a0bSNewPaulWalker  permitMod.io.in.xRet.mret  := io.in.bits.mret  && valid
47537748a0bSNewPaulWalker  permitMod.io.in.xRet.sret  := io.in.bits.sret  && valid
47637748a0bSNewPaulWalker  permitMod.io.in.xRet.dret  := io.in.bits.dret  && valid
47701cdded8SXuan Hu
4788aa89407SXuan Hu  permitMod.io.in.status.tsr := mstatus.regOut.TSR.asBool
4798aa89407SXuan Hu  permitMod.io.in.status.vtsr := hstatus.regOut.VTSR.asBool
48001cdded8SXuan Hu
48190cbdd93SsinceforYy  permitMod.io.in.status.tvm  := mstatus.regOut.TVM.asBool
48290cbdd93SsinceforYy  permitMod.io.in.status.vtvm := hstatus.regOut.VTVM.asBool
48390cbdd93SsinceforYy
484e733b25bSlinzhida  permitMod.io.in.status.vgein := hstatus.regOut.VGEIN.asUInt
485e733b25bSlinzhida
48637748a0bSNewPaulWalker  permitMod.io.in.xcounteren.mcounteren := mcounteren.rdata
48737748a0bSNewPaulWalker  permitMod.io.in.xcounteren.hcounteren := hcounteren.rdata
48837748a0bSNewPaulWalker  permitMod.io.in.xcounteren.scounteren := scounteren.rdata
48965ddf865SXuan Hu
49037748a0bSNewPaulWalker  permitMod.io.in.xstateen.mstateen0 := mstateen0.rdata
49137748a0bSNewPaulWalker  permitMod.io.in.xstateen.hstateen0 := hstateen0.rdata
49237748a0bSNewPaulWalker  permitMod.io.in.xstateen.sstateen0 := sstateen0.rdata
49326033c52Schengguanghui
49437748a0bSNewPaulWalker  permitMod.io.in.xenvcfg.menvcfg := menvcfg.rdata
49537748a0bSNewPaulWalker  permitMod.io.in.xenvcfg.henvcfg := henvcfg.rdata
4961e8ffa38SsinceforYy
49788857889SXuan Hu  permitMod.io.in.status.mstatusFSOff  :=  mstatus.regOut.FS === ContextStatus.Off
49888857889SXuan Hu  permitMod.io.in.status.mstatusVSOff  :=  mstatus.regOut.VS === ContextStatus.Off
49988857889SXuan Hu  permitMod.io.in.status.vsstatusFSOff := vsstatus.regOut.FS === ContextStatus.Off
50088857889SXuan Hu  permitMod.io.in.status.vsstatusVSOff := vsstatus.regOut.VS === ContextStatus.Off
5014d2be3d2SsinceforYy
5027a0a09b9SsinceforYy  permitMod.io.in.aia.miselectIsIllegal  := miselect.isIllegal
5037a0a09b9SsinceforYy  permitMod.io.in.aia.siselectIsIllegal  := siselect.isIllegal
5047a0a09b9SsinceforYy  permitMod.io.in.aia.vsiselectIsIllegal := vsiselect.isIllegal
5057a0a09b9SsinceforYy  permitMod.io.in.aia.siselect := siselect.rdata
5067a0a09b9SsinceforYy  permitMod.io.in.aia.vsiselect := vsiselect.rdata
5077a0a09b9SsinceforYy  permitMod.io.in.aia.mvienSEIE := mvien.regOut.SEIE.asBool
5087a0a09b9SsinceforYy  permitMod.io.in.aia.hvictlVTI := hvictl.regOut.VTI.asBool
5097a0a09b9SsinceforYy
510244b1012SsinceforYy  sstcIRGen.i.stime.valid := time.updated
511244b1012SsinceforYy  sstcIRGen.i.stime.bits  := time.stime
512244b1012SsinceforYy  sstcIRGen.i.vstime.valid := time.updated
513244b1012SsinceforYy  sstcIRGen.i.vstime.bits  := time.vstime
51400514503SZhaoyang You  sstcIRGen.i.stimecmp.wen := GatedValidRegNext(stimecmp.w.wen)
51500514503SZhaoyang You  sstcIRGen.i.stimecmp.rdata  := stimecmp.rdata
51600514503SZhaoyang You  sstcIRGen.i.vstimecmp.wen   := GatedValidRegNext(vstimecmp.w.wen)
51700514503SZhaoyang You  sstcIRGen.i.vstimecmp.rdata := vstimecmp.rdata
51800514503SZhaoyang You  sstcIRGen.i.menvcfg.wen   := GatedValidRegNext(menvcfg.w.wen)
51900514503SZhaoyang You  sstcIRGen.i.menvcfg.STCE  := menvcfg.regOut.STCE.asBool
52000514503SZhaoyang You  sstcIRGen.i.henvcfg.wen   := GatedValidRegNext(henvcfg.w.wen)
52100514503SZhaoyang You  sstcIRGen.i.henvcfg.STCE  := henvcfg.regOut.STCE.asBool
52200514503SZhaoyang You  sstcIRGen.i.htimedeltaWen := GatedValidRegNext(htimedelta.w.wen)
5230b4c00ffSXuan Hu
524523f2fa2SXuan Hu  miregiprios.foreach { mod =>
5259c5487c4SXuan Hu    mod.w.wen := mireg.w.wen && (miselect.regOut.ALL.asUInt === mod.addr.U)
52632fe4d47SsinceforYy    mod.w.wdata := wdata
527523f2fa2SXuan Hu  }
528523f2fa2SXuan Hu
529523f2fa2SXuan Hu  siregiprios.foreach { mod =>
5309c5487c4SXuan Hu    mod.w.wen := sireg.w.wen && (siselect.regOut.ALL.asUInt === mod.addr.U)
53132fe4d47SsinceforYy    mod.w.wdata := wdata
532523f2fa2SXuan Hu  }
533523f2fa2SXuan Hu
53496292cf5SsinceforYy  iregiprios.foreach { mod =>
53596292cf5SsinceforYy    mod match {
53696292cf5SsinceforYy      case m: HasIeBundle =>
53796292cf5SsinceforYy        m.mie := mie.regOut
53896292cf5SsinceforYy        m.sie := sie.regOut
53996292cf5SsinceforYy      case _ =>
54096292cf5SsinceforYy    }
54196292cf5SsinceforYy  }
54296292cf5SsinceforYy
543cb4fe84bSXuan Hu  mhartid.hartid := this.io.fromTop.hartId
544cb4fe84bSXuan Hu
545011d262cSZhaoyang You  pmpcfgs.zipWithIndex.foreach { case (mod, i) =>
546011d262cSZhaoyang You    mod.w.wen   := wenLegalReg && (addr === (CSRs.pmpcfg0 + i / 8 * 2).U)
5479ff1c68fSsinceforYy    mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8))
5489ff1c68fSsinceforYy  }
5499ff1c68fSsinceforYy
5509ff1c68fSsinceforYy  pmpaddr.zipWithIndex.foreach { case (mod, i) =>
551011d262cSZhaoyang You    mod.w.wen   := wenLegalReg && (addr === (CSRs.pmpaddr0 + i).U)
5529ff1c68fSsinceforYy    mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i)
5539ff1c68fSsinceforYy  }
5549ff1c68fSsinceforYy
555011d262cSZhaoyang You  pmacfgs.zipWithIndex.foreach { case (mod, i) =>
556011d262cSZhaoyang You    mod.w.wen   := wenLegalReg && (addr === (CSRConst.PmacfgBase + i / 8 * 2).U)
557011d262cSZhaoyang You    mod.w.wdata := pmaEntryMod.io.out.pmaCfgWdata(8*((i%8)+1)-1,8*(i%8))
558011d262cSZhaoyang You  }
559011d262cSZhaoyang You
560039cdc35SXuan Hu  csrMods.foreach { mod =>
561039cdc35SXuan Hu    mod match {
562039cdc35SXuan Hu      case m: HypervisorBundle =>
563039cdc35SXuan Hu        m.hstatus := hstatus.regOut
564039cdc35SXuan Hu      case _ =>
565039cdc35SXuan Hu    }
566039cdc35SXuan Hu    mod match {
567f56c6de4SsinceforYy      case m: VirtualSupervisorBundle =>
568f56c6de4SsinceforYy        m.v := V.asUInt.asBool
5699c0fd28fSXuan Hu        m.hgatp := hgatp.regOut
570f56c6de4SsinceforYy      case _ =>
571f56c6de4SsinceforYy    }
572f56c6de4SsinceforYy    mod match {
573039cdc35SXuan Hu      case m: HasMachineDelegBundle =>
574039cdc35SXuan Hu        m.mideleg := mideleg.regOut
575039cdc35SXuan Hu        m.medeleg := medeleg.regOut
576039cdc35SXuan Hu      case _ =>
577039cdc35SXuan Hu    }
578039cdc35SXuan Hu    mod match {
579039cdc35SXuan Hu      case m: HasMachineCounterControlBundle =>
580039cdc35SXuan Hu        m.mcountinhibit := mcountinhibit.regOut
581039cdc35SXuan Hu      case _ =>
582039cdc35SXuan Hu    }
583039cdc35SXuan Hu    mod match {
584039cdc35SXuan Hu      case m: HasExternalInterruptBundle =>
585039cdc35SXuan Hu        m.platformIRP := this.platformIRP
5860b4c00ffSXuan Hu        m.platformIRP.STIP  := sstcIRGen.o.STIP
5870b4c00ffSXuan Hu        m.platformIRP.VSTIP := sstcIRGen.o.VSTIP
588039cdc35SXuan Hu      case _ =>
589039cdc35SXuan Hu    }
590039cdc35SXuan Hu    mod match {
59101cdded8SXuan Hu      case m: HasRobCommitBundle =>
59253e1a9f5SXuan Hu        // Todo: move RegNext from ROB to CSR
59353e1a9f5SXuan Hu        m.robCommit.instNum := io.fromRob.commit.instNum
59453e1a9f5SXuan Hu        m.robCommit.fflags  := RegNextWithEnable(io.fromRob.commit.fflags)
595a0231889SXuan Hu        m.robCommit.fsDirty := GatedValidRegNext(io.fromRob.commit.fsDirty)
596a0231889SXuan Hu        m.robCommit.vsDirty := GatedValidRegNext(io.fromRob.commit.vsDirty)
59753e1a9f5SXuan Hu        m.robCommit.vxsat   := RegNextWithEnable(io.fromRob.commit.vxsat)
59853e1a9f5SXuan Hu        m.robCommit.vtype   := RegNextWithEnable(io.fromRob.commit.vtype)
59953e1a9f5SXuan Hu        m.robCommit.vl      := RegNext          (io.fromRob.commit.vl)
60053e1a9f5SXuan Hu        m.robCommit.vstart  := RegNextWithEnable(io.fromRob.commit.vstart)
601a0231889SXuan Hu        m.writeFCSR         := writeFpLegal
602a0231889SXuan Hu        m.writeVCSR         := writeVecLegal
60382f438edSXuan Hu        m.isVirtMode        := V.asUInt.asBool
604039cdc35SXuan Hu      case _ =>
605039cdc35SXuan Hu    }
606237d4cfdSXuan Hu    mod match {
607a7a6d0a6Schengguanghui      case m: TrapEntryDEventSinkBundle =>
608a7a6d0a6Schengguanghui        m.trapToD := trapEntryDEvent.out
609a7a6d0a6Schengguanghui      case _ =>
610a7a6d0a6Schengguanghui    }
611a7a6d0a6Schengguanghui    mod match {
612237d4cfdSXuan Hu      case m: TrapEntryMEventSinkBundle =>
613237d4cfdSXuan Hu        m.trapToM := trapEntryMEvent.out
614237d4cfdSXuan Hu      case _ =>
615237d4cfdSXuan Hu    }
616237d4cfdSXuan Hu    mod match {
617c2a2229dSlewislzh      case m: TrapEntryMNEventSinkBundle =>
618c2a2229dSlewislzh        m.trapToMN := trapEntryMNEvent.out
619c2a2229dSlewislzh      case _ =>
620c2a2229dSlewislzh    }
621c2a2229dSlewislzh    mod match {
622237d4cfdSXuan Hu      case m: TrapEntryHSEventSinkBundle =>
623237d4cfdSXuan Hu        m.trapToHS := trapEntryHSEvent.out
624237d4cfdSXuan Hu      case _ =>
625237d4cfdSXuan Hu    }
626237d4cfdSXuan Hu    mod match {
627237d4cfdSXuan Hu      case m: TrapEntryVSEventSinkBundle =>
628237d4cfdSXuan Hu        m.trapToVS := trapEntryVSEvent.out
629237d4cfdSXuan Hu      case _ =>
630237d4cfdSXuan Hu    }
631237d4cfdSXuan Hu    mod match {
632237d4cfdSXuan Hu      case m: MretEventSinkBundle =>
633237d4cfdSXuan Hu        m.retFromM := mretEvent.out
634237d4cfdSXuan Hu      case _ =>
635237d4cfdSXuan Hu    }
636237d4cfdSXuan Hu    mod match {
637c2a2229dSlewislzh      case m: MNretEventSinkBundle =>
638c2a2229dSlewislzh        m.retFromMN := mnretEvent.out
639c2a2229dSlewislzh      case _ =>
640c2a2229dSlewislzh    }
641c2a2229dSlewislzh    mod match {
642237d4cfdSXuan Hu      case m: SretEventSinkBundle =>
643237d4cfdSXuan Hu        m.retFromS := sretEvent.out
644237d4cfdSXuan Hu      case _ =>
645237d4cfdSXuan Hu    }
646007f6122SXuan Hu    mod match {
647eca6983fSZehao Liu      case m: SretEventSDTSinkBundle =>
648eca6983fSZehao Liu        m.retFromSSDT := sretEvent.outSDT
649eca6983fSZehao Liu      case _ =>
650eca6983fSZehao Liu    }
651eca6983fSZehao Liu    mod match {
6521e7040baSsinceforYy      case m: DretEventSinkBundle =>
6531e7040baSsinceforYy        m.retFromD := dretEvent.out
65447bb101bSXuan Hu      case _ =>
6551e7040baSsinceforYy    }
6561e7040baSsinceforYy    mod match {
657007f6122SXuan Hu      case m: HasAIABundle =>
658007f6122SXuan Hu        m.aiaToCSR.rdata.valid := fromAIA.rdata.valid
659007f6122SXuan Hu        m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data
660007f6122SXuan Hu        m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal
66189bb2535SXuan Hu        m.aiaToCSR.meip    := fromAIA.meip
66289bb2535SXuan Hu        m.aiaToCSR.seip    := fromAIA.seip
66389bb2535SXuan Hu        m.aiaToCSR.vseip   := fromAIA.vseip
66489bb2535SXuan Hu        m.aiaToCSR.mtopei  := fromAIA.mtopei
66589bb2535SXuan Hu        m.aiaToCSR.stopei  := fromAIA.stopei
66689bb2535SXuan Hu        m.aiaToCSR.vstopei := fromAIA.vstopei
667007f6122SXuan Hu      case _ =>
668007f6122SXuan Hu    }
6694016eee8SsinceforYy    mod match {
670523f2fa2SXuan Hu      case m: HasInterruptFilterSink =>
671523f2fa2SXuan Hu        m.topIR.mtopi  := intrMod.io.out.mtopi
672523f2fa2SXuan Hu        m.topIR.stopi  := intrMod.io.out.stopi
673523f2fa2SXuan Hu        m.topIR.vstopi := intrMod.io.out.vstopi
6744016eee8SsinceforYy      case _ =>
6754016eee8SsinceforYy    }
6764016eee8SsinceforYy    mod match {
6779ff1c68fSsinceforYy      case m: HasPMPAddrSink =>
6789ff1c68fSsinceforYy        m.addrRData := pmpEntryMod.io.out.pmpAddrRData
6799ff1c68fSsinceforYy      case _ =>
6809ff1c68fSsinceforYy    }
681e628dd84SXuan Hu    mod match {
682011d262cSZhaoyang You      case m: HasPMAAddrSink =>
683011d262cSZhaoyang You        m.addrRData := pmaEntryMod.io.out.pmaAddrRData
684011d262cSZhaoyang You      case _ =>
685011d262cSZhaoyang You    }
686011d262cSZhaoyang You    mod match {
68765ddf865SXuan Hu      case m: HasMHPMSink =>
68865ddf865SXuan Hu        // cycle from mcycle
68965ddf865SXuan Hu        m.mHPM.cycle := mcycle.rdata
69065ddf865SXuan Hu        // time from clint
69165ddf865SXuan Hu        m.mHPM.time  := io.fromTop.clintTime
69265ddf865SXuan Hu        // instret from minstret
69365ddf865SXuan Hu        m.mHPM.instret := minstret.rdata
694244b1012SsinceforYy        // VS-Mode or VU-Mode
695244b1012SsinceforYy        m.v := privState.isVirtual
6962e25304fSXu, Zefan        m.nextV := nextV.isOneOf(VirtMode.On)
697244b1012SsinceforYy        m.htimedelta := htimedelta.rdata
698b51a1abdSchengguanghui        m.mHPM.hpmcounters.zip(mhpmcounters).map{
699b51a1abdSchengguanghui          case(counter, mcounter) => counter := mcounter.rdata
700b51a1abdSchengguanghui        }
701e628dd84SXuan Hu      case _ =>
702e628dd84SXuan Hu    }
7030b4c00ffSXuan Hu    mod match {
7040b4c00ffSXuan Hu      case m: HasMachineEnvBundle =>
7050b4c00ffSXuan Hu        m.menvcfg := menvcfg.regOut
7060b4c00ffSXuan Hu      case _ =>
7070b4c00ffSXuan Hu    }
7088fafb45aSsinceforYy    mod match {
7098fafb45aSsinceforYy      case m: HasHypervisorEnvBundle =>
7108fafb45aSsinceforYy        m.menvcfg := menvcfg.regOut
7118fafb45aSsinceforYy      case _ =>
7128fafb45aSsinceforYy    }
7131d192ad8SXuan Hu    mod match {
7146808b803SZehao Liu      case m: HasVirtualSupervisorEnvBundle =>
7156808b803SZehao Liu        m.henvcfg := henvcfg.regOut
7166808b803SZehao Liu        m.menvcfg := menvcfg.regOut
7176808b803SZehao Liu      case _ =>
7186808b803SZehao Liu    }
7196808b803SZehao Liu    mod match {
7201d192ad8SXuan Hu      case m: HasIpIeBundle =>
7211d192ad8SXuan Hu        m.mideleg := mideleg.regOut
72260deedbfSXuan Hu        m.mip := mip.rdata
7231d192ad8SXuan Hu        m.mie := mie.regOut
7241d192ad8SXuan Hu        m.mvip := mvip.regOut
7251d192ad8SXuan Hu        m.mvien := mvien.regOut
7261d192ad8SXuan Hu        m.hideleg := hideleg.regOut
7271d192ad8SXuan Hu        m.hip := hip.regOut
7281d192ad8SXuan Hu        m.hie := hie.regOut
7291d192ad8SXuan Hu        m.hvien := hvien.regOut
7301d192ad8SXuan Hu        m.hvip := hvip.regOut
7311d192ad8SXuan Hu        m.sip := sip.regOut
7321d192ad8SXuan Hu        m.sie := sie.regOut
7331d192ad8SXuan Hu        m.vsip := vsip.regOut
7341d192ad8SXuan Hu        m.vsie := vsie.regOut
7351d192ad8SXuan Hu        m.hgeip := hgeip.regOut
7361d192ad8SXuan Hu        m.hgeie := hgeie.regOut
7371d192ad8SXuan Hu        m.hstatusVGEIN := hstatus.regOut.VGEIN
7381d192ad8SXuan Hu      case _ =>
7391d192ad8SXuan Hu    }
740fd72f3d9Schengguanghui    mod match {
741fd72f3d9Schengguanghui      case m: HasMhpmeventOfBundle =>
742b8e923e6Schengguanghui        m.ofVec := VecInit(mhpmevents.map{ event =>
743b8e923e6Schengguanghui          val mhpmevent = Wire(new MhpmeventBundle)
744b8e923e6Schengguanghui          mhpmevent := event.rdata
745b8e923e6Schengguanghui          mhpmevent.OF.asBool
746b8e923e6Schengguanghui        }).asUInt
747202093f4Schengguanghui        m.privState := privState
748202093f4Schengguanghui        m.mcounteren := mcounteren.rdata
749202093f4Schengguanghui        m.hcounteren := hcounteren.rdata
750fd72f3d9Schengguanghui      case _ =>
751fd72f3d9Schengguanghui    }
75226033c52Schengguanghui    mod match {
75326033c52Schengguanghui      case m: HasStateen0Bundle =>
75426033c52Schengguanghui        m.fromMstateen0 := mstateen0.regOut
75526033c52Schengguanghui        m.fromHstateen0 := hstateen0.regOut
75626033c52Schengguanghui        m.privState     := privState
75726033c52Schengguanghui      case _ =>
75826033c52Schengguanghui    }
7591e49aeedSchengguanghui    mod match {
7601e49aeedSchengguanghui      case m: HasDebugStopBundle =>
7611e49aeedSchengguanghui        m.debugModeStopCount := debugModeStopCount
7621e49aeedSchengguanghui        m.debugModeStopTime  := debugModeStopTimeNext
7631e49aeedSchengguanghui        m.unprivCountUpdate  := unprivCountUpdate
7641e49aeedSchengguanghui      case _ =>
7651e49aeedSchengguanghui    }
766a751b11aSchengguanghui    mod match {
767a751b11aSchengguanghui      case m: HasNmipBundle =>
768a751b11aSchengguanghui        m.nmip := nmip.asUInt.orR
769a751b11aSchengguanghui      case _ =>
770a751b11aSchengguanghui    }
771b7a63495SNewPaulWalker    mod match {
772b7a63495SNewPaulWalker      case m: HasMachineFlushL2Bundle =>
773b7a63495SNewPaulWalker        m.l2FlushDone := io.fromTop.l2FlushDone
774b7a63495SNewPaulWalker      case _ =>
775b7a63495SNewPaulWalker    }
776039cdc35SXuan Hu  }
777039cdc35SXuan Hu
778039cdc35SXuan Hu  csrMods.foreach { mod =>
779039cdc35SXuan Hu    println(s"${mod.modName}: ")
780039cdc35SXuan Hu    println(mod.dumpFields)
781039cdc35SXuan Hu  }
782237d4cfdSXuan Hu
783011ce0baSGuanghui Cheng  trapEntryMNEvent.valid  := ((hasTrap && nmi) || dbltrpToMN) && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
7846808b803SZehao Liu  trapEntryMEvent .valid  := hasTrap && entryPrivState.isModeM && !dbltrpToMN && !entryDebugMode && !debugMode && !nmi && mnstatus.regOut.NMIE
7856808b803SZehao Liu  trapEntryHSEvent.valid  := hasTrap && entryPrivState.isModeHS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
7866808b803SZehao Liu  trapEntryVSEvent.valid  := hasTrap && entryPrivState.isModeVS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
787237d4cfdSXuan Hu
788c2a2229dSlewislzh  Seq(trapEntryMEvent, trapEntryMNEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod =>
7890c2ba7aeSXuan Hu    eMod.in match {
7900c2ba7aeSXuan Hu      case in: TrapEntryEventInput =>
791e877d8bfSXuan Hu        in.causeNO := trapHandleMod.io.out.causeNO
792e877d8bfSXuan Hu        in.trapPc := trapPC
793bfac3305Speixiaokun        in.trapPcGPA := trapPCGPA // only used by trapEntryMEvent & trapEntryHSEvent
79492c61038SXuan Hu        in.trapInst := io.trapInst
795c1b28b66STang Haojin        in.fetchMalTval := io.fetchMalTval
796e877d8bfSXuan Hu        in.isCrossPageIPF := trapIsCrossPageIPF
797f60da58cSXuan Hu        in.isHls := trapIsHls
798c1b28b66STang Haojin        in.isFetchMalAddr := trapIsFetchMalAddr
799fe52823cSXuan Hu        in.isFetchBkpt := trapIsFetchBkpt
800ad415ae0SXiaokun-Pei        in.trapIsForVSnonLeafPTE := trapIsForVSnonLeafPTE
8016808b803SZehao Liu        in.hasDTExcp := hasDTExcp
802237d4cfdSXuan Hu
803237d4cfdSXuan Hu        in.iMode.PRVM := PRVM
804237d4cfdSXuan Hu        in.iMode.V := V
805c2a2229dSlewislzh        // when NMIE is zero, force to behave as MPRV is zero
806c2a2229dSlewislzh        in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool && mnstatus.regOut.NMIE.asBool, mstatus.regOut.MPP, PRVM)
807c2a2229dSlewislzh        in.dMode.V := V.asUInt.asBool || mstatus.regOut.MPRV && mnstatus.regOut.NMIE.asBool && (mstatus.regOut.MPP =/= PrivMode.M) && mstatus.regOut.MPV
808237d4cfdSXuan Hu
809760398d7SXuan Hu        in.privState := privState
810237d4cfdSXuan Hu        in.mstatus := mstatus.regOut
811237d4cfdSXuan Hu        in.hstatus := hstatus.regOut
812237d4cfdSXuan Hu        in.sstatus := mstatus.sstatus
813237d4cfdSXuan Hu        in.vsstatus := vsstatus.regOut
8140c2ba7aeSXuan Hu        in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec
8150c2ba7aeSXuan Hu
8166808b803SZehao Liu        in.menvcfg := menvcfg.regOut
8176808b803SZehao Liu        in.henvcfg := henvcfg.regOut
8186808b803SZehao Liu
8198aa89407SXuan Hu        in.satp  := satp.regOut
8208aa89407SXuan Hu        in.vsatp := vsatp.regOut
8218aa89407SXuan Hu        in.hgatp := hgatp.regOut
8228882eb68SXin Tian        if (HasBitmapCheck) {
8238882eb68SXin Tian          in.mbmc := mbmc.get.regOut
8248882eb68SXin Tian        } else {
8258882eb68SXin Tian          in.mbmc := DontCare
8268882eb68SXin Tian        }
827237d4cfdSXuan Hu
828237d4cfdSXuan Hu        in.memExceptionVAddr := io.fromMem.excpVA
829237d4cfdSXuan Hu        in.memExceptionGPAddr := io.fromMem.excpGPA
830ad415ae0SXiaokun-Pei        in.memExceptionIsForVSnonLeafPTE := io.fromMem.excpIsForVSnonLeafPTE
8319205730dSsinceforYy
8329205730dSsinceforYy        in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
8339205730dSsinceforYy        in.hvictlIID := hvictl.regOut.IID.asUInt
834237d4cfdSXuan Hu    }
835237d4cfdSXuan Hu  }
836237d4cfdSXuan Hu
837c2a2229dSlewislzh  mnretEvent.valid := legalMNret
838c2a2229dSlewislzh  mnretEvent.in match {
839c2a2229dSlewislzh    case in =>
840c2a2229dSlewislzh      in.mstatus := mstatus.regOut
8416808b803SZehao Liu      in.vsstatus := vsstatus.regOut
842c2a2229dSlewislzh      in.mnepc   := mnepc.regOut
843c2a2229dSlewislzh      in.mnstatus:= mnstatus.regOut
844c1b28b66STang Haojin      in.satp := satp.regOut
845c1b28b66STang Haojin      in.vsatp := vsatp.regOut
846c1b28b66STang Haojin      in.hgatp := hgatp.regOut
847c2a2229dSlewislzh  }
848c2a2229dSlewislzh
849f1b77b5eSXuan Hu  mretEvent.valid := legalMret
850237d4cfdSXuan Hu  mretEvent.in match {
851237d4cfdSXuan Hu    case in =>
852237d4cfdSXuan Hu      in.mstatus := mstatus.regOut
8536808b803SZehao Liu      in.vsstatus := vsstatus.regOut
854237d4cfdSXuan Hu      in.mepc := mepc.regOut
855c1b28b66STang Haojin      in.satp := satp.regOut
856c1b28b66STang Haojin      in.vsatp := vsatp.regOut
857c1b28b66STang Haojin      in.hgatp := hgatp.regOut
858237d4cfdSXuan Hu  }
859237d4cfdSXuan Hu
860f1b77b5eSXuan Hu  sretEvent.valid := legalSret
861237d4cfdSXuan Hu  sretEvent.in match {
862237d4cfdSXuan Hu    case in =>
863760398d7SXuan Hu      in.privState := privState
8646808b803SZehao Liu      in.mstatus := mstatus.regOut
865237d4cfdSXuan Hu      in.hstatus := hstatus.regOut
866237d4cfdSXuan Hu      in.vsstatus := vsstatus.regOut
867237d4cfdSXuan Hu      in.sepc := sepc.regOut
868237d4cfdSXuan Hu      in.vsepc := vsepc.regOut
869c1b28b66STang Haojin      in.satp := satp.regOut
870c1b28b66STang Haojin      in.vsatp := vsatp.regOut
871c1b28b66STang Haojin      in.hgatp := hgatp.regOut
872237d4cfdSXuan Hu  }
873237d4cfdSXuan Hu
874be37cd3aSsinceforYy  dretEvent.valid := legalDret
8751e7040baSsinceforYy  dretEvent.in match {
8761e7040baSsinceforYy    case in =>
8771e7040baSsinceforYy      in.dcsr := dcsr.regOut
8781e7040baSsinceforYy      in.dpc  := dpc.regOut
8791e7040baSsinceforYy      in.mstatus := mstatus.regOut
880e50a46eaSGuanghui Cheng      in.vsstatus := vsstatus.regOut
881c1b28b66STang Haojin      in.satp := satp.regOut
882c1b28b66STang Haojin      in.vsatp := vsatp.regOut
883c1b28b66STang Haojin      in.hgatp := hgatp.regOut
8841e7040baSsinceforYy  }
8851e7040baSsinceforYy
886237d4cfdSXuan Hu  PRVM := MuxCase(
887237d4cfdSXuan Hu    PRVM,
888237d4cfdSXuan Hu    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
889237d4cfdSXuan Hu      x => x.out match {
890237d4cfdSXuan Hu        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
891237d4cfdSXuan Hu      }
892237d4cfdSXuan Hu    }
893237d4cfdSXuan Hu  )
894237d4cfdSXuan Hu
8952e25304fSXu, Zefan  nextV := MuxCase(
896237d4cfdSXuan Hu    V,
897237d4cfdSXuan Hu    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
898237d4cfdSXuan Hu      x => x.out match {
899237d4cfdSXuan Hu        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
900237d4cfdSXuan Hu      }
901237d4cfdSXuan Hu    }
902237d4cfdSXuan Hu  )
903237d4cfdSXuan Hu
9046057352aSXuan Hu  debugMode := MuxCase(
9056057352aSXuan Hu    debugMode,
9066057352aSXuan Hu    Seq(
907a7a6d0a6Schengguanghui      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits,
908a7a6d0a6Schengguanghui      trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits
9096057352aSXuan Hu    )
9106057352aSXuan Hu  )
9116057352aSXuan Hu
912a7a6d0a6Schengguanghui  debugIntrEnable := MuxCase(
913a7a6d0a6Schengguanghui    debugIntrEnable,
914a7a6d0a6Schengguanghui    Seq(
915a7a6d0a6Schengguanghui      dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits,
916a7a6d0a6Schengguanghui      trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits
917a7a6d0a6Schengguanghui    )
918a7a6d0a6Schengguanghui  )
9196057352aSXuan Hu
920007f6122SXuan Hu  // perf
9219c5487c4SXuan Hu  val addrInPerfCnt = (wenLegal || ren) && (
9228a2013d4SXuan Hu    (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
9230427fd02SsinceforYy    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U)
9248a2013d4SXuan Hu  )
925007f6122SXuan Hu
9268882eb68SXin Tian  val resetSatp = WireInit(false.B)
927007f6122SXuan Hu  // flush
9288882eb68SXin Tian  if (HasBitmapCheck) {
9298882eb68SXin Tian    resetSatp := Cat(Seq(satp, vsatp, hgatp, mbmc.get).map(_.addr.U === addr)).orR && wenLegalReg // write to satp will cause the pipeline be flushed
9308882eb68SXin Tian  } else {
9318882eb68SXin Tian    resetSatp := Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegalReg // write to satp will cause the pipeline be flushed
9328882eb68SXin Tian  }
93301cdded8SXuan Hu
9340cef0d38SXuan Hu  val floatStatusOnOff = mstatus.w.wen && (
9350cef0d38SXuan Hu    mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
9360cef0d38SXuan Hu    mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
9370cef0d38SXuan Hu  ) || mstatus.wAliasSstatus.wen && (
9380cef0d38SXuan Hu    mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
9390cef0d38SXuan Hu    mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
9400cef0d38SXuan Hu  ) || vsstatus.w.wen && (
9410cef0d38SXuan Hu    vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off ||
9420cef0d38SXuan Hu    vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off
9430cef0d38SXuan Hu  )
9440cef0d38SXuan Hu
9450cef0d38SXuan Hu  val vectorStatusOnOff = mstatus.w.wen && (
9460cef0d38SXuan Hu    mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
9470cef0d38SXuan Hu    mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
9480cef0d38SXuan Hu  ) || mstatus.wAliasSstatus.wen && (
9490cef0d38SXuan Hu    mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
9500cef0d38SXuan Hu    mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
9510cef0d38SXuan Hu  ) || vsstatus.w.wen && (
9520cef0d38SXuan Hu    vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off ||
9530cef0d38SXuan Hu    vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off
9540cef0d38SXuan Hu  )
955f5fc69efSsinceforYy
956a7a6d0a6Schengguanghui  val triggerFrontendChange = Wire(Bool())
957a9d72c93SXuan Hu
958a9d72c93SXuan Hu  val vstartChange = vstart.w.wen && (
959a9d72c93SXuan Hu    vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U ||
960a9d72c93SXuan Hu    vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U
961a9d72c93SXuan Hu  )
962a9d72c93SXuan Hu
963689f6b88SsinceforYy  // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved
964689f6b88SsinceforYy  val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR
965689f6b88SsinceforYy  val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR
966689f6b88SsinceforYy  val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR
967689f6b88SsinceforYy  val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) ||
968689f6b88SsinceforYy    fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved)
969689f6b88SsinceforYy
97038b699bbSXuan Hu  val flushPipe = resetSatp ||
971a9d72c93SXuan Hu    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
972689f6b88SsinceforYy    vstartChange || frmChange
9731e7040baSsinceforYy
974075d4937Sjunxiong-ji  /**
975075d4937Sjunxiong-ji   * Look up id in vsMapS and sMapVS.
976075d4937Sjunxiong-ji   * If id is in vsMapS, use vsMapS(id) when under VS mode,
977075d4937Sjunxiong-ji   *                         id under other modes
978075d4937Sjunxiong-ji   * Else If id is in sMapVS, use 0 when under VS mode,
979075d4937Sjunxiong-ji   *                              id under modes except VS
980075d4937Sjunxiong-ji   * Else, use id as read address
981075d4937Sjunxiong-ji   * Use read address to look up rdata in csrRwMap
982075d4937Sjunxiong-ji   */
98394895e77SXuan Hu  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
98494895e77SXuan Hu    if (vsMapS.contains(id)) {
98594895e77SXuan Hu      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
98694895e77SXuan Hu    } else if (sMapVS.contains(id)) {
98794895e77SXuan Hu      (!isModeVS && addr === id.U) -> rdata
98894895e77SXuan Hu    } else {
98994895e77SXuan Hu      (raddr === id.U) -> rdata
99094895e77SXuan Hu    }
991e877d8bfSXuan Hu  })
992e877d8bfSXuan Hu
993*6683fc49SZhaoyang You  private val rwMask = 0xc00
994*6683fc49SZhaoyang You  private val csrOutMapFilter = csrOutMap.filter { case (id, _) => (id & rwMask) != rwMask }
995*6683fc49SZhaoyang You
996*6683fc49SZhaoyang You  private val regOut = Mux1H(csrOutMapFilter.map { case (id, regOut) =>
99794895e77SXuan Hu    if (vsMapS.contains(id)) {
99894895e77SXuan Hu      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
99994895e77SXuan Hu    } else if (sMapVS.contains(id)) {
100094895e77SXuan Hu      (!isModeVS && addr === id.U) -> regOut
100194895e77SXuan Hu    } else {
1002e877d8bfSXuan Hu      (raddr === id.U) -> regOut
100394895e77SXuan Hu    }
1004e877d8bfSXuan Hu  })
1005e877d8bfSXuan Hu
1006c2a2229dSlewislzh  private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
1007c2a2229dSlewislzh    trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
100801cdded8SXuan Hu
10093455ad08SXuan Hu  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
10103455ad08SXuan Hu
10112b1f9796SXuan Hu  private val noCSRIllegalReg = RegEnable(noCSRIllegal, ren || wen)
10122b1f9796SXuan Hu
10139d9b0bfaSjunxiong-ji  private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3)
1014e877d8bfSXuan Hu
10159d9b0bfaSjunxiong-ji  /** the state machine of newCSR module */
1016f7c21cb5SXuan Hu  private val state = RegInit(s_idle)
10179d9b0bfaSjunxiong-ji  /** the next state of newCSR */
1018f7c21cb5SXuan Hu  private val stateNext = WireInit(state)
1019f7c21cb5SXuan Hu  state := stateNext
1020f7c21cb5SXuan Hu
10219d9b0bfaSjunxiong-ji  /**
10225d6c8aecSZhaoyang You   * Asynchronous access operation of CSR. Check whether an access is asynchronous when read/write-enable is high.
10235d6c8aecSZhaoyang You   * AIA registers are designed to be access asynchronously, so newCSR will wait for response.
10249d9b0bfaSjunxiong-ji   **/
10255d6c8aecSZhaoyang You  private val asyncAccess = (wen || ren) && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && (
1026f7c21cb5SXuan Hu    mireg.addr.U === addr && miselect.inIMSICRange ||
1027d10d7061Slinzhida    sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) ||
1028f7c21cb5SXuan Hu    vsireg.addr.U === addr && vsiselect.inIMSICRange
1029f7c21cb5SXuan Hu  )
1030f7c21cb5SXuan Hu
10319d9b0bfaSjunxiong-ji  /** State machine of newCSR */
1032f7c21cb5SXuan Hu  switch(state) {
1033f7c21cb5SXuan Hu    is(s_idle) {
1034c559bb17SZhaoyang You      when(valid && redirectFlush) {
1035c559bb17SZhaoyang You        stateNext := s_idle
1036c559bb17SZhaoyang You      }.elsewhen(valid && asyncAccess) {
1037f7c21cb5SXuan Hu        stateNext := s_waitIMSIC
10387071df62SZhaoyang You      }.elsewhen(valid) {
10399d9b0bfaSjunxiong-ji        stateNext := s_finish
1040f7c21cb5SXuan Hu      }
1041f7c21cb5SXuan Hu    }
1042f7c21cb5SXuan Hu    is(s_waitIMSIC) {
1043c559bb17SZhaoyang You      when(redirectFlush) {
1044c559bb17SZhaoyang You        stateNext := s_idle
1045c559bb17SZhaoyang You      }.elsewhen(fromAIA.rdata.valid) {
10469d9b0bfaSjunxiong-ji        when(io.out.ready) {
10479d9b0bfaSjunxiong-ji          stateNext := s_idle
10489d9b0bfaSjunxiong-ji        }.otherwise {
10499d9b0bfaSjunxiong-ji          stateNext := s_finish
10509d9b0bfaSjunxiong-ji        }
10519d9b0bfaSjunxiong-ji      }
10529d9b0bfaSjunxiong-ji    }
10539d9b0bfaSjunxiong-ji    is(s_finish) {
1054c559bb17SZhaoyang You      when(redirectFlush || io.out.ready) {
1055f7c21cb5SXuan Hu        stateNext := s_idle
1056f7c21cb5SXuan Hu      }
1057f7c21cb5SXuan Hu    }
1058f7c21cb5SXuan Hu  }
1059f7c21cb5SXuan Hu
10609d9b0bfaSjunxiong-ji
1061f7c21cb5SXuan Hu  // Todo: check IMSIC EX_II and EX_VI
1062f7c21cb5SXuan Hu  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
1063f7c21cb5SXuan Hu  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
1064f7c21cb5SXuan Hu  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
1065f7c21cb5SXuan Hu
10669d9b0bfaSjunxiong-ji  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
10679d9b0bfaSjunxiong-ji  io.in.ready := (state === s_idle)
10689d9b0bfaSjunxiong-ji
10699d9b0bfaSjunxiong-ji  /**
10709d9b0bfaSjunxiong-ji   * Valid signal of newCSR output.
10719d9b0bfaSjunxiong-ji   * When in IDLE state, when input_valid is high, we set it.
10729d9b0bfaSjunxiong-ji   * When in waitIMSIC state, and the next state is IDLE, we set it.
10739d9b0bfaSjunxiong-ji   **/
1074e0bc5040Slewislzh
107544467224SZhaoyang You  /** Data that have been read before,and should be stored because output not fired */
1076bb94c7b4SZhaoyang You  val normalCSRValid = state === s_idle && valid && !asyncAccess
1077bb94c7b4SZhaoyang You  val waitIMSICValid = state === s_waitIMSIC && fromAIA.rdata.valid
1078bb94c7b4SZhaoyang You
1079c559bb17SZhaoyang You  io.out.valid := (waitIMSICValid || state === s_finish) && !redirectFlush
1080bb94c7b4SZhaoyang You  io.out.bits.EX_II := DataHoldBypass(Mux1H(Seq(
1081bb94c7b4SZhaoyang You    normalCSRValid -> (permitMod.io.out.EX_II || noCSRIllegal),
1082bb94c7b4SZhaoyang You    waitIMSICValid -> imsic_EX_II,
1083bb94c7b4SZhaoyang You  )), false.B, normalCSRValid || waitIMSICValid)
1084bb94c7b4SZhaoyang You  io.out.bits.EX_VI := DataHoldBypass(Mux1H(Seq(
1085bb94c7b4SZhaoyang You    normalCSRValid -> permitMod.io.out.EX_VI,
1086bb94c7b4SZhaoyang You    waitIMSICValid -> imsic_EX_VI,
1087bb94c7b4SZhaoyang You  )), false.B, normalCSRValid || waitIMSICValid)
10887071df62SZhaoyang You  io.out.bits.flushPipe := flushPipe
1089f7c21cb5SXuan Hu
10909d9b0bfaSjunxiong-ji  /** Prepare read data for output */
109144467224SZhaoyang You  io.out.bits.rData := DataHoldBypass(
109244467224SZhaoyang You    Mux1H(Seq(
109344467224SZhaoyang You      io.in.fire -> rdata,
109444467224SZhaoyang You      fromAIA.rdata.valid -> fromAIA.rdata.bits.data
109544467224SZhaoyang You    )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid)
1096f7c21cb5SXuan Hu  io.out.bits.regOut := regOut
1097f7c21cb5SXuan Hu  io.out.bits.targetPc := DataHoldBypass(
1098a7a6d0a6Schengguanghui    Mux(trapEntryDEvent.out.targetPc.valid,
1099a7a6d0a6Schengguanghui      trapEntryDEvent.out.targetPc.bits,
1100a7a6d0a6Schengguanghui      Mux1H(Seq(
1101c2a2229dSlewislzh        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
11021e7040baSsinceforYy        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
11031e7040baSsinceforYy        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
11041e7040baSsinceforYy        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
11051e7040baSsinceforYy        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
1106c2a2229dSlewislzh        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
11071e7040baSsinceforYy        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
1108a7a6d0a6Schengguanghui        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
1109a7a6d0a6Schengguanghui      )
1110a7a6d0a6Schengguanghui    ),
1111a7a6d0a6Schengguanghui  needTargetUpdate)
11122b20b832STang Haojin  io.out.bits.targetPcUpdate := needTargetUpdate
111344467224SZhaoyang You  io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire)
1114e877d8bfSXuan Hu
1115f7c21cb5SXuan Hu  io.status.privState := privState
1116f7c21cb5SXuan Hu  io.status.fpState.frm := fcsr.frm
1117f7c21cb5SXuan Hu  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
1118f7c21cb5SXuan Hu  io.status.vecState.vstart := vstart.rdata.asUInt
1119f7c21cb5SXuan Hu  io.status.vecState.vxsat := vcsr.vxsat
1120f7c21cb5SXuan Hu  io.status.vecState.vxrm := vcsr.vxrm
1121f7c21cb5SXuan Hu  io.status.vecState.vcsr := vcsr.rdata.asUInt
1122f7c21cb5SXuan Hu  io.status.vecState.vl := vl.rdata.asUInt
1123f7c21cb5SXuan Hu  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
1124f7c21cb5SXuan Hu  io.status.vecState.vlenb := vlenb.rdata.asUInt
1125f7c21cb5SXuan Hu  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
1126f7c21cb5SXuan Hu  io.status.interrupt := intrMod.io.out.interruptVec.valid
1127f7c21cb5SXuan Hu  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
1128f7c21cb5SXuan Hu  io.status.debugMode := debugMode
1129f7c21cb5SXuan Hu  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
11308419d406SXuan Hu
11318419d406SXuan Hu  /**
1132a7a6d0a6Schengguanghui   * debug_begin
1133a7a6d0a6Schengguanghui   */
113436fba821SGuanghui Cheng  val tdata1Selected = Wire(new Tdata1Bundle)
113536fba821SGuanghui Cheng  tdata1Selected := tdata1.rdata
113636fba821SGuanghui Cheng  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
113736fba821SGuanghui Cheng  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
113836fba821SGuanghui Cheng  val tdata1Update  = tdata1.w.wen && triggerCanWrite
113936fba821SGuanghui Cheng  val tdata2Update  = tdata2.w.wen && triggerCanWrite
11404ac3bf33Schengguanghui  val tdata1Vec = tdata1RegVec.map{ mod => {
1141a7a6d0a6Schengguanghui    val tdata1Wire = Wire(new Tdata1Bundle)
1142a7a6d0a6Schengguanghui    tdata1Wire := mod.rdata
1143a7a6d0a6Schengguanghui    tdata1Wire
1144a7a6d0a6Schengguanghui  }}
1145a7a6d0a6Schengguanghui
1146c08f49a0Schengguanghui  val triggerCanRaiseBpExp = !(privState.isModeM && !mstatus.regOut.MIE ||
1147c08f49a0Schengguanghui    medeleg.regOut.EX_BP && privState.isModeHS && !mstatus.sstatus.SIE ||
1148c08f49a0Schengguanghui    medeleg.regOut.EX_BP && hedeleg.regOut.EX_BP && privState.isModeVS && !vsstatus.regOut.SIE)
1149c08f49a0Schengguanghui
11504ac3bf33Schengguanghui  val debugMod = Module(new Debug)
11514ac3bf33Schengguanghui  debugMod.io.in.trapInfo.valid            := hasTrap
11524ac3bf33Schengguanghui  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
115322872cfdSsinceforYy  debugMod.io.in.trapInfo.bits.isDebugIntr := debug
11544ac3bf33Schengguanghui  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
11557e0f64b0SGuanghui Cheng  debugMod.io.in.trapInfo.bits.trigger     := trigger
11564ac3bf33Schengguanghui  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
1157a751b11aSchengguanghui  debugMod.io.in.trapInfo.bits.criticalErrorState := criticalErrorState
11584ac3bf33Schengguanghui  debugMod.io.in.privState                 := privState
11594ac3bf33Schengguanghui  debugMod.io.in.debugMode                 := debugMode
11604ac3bf33Schengguanghui  debugMod.io.in.dcsr                      := dcsr.regOut
11614ac3bf33Schengguanghui  debugMod.io.in.tselect                   := tselect.regOut
11624ac3bf33Schengguanghui  debugMod.io.in.tdata1Vec                 := tdata1Vec
11634ac3bf33Schengguanghui  debugMod.io.in.tdata1Selected            := tdata1.rdata
11644ac3bf33Schengguanghui  debugMod.io.in.tdata2Selected            := tdata2.rdata
11654ac3bf33Schengguanghui  debugMod.io.in.tdata1Update              := tdata1Update
11664ac3bf33Schengguanghui  debugMod.io.in.tdata2Update              := tdata2Update
116732fe4d47SsinceforYy  debugMod.io.in.tdata1Wdata               := wdata
1168c08f49a0Schengguanghui  debugMod.io.in.triggerCanRaiseBpExp      := triggerCanRaiseBpExp
1169a7a6d0a6Schengguanghui
117085a8d7caSZehao Liu  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
1171a75accccSchengguanghui
1172a75accccSchengguanghui  trapEntryDEvent.valid                           := entryDebugMode
11734ac3bf33Schengguanghui  trapEntryDEvent.in.hasDebugIntr                 := debugMod.io.out.hasDebugIntr
1174a7a6d0a6Schengguanghui  trapEntryDEvent.in.debugMode                    := debugMode
1175a7a6d0a6Schengguanghui  trapEntryDEvent.in.hasTrap                      := hasTrap
11764ac3bf33Schengguanghui  trapEntryDEvent.in.hasSingleStep                := debugMod.io.out.hasSingleStep
11777e0f64b0SGuanghui Cheng  trapEntryDEvent.in.triggerEnterDebugMode        := debugMod.io.out.triggerEnterDebugMode
11784ac3bf33Schengguanghui  trapEntryDEvent.in.hasDebugEbreakException      := debugMod.io.out.hasDebugEbreakException
11794ac3bf33Schengguanghui  trapEntryDEvent.in.breakPoint                   := debugMod.io.out.breakPoint
1180a751b11aSchengguanghui  trapEntryDEvent.in.criticalErrorStateEnterDebug := debugMod.io.out.criticalErrorStateEnterDebug
1181a7a6d0a6Schengguanghui
118239ec22f6SGuanghui Cheng  for(idx <- 0 until TriggerNum) {
118339ec22f6SGuanghui Cheng    val tdata1Pre = Wire(new Tdata1Bundle)
118439ec22f6SGuanghui Cheng    val mcontrol6Pre = Wire(new Mcontrol6)
118539ec22f6SGuanghui Cheng    tdata1Pre := (if (idx > 0) tdata1RegVec(idx - 1) else tdata1RegVec(idx)).rdata.asUInt
118639ec22f6SGuanghui Cheng    mcontrol6Pre := tdata1Pre.DATA.asUInt
118739ec22f6SGuanghui Cheng    val canWriteDmode = WireInit(false.B)
118839ec22f6SGuanghui Cheng    canWriteDmode := (if(idx > 0) (Mux(mcontrol6Pre.CHAIN.asBool, tdata1Pre.DMODE.asBool && tdata1Pre.TYPE.isLegal, true.B)) && debugMode else debugMode).asBool
118939ec22f6SGuanghui Cheng    tdata1RegVec(idx) match {
119039ec22f6SGuanghui Cheng      case m: HasTriggerBundle =>
119139ec22f6SGuanghui Cheng        m.canWriteDmode := canWriteDmode
11924ac3bf33Schengguanghui        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1193a7a6d0a6Schengguanghui      case _ =>
1194a7a6d0a6Schengguanghui    }
1195a7a6d0a6Schengguanghui  }
119639ec22f6SGuanghui Cheng
1197a7a6d0a6Schengguanghui  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1198a7a6d0a6Schengguanghui    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
119932fe4d47SsinceforYy    mod1.w.wdata  := wdata
1200a7a6d0a6Schengguanghui    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
120132fe4d47SsinceforYy    mod2.w.wdata  := wdata
12024ac3bf33Schengguanghui  }}
1203a7a6d0a6Schengguanghui
12044ac3bf33Schengguanghui  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1205a7a6d0a6Schengguanghui
12064ac3bf33Schengguanghui  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
12074ac3bf33Schengguanghui  io.status.memTrigger      := debugMod.io.out.memTrigger
1208a7a6d0a6Schengguanghui  /**
1209a7a6d0a6Schengguanghui   * debug_end
1210a7a6d0a6Schengguanghui   */
1211a7a6d0a6Schengguanghui
12124907ec88Schengguanghui  // trace
1213c308d936Schengguanghui  val privForTrace = Mux(debugMode,
12144907ec88Schengguanghui    Priv.D,
1215c308d936Schengguanghui    Mux1H(
1216c308d936Schengguanghui      Seq(privState.isModeM, privState.isModeHS, privState.isModeVS, privState.isModeHU, privState.isModeVU),
1217c308d936Schengguanghui      Seq(Priv.M,            Priv.HS,            Priv.VS,            Priv.HU,            Priv.VU)
12184907ec88Schengguanghui    )
1219c308d936Schengguanghui  )
1220c308d936Schengguanghui  val xret = legalDret || legalMNret || legalMret || legalSret
1221c308d936Schengguanghui  val currentPriv = privForTrace
1222c308d936Schengguanghui  val lastPriv = RegEnable(privForTrace, Priv.M, (xret || io.fromRob.trap.valid))
1223c308d936Schengguanghui
1224c308d936Schengguanghui  io.status.traceCSR.lastPriv       := lastPriv
1225c308d936Schengguanghui  io.status.traceCSR.currentPriv    := privForTrace
1226c308d936Schengguanghui  io.status.traceCSR.cause := Mux1H(
1227c308d936Schengguanghui    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1228c308d936Schengguanghui    Seq(mcause.rdata,      scause.rdata,       vscause.rdata)
1229c308d936Schengguanghui  )
1230c308d936Schengguanghui  io.status.traceCSR.tval  := Mux1H(
1231c308d936Schengguanghui    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1232c308d936Schengguanghui    Seq(mtval.rdata,       stval.rdata,        vstval.rdata)
1233c308d936Schengguanghui  )
12344907ec88Schengguanghui
1235a7a6d0a6Schengguanghui  /**
1236b51a1abdSchengguanghui   * perf_begin
1237e1a85e9fSchengguanghui   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1238b51a1abdSchengguanghui   */
1239b8e923e6Schengguanghui  val csrevents = mhpmevents.slice(24, 29).map(_.rdata)
1240b51a1abdSchengguanghui
1241e1a85e9fSchengguanghui  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1242b51a1abdSchengguanghui  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1243e1a85e9fSchengguanghui    hcEvents(i) := io.perf.perfEventsHc(i)
1244b51a1abdSchengguanghui  }
1245b51a1abdSchengguanghui
1246e1a85e9fSchengguanghui  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1247b51a1abdSchengguanghui  val allPerfEvents = io.perf.perfEventsFrontend ++
1248e1a85e9fSchengguanghui    io.perf.perfEventsBackend ++
1249b51a1abdSchengguanghui    io.perf.perfEventsLsu ++
1250b51a1abdSchengguanghui    hpmHc.getPerf
1251b51a1abdSchengguanghui
1252b8e923e6Schengguanghui  val countingEn        = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1253202093f4Schengguanghui  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1254202093f4Schengguanghui  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1255b8e923e6Schengguanghui
1256202093f4Schengguanghui  for(i <- 0 until perfCntNum) {
1257202093f4Schengguanghui    mhpmcounters(i) match {
1258b51a1abdSchengguanghui      case m: HasPerfCounterBundle =>
1259202093f4Schengguanghui        m.countingEn        := countingEn(i)
1260202093f4Schengguanghui        m.perf              := allPerfEvents(i)
1261202093f4Schengguanghui        ofFromPerfCntVec(i) := m.toMhpmeventOF
1262b51a1abdSchengguanghui      case _ =>
1263b51a1abdSchengguanghui    }
1264b8e923e6Schengguanghui
1265b8e923e6Schengguanghui    mhpmevents(i) match {
1266b8e923e6Schengguanghui      case m: HasOfFromPerfCntBundle =>
1267b8e923e6Schengguanghui        m.ofFromPerfCnt := ofFromPerfCntVec(i)
1268b8e923e6Schengguanghui      case _ =>
1269b8e923e6Schengguanghui    }
1270b8e923e6Schengguanghui
1271b8e923e6Schengguanghui    val mhpmevent = Wire(new MhpmeventBundle)
1272b8e923e6Schengguanghui    mhpmevent := mhpmevents(i).rdata
1273b8e923e6Schengguanghui    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevent.OF.asBool
1274b8e923e6Schengguanghui
1275b8e923e6Schengguanghui    countingEn(i) := (privState.isModeM && !mhpmevent.MINH) ||
1276b8e923e6Schengguanghui      (privState.isModeHS && !mhpmevent.SINH)  ||
1277b8e923e6Schengguanghui      (privState.isModeHU && !mhpmevent.UINH)  ||
1278b8e923e6Schengguanghui      (privState.isModeVS && !mhpmevent.VSINH) ||
1279b8e923e6Schengguanghui      (privState.isModeVU && !mhpmevent.VUINH)
1280202093f4Schengguanghui  }
1281202093f4Schengguanghui
1282202093f4Schengguanghui  val lcofiReq = lcofiReqVec.asUInt.orR
1283202093f4Schengguanghui  mip match {
1284202093f4Schengguanghui    case m: HasLocalInterruptReqBundle =>
1285202093f4Schengguanghui      m.lcofiReq := lcofiReq
1286202093f4Schengguanghui    case _ =>
1287b51a1abdSchengguanghui  }
1288b51a1abdSchengguanghui  /**
1289b51a1abdSchengguanghui   * perf_end
1290b51a1abdSchengguanghui   */
1291b51a1abdSchengguanghui
1292b51a1abdSchengguanghui  /**
1293f7c21cb5SXuan Hu   * [[io.status.custom]] connection
12948419d406SXuan Hu   */
1295881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1296881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1297881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1298881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1299881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1300881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1301881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1302881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1303881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1304881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1305881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l2_pf_recv_enable       := spfctl.regOut.L2_PF_RECV_ENABLE.asBool
1306881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l2_pf_pbop_enable       := spfctl.regOut.L2_PF_PBOP_ENABLE.asBool
1307881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l2_pf_vbop_enable       := spfctl.regOut.L2_PF_VBOP_ENABLE.asBool
1308881e32f5SZifei Zhang  io.status.custom.pf_ctrl.l2_pf_tp_enable         := spfctl.regOut.L2_PF_TP_ENABLE.asBool
13098419d406SXuan Hu
1310f7c21cb5SXuan Hu  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1311f7c21cb5SXuan Hu  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1312f7c21cb5SXuan Hu  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1313f7c21cb5SXuan Hu  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1314f7c21cb5SXuan Hu  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
13158419d406SXuan Hu
1316f7c21cb5SXuan Hu  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1317f7c21cb5SXuan Hu  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1318f7c21cb5SXuan Hu  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1319f7c21cb5SXuan Hu  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1320f7c21cb5SXuan Hu  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1321f7c21cb5SXuan Hu  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1322f7c21cb5SXuan Hu  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
13238419d406SXuan Hu
1324f7c21cb5SXuan Hu  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1325f7c21cb5SXuan Hu  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1326f7c21cb5SXuan Hu  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1327f7c21cb5SXuan Hu  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1328f7c21cb5SXuan Hu  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
132941d8d239Shappy-lx  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
133041d8d239Shappy-lx  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
13318419d406SXuan Hu
1332f7c21cb5SXuan Hu  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1333064c9c5aSGuanghui Cheng  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool && (!io.status.singleStepFlag) && !debugMode
1334007f6122SXuan Hu
1335b7a63495SNewPaulWalker  io.status.custom.power_down_enable := mcorepwr.regOut.POWER_DOWN_ENABLE.asBool
1336b7a63495SNewPaulWalker
1337b7a63495SNewPaulWalker  io.status.custom.flush_l2_enable := mflushpwr.regOut.FLUSH_L2_ENABLE.asBool
1338b7a63495SNewPaulWalker
1339c1b28b66STang Haojin  io.status.instrAddrTransType.bare := privState.isModeM ||
1340c1b28b66STang Haojin    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1341c1b28b66STang Haojin    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1342c1b28b66STang Haojin  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1343c1b28b66STang Haojin    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1344c1b28b66STang Haojin  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1345c1b28b66STang Haojin    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1346c1b28b66STang Haojin  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1347c1b28b66STang Haojin  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1348c1b28b66STang Haojin  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1349c1b28b66STang Haojin
1350df65a16aSZhaoyang You  private val csrAccess = wenLegalReg || RegNext(ren)
1351f7c21cb5SXuan Hu
1352f7c21cb5SXuan Hu  private val imsicAddrValid =
13536872cbe9SXuan Hu    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
13546872cbe9SXuan Hu    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
13556872cbe9SXuan Hu    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1356f7c21cb5SXuan Hu
1357f7c21cb5SXuan Hu  private val imsicAddr = Mux1H(Seq(
13586872cbe9SXuan Hu    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
13596872cbe9SXuan Hu    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
13606872cbe9SXuan Hu    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1361f7c21cb5SXuan Hu  ))
1362f7c21cb5SXuan Hu
1363f7c21cb5SXuan Hu  private val imsicAddrPrivState = Mux1H(Seq(
13646872cbe9SXuan Hu    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
13656872cbe9SXuan Hu    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
13666872cbe9SXuan Hu    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1367f7c21cb5SXuan Hu  ))
1368f7c21cb5SXuan Hu
1369f7c21cb5SXuan Hu  private val imsicWdataValid =
13706872cbe9SXuan Hu    mireg.w.wen  && miselect.inIMSICRange ||
13716872cbe9SXuan Hu    sireg.w.wen  && siselect.inIMSICRange ||
13726872cbe9SXuan Hu    vsireg.w.wen && vsiselect.inIMSICRange
1373f7c21cb5SXuan Hu
1374f7c21cb5SXuan Hu  toAIA.addr.valid     := imsicAddrValid
1375f7c21cb5SXuan Hu  toAIA.addr.bits.addr := imsicAddr
1376f7c21cb5SXuan Hu  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1377f7c21cb5SXuan Hu  toAIA.addr.bits.v    := imsicAddrPrivState.V
1378f7c21cb5SXuan Hu
1379f7c21cb5SXuan Hu  toAIA.wdata.valid := imsicWdataValid
13807071df62SZhaoyang You  toAIA.wdata.bits.op := RegNext(io.in.bits.op)
13817071df62SZhaoyang You  toAIA.wdata.bits.data := RegNext(io.in.bits.src)
13828aa89407SXuan Hu  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1383f7c21cb5SXuan Hu  toAIA.mClaim  := mtopei.w.wen
1384f7c21cb5SXuan Hu  toAIA.sClaim  := stopei.w.wen
1385f7c21cb5SXuan Hu  toAIA.vsClaim := vstopei.w.wen
138694c2cc17SsinceforYy
138794c2cc17SsinceforYy  // tlb
1388a32bbcbbSXuan Hu  io.tlb.satpASIDChanged  := GatedValidRegNext(satp.w.wen  && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1389a32bbcbbSXuan Hu  io.tlb.vsatpASIDChanged := GatedValidRegNext(vsatp.w.wen && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1390a32bbcbbSXuan Hu  io.tlb.hgatpVMIDChanged := GatedValidRegNext(hgatp.w.wen && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
13919a4a4f17SXuan Hu  io.tlb.satp := satp.rdata
1392c577d933SXuan Hu  io.tlb.vsatp := vsatp.rdata
1393c577d933SXuan Hu  io.tlb.hgatp := hgatp.rdata
13948882eb68SXin Tian  if (HasBitmapCheck) {
13958882eb68SXin Tian    io.tlb.mbmc := mbmc.get.rdata
13968882eb68SXin Tian  } else {
13978882eb68SXin Tian    io.tlb.mbmc := DontCare
13988882eb68SXin Tian  }
13998aa89407SXuan Hu  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
14008aa89407SXuan Hu  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
14018aa89407SXuan Hu  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
14028aa89407SXuan Hu  io.tlb.vsum := vsstatus.regOut.SUM.asBool
14038aa89407SXuan Hu  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1404c577d933SXuan Hu
140594c2cc17SsinceforYy  io.tlb.imode := PRVM.asUInt
1406c2a2229dSlewislzh  // when NMIE is zero, force to behave as MPRV is zero
1407e92e298cSXuan Hu  io.tlb.dmode := Mux(
1408c2a2229dSlewislzh    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1409e92e298cSXuan Hu    mstatus.regOut.MPP.asUInt,
1410e92e298cSXuan Hu    PRVM.asUInt
1411e92e298cSXuan Hu  )
1412e92e298cSXuan Hu  io.tlb.dvirt := Mux(
1413c2a2229dSlewislzh    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1414e92e298cSXuan Hu    mstatus.regOut.MPV.asUInt,
1415e92e298cSXuan Hu    V.asUInt
1416e92e298cSXuan Hu  )
141739db506bSXuan Hu  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
141839db506bSXuan Hu  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1419189833a1SHaoyuan Feng  io.tlb.pmm.mseccfg := RegNext(mseccfg.regOut.PMM.asUInt)
1420189833a1SHaoyuan Feng  io.tlb.pmm.menvcfg := RegNext(menvcfg.regOut.PMM.asUInt)
1421189833a1SHaoyuan Feng  io.tlb.pmm.henvcfg := RegNext(henvcfg.regOut.PMM.asUInt)
1422189833a1SHaoyuan Feng  io.tlb.pmm.hstatus := RegNext(hstatus.regOut.HUPMM.asUInt)
1423189833a1SHaoyuan Feng  io.tlb.pmm.senvcfg := RegNext(senvcfg.regOut.PMM.asUInt)
142494c2cc17SsinceforYy
142515ed99a7SXuan Hu  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
142615ed99a7SXuan Hu  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
142715ed99a7SXuan Hu  io.toDecode.illegalInst.sfencePart := isModeHU
142815ed99a7SXuan Hu  io.toDecode.virtualInst.sfencePart := isModeVU
142915ed99a7SXuan Hu  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
143015ed99a7SXuan Hu  io.toDecode.illegalInst.hfenceVVMA := isModeHU
143115ed99a7SXuan Hu  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1432e252fdaeSpeixiaokun  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
143315ed99a7SXuan Hu  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
14341e8ffa38SsinceforYy  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
14351e8ffa38SsinceforYy  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1436b50a88ecSXuan Hu  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1437b50a88ecSXuan Hu  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
14386520f4f4STang Haojin  io.toDecode.illegalInst.wrs_nto    := !isModeM && mstatus.regOut.TW
14396520f4f4STang Haojin  io.toDecode.virtualInst.wrs_nto    := privState.V && !mstatus.regOut.TW && hstatus.regOut.VTW
1440689f6b88SsinceforYy  io.toDecode.illegalInst.frm        := frmIsReserved
1441e9f7c490SXuan Hu  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1442e9f7c490SXuan Hu  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1443e9f7c490SXuan Hu  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1444e9f7c490SXuan Hu    isModeVS && !henvcfg.regOut.CBZE ||
1445e9f7c490SXuan Hu    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1446e9f7c490SXuan Hu  )
1447e9f7c490SXuan Hu  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1448e9f7c490SXuan Hu  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1449e9f7c490SXuan Hu    isModeVS && !henvcfg.regOut.CBCFE ||
1450e9f7c490SXuan Hu    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1451e9f7c490SXuan Hu  )
1452e9f7c490SXuan Hu  io.toDecode.illegalInst.cboI       :=
1453e9f7c490SXuan Hu    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1454e9f7c490SXuan Hu    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1455e9f7c490SXuan Hu  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1456e9f7c490SXuan Hu    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1457e9f7c490SXuan Hu    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1458e9f7c490SXuan Hu  )
1459e9f7c490SXuan Hu  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1460e9f7c490SXuan Hu    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1461e9f7c490SXuan Hu    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1462e9f7c490SXuan Hu    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1463e9f7c490SXuan Hu  )
146415ed99a7SXuan Hu
14652b1f9796SXuan Hu  io.distributedWenLegal := wenLegalReg && !noCSRIllegalReg
1466a751b11aSchengguanghui  io.status.criticalErrorState := criticalErrorState && !dcsr.regOut.CETRIG.asBool
1467676ddb73SXuan Hu
146885a8d7caSZehao Liu  val criticalErrors = Seq(
146985a8d7caSZehao Liu    ("csr_dbltrp_inMN", !mnstatus.regOut.NMIE && hasTrap && !entryDebugMode),
147085a8d7caSZehao Liu  )
1471a751b11aSchengguanghui  criticalErrorStateInCSR := criticalErrors.map(criticalError => criticalError._2).reduce(_ || _).asBool
147285a8d7caSZehao Liu  generateCriticalErrors()
147385a8d7caSZehao Liu
1474881eb731SXuan Hu  // Always instantiate basic difftest modules.
1475881eb731SXuan Hu  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1476e43bb916SXuan Hu    // Delay trap passed to difftest until VecExcpMod is not busy
1477e43bb916SXuan Hu    val pendingTrap = RegInit(false.B)
1478e43bb916SXuan Hu    when (hasTrap) {
1479e43bb916SXuan Hu      pendingTrap := true.B
1480e43bb916SXuan Hu    }.elsewhen (!io.fromVecExcpMod.busy) {
1481e43bb916SXuan Hu      pendingTrap := false.B
1482e43bb916SXuan Hu    }
1483e43bb916SXuan Hu
1484cb4fe84bSXuan Hu    val hartId = io.fromTop.hartId
1485e43bb916SXuan Hu    val trapValid = pendingTrap && !io.fromVecExcpMod.busy
14869205730dSsinceforYy    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1487881eb731SXuan Hu    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1488c2a2229dSlewislzh    val hasNMI = nmi && hasTrap
1489881eb731SXuan Hu    val interruptNO = Mux(interrupt, trapNO, 0.U)
1490881eb731SXuan Hu    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
14913ea4388cSHaoyuan Feng    val isSv39: Bool =
14923ea4388cSHaoyuan Feng      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
14933ea4388cSHaoyuan Feng      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
14943ea4388cSHaoyuan Feng    val isSv48: Bool =
14953ea4388cSHaoyuan Feng      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
14963ea4388cSHaoyuan Feng      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
14973ea4388cSHaoyuan Feng    val isBare = !isSv39 && !isSv48
14983ea4388cSHaoyuan Feng    val sv39PC = SignExt(trapPC.take(39), XLEN)
14993ea4388cSHaoyuan Feng    val sv48PC = SignExt(trapPC.take(48), XLEN)
15003ea4388cSHaoyuan Feng    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1501881eb731SXuan Hu    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
15023ea4388cSHaoyuan Feng    val exceptionPC = Mux1H(Seq(
15033ea4388cSHaoyuan Feng      isSv39 -> sv39PC,
15043ea4388cSHaoyuan Feng      isSv48 -> sv48PC,
15053ea4388cSHaoyuan Feng      isBare -> barePC,
15063ea4388cSHaoyuan Feng    ))
1507881eb731SXuan Hu
1508881eb731SXuan Hu    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1509881eb731SXuan Hu    diffArchEvent.coreid := hartId
1510881eb731SXuan Hu    diffArchEvent.valid := trapValid
1511e43bb916SXuan Hu    diffArchEvent.interrupt := RegEnable(interruptNO, hasTrap)
1512e43bb916SXuan Hu    diffArchEvent.exception := RegEnable(exceptionNO, hasTrap)
1513e43bb916SXuan Hu    diffArchEvent.exceptionPC := RegEnable(exceptionPC, hasTrap)
1514e43bb916SXuan Hu    diffArchEvent.hasNMI := RegEnable(hasNMI, hasTrap)
15158c0eee90SZhaoyang You    diffArchEvent.virtualInterruptIsHvictlInject := RegNext(virtualInterruptIsHvictlInject && hasTrap)
15161191982fSZhaoyang You    diffArchEvent.irToHS := RegEnable(irToHS, hasTrap)
15171191982fSZhaoyang You    diffArchEvent.irToVS := RegEnable(irToVS, hasTrap)
1518881eb731SXuan Hu    if (env.EnableDifftest) {
1519e43bb916SXuan Hu      diffArchEvent.exceptionInst := RegEnable(io.fromRob.trap.bits.instr, hasTrap)
1520881eb731SXuan Hu    }
1521881eb731SXuan Hu
152292f36649SZehao Liu    val diffCriticalErrorEvent = DifftestModule(new DiffCriticalErrorEvent, delay = 4, dontCare = true)
152392f36649SZehao Liu    diffCriticalErrorEvent.valid := io.status.criticalErrorState && trapValid
152492f36649SZehao Liu    diffCriticalErrorEvent.coreid := hartId
152592f36649SZehao Liu    diffCriticalErrorEvent.criticalError := io.status.criticalErrorState
152692f36649SZehao Liu
1527881eb731SXuan Hu    val diffCSRState = DifftestModule(new DiffCSRState)
1528881eb731SXuan Hu    diffCSRState.coreid         := hartId
1529881eb731SXuan Hu    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1530881eb731SXuan Hu    diffCSRState.mstatus        := mstatus.rdata.asUInt
1531881eb731SXuan Hu    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1532881eb731SXuan Hu    diffCSRState.mepc           := mepc.rdata.asUInt
1533881eb731SXuan Hu    diffCSRState.sepc           := sepc.rdata.asUInt
1534881eb731SXuan Hu    diffCSRState.mtval          := mtval.rdata.asUInt
1535881eb731SXuan Hu    diffCSRState.stval          := stval.rdata.asUInt
1536881eb731SXuan Hu    diffCSRState.mtvec          := mtvec.rdata.asUInt
1537881eb731SXuan Hu    diffCSRState.stvec          := stvec.rdata.asUInt
1538881eb731SXuan Hu    diffCSRState.mcause         := mcause.rdata.asUInt
1539881eb731SXuan Hu    diffCSRState.scause         := scause.rdata.asUInt
1540881eb731SXuan Hu    diffCSRState.satp           := satp.rdata.asUInt
1541f20002a0SZhaoyang You    diffCSRState.mip            := mip.rdata.asUInt
1542881eb731SXuan Hu    diffCSRState.mie            := mie.rdata.asUInt
1543881eb731SXuan Hu    diffCSRState.mscratch       := mscratch.rdata.asUInt
1544881eb731SXuan Hu    diffCSRState.sscratch       := sscratch.rdata.asUInt
1545881eb731SXuan Hu    diffCSRState.mideleg        := mideleg.rdata.asUInt
1546881eb731SXuan Hu    diffCSRState.medeleg        := medeleg.rdata.asUInt
1547881eb731SXuan Hu
1548881eb731SXuan Hu    val diffDebugMode = DifftestModule(new DiffDebugMode)
1549881eb731SXuan Hu    diffDebugMode.coreid    := hartId
1550881eb731SXuan Hu    diffDebugMode.debugMode := debugMode
1551881eb731SXuan Hu    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1552881eb731SXuan Hu    diffDebugMode.dpc       := dpc.rdata.asUInt
1553881eb731SXuan Hu    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1554881eb731SXuan Hu    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1555881eb731SXuan Hu
155684b30982SGuanghui Cheng    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
155784b30982SGuanghui Cheng    diffTriggerCSRState.coreid    := hartId
155884b30982SGuanghui Cheng    diffTriggerCSRState.tselect   := tselect.rdata
155984b30982SGuanghui Cheng    diffTriggerCSRState.tdata1    := tdata1.rdata
156084b30982SGuanghui Cheng    diffTriggerCSRState.tinfo     := tinfo.rdata
156184b30982SGuanghui Cheng
1562881eb731SXuan Hu    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1563881eb731SXuan Hu    diffVecCSRState.coreid := hartId
1564881eb731SXuan Hu    diffVecCSRState.vstart := vstart.rdata.asUInt
1565881eb731SXuan Hu    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1566881eb731SXuan Hu    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1567881eb731SXuan Hu    diffVecCSRState.vcsr := vcsr.rdata.asUInt
156853e1a9f5SXuan Hu    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1569881eb731SXuan Hu    diffVecCSRState.vtype := vtype.rdata.asUInt
1570881eb731SXuan Hu    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1571881eb731SXuan Hu
1572e4d0adc8Slinzhida    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1573e4d0adc8Slinzhida    diffFpCSRState.coreid := hartId
1574e4d0adc8Slinzhida    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1575e4d0adc8Slinzhida
1576881eb731SXuan Hu    val diffHCSRState = DifftestModule(new DiffHCSRState)
1577881eb731SXuan Hu    diffHCSRState.coreid      := hartId
1578881eb731SXuan Hu    diffHCSRState.virtMode    := privState.V.asBool
1579881eb731SXuan Hu    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1580881eb731SXuan Hu    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1581881eb731SXuan Hu    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1582881eb731SXuan Hu    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1583881eb731SXuan Hu    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1584881eb731SXuan Hu    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1585881eb731SXuan Hu    diffHCSRState.htval       := htval.rdata.asUInt
1586881eb731SXuan Hu    diffHCSRState.htinst      := htinst.rdata.asUInt
1587881eb731SXuan Hu    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1588881eb731SXuan Hu    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1589881eb731SXuan Hu    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1590881eb731SXuan Hu    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1591881eb731SXuan Hu    diffHCSRState.vscause     := vscause.rdata.asUInt
1592881eb731SXuan Hu    diffHCSRState.vstval      := vstval.rdata.asUInt
1593881eb731SXuan Hu    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1594881eb731SXuan Hu    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1595881eb731SXuan Hu
159674668295SsinceforYy    val platformIRPMeipChange = !platformIRP.MEIP &&  RegNext(platformIRP.MEIP) || platformIRP.MEIP && !RegNext(platformIRP.MEIP)
1597f20002a0SZhaoyang You    val platformIRPMtipChange = !platformIRP.MTIP &&  RegNext(platformIRP.MTIP) || platformIRP.MTIP && !RegNext(platformIRP.MTIP)
1598f20002a0SZhaoyang You    val platformIRPMsipChange = !platformIRP.MSIP &&  RegNext(platformIRP.MSIP) || platformIRP.MSIP && !RegNext(platformIRP.MSIP)
159974668295SsinceforYy    val platformIRPSeipChange = !platformIRP.SEIP &&  RegNext(platformIRP.SEIP) || platformIRP.SEIP && !RegNext(platformIRP.SEIP)
1600f20002a0SZhaoyang You    val platformIRPStipChange = !sstcIRGen.o.STIP &&  RegNext(sstcIRGen.o.STIP) || sstcIRGen.o.STIP && !RegNext(sstcIRGen.o.STIP)
1601f20002a0SZhaoyang You    val platformIRPVseipChange = !platformIRP.VSEIP &&  RegNext(platformIRP.VSEIP) ||
1602f20002a0SZhaoyang You                                  platformIRP.VSEIP && !RegNext(platformIRP.VSEIP) ||
1603f20002a0SZhaoyang You                                 !hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) &&  RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) ||
1604f20002a0SZhaoyang You                                  hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && !RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt))
1605f20002a0SZhaoyang You    val platformIRPVstipChange = !sstcIRGen.o.VSTIP && RegNext(sstcIRGen.o.VSTIP) || sstcIRGen.o.VSTIP && !RegNext(sstcIRGen.o.VSTIP)
160674668295SsinceforYy    val fromAIAMeipChange = !fromAIA.meip && RegNext(fromAIA.meip) || fromAIA.meip && !RegNext(fromAIA.meip)
160774668295SsinceforYy    val fromAIASeipChange = !fromAIA.seip && RegNext(fromAIA.seip) || fromAIA.seip && !RegNext(fromAIA.seip)
1608f20002a0SZhaoyang You    val lcofiReqChange = !lcofiReq && RegNext(lcofiReq) || lcofiReq && !RegNext(lcofiReq)
1609f20002a0SZhaoyang You
1610f20002a0SZhaoyang You    val diffNonRegInterruptPendingEvent = DifftestModule(new DiffNonRegInterruptPendingEvent)
1611f20002a0SZhaoyang You    diffNonRegInterruptPendingEvent.coreid           := hartId
1612a9115dabSsinceforYy    diffNonRegInterruptPendingEvent.valid            := (platformIRPMeipChange || platformIRPMtipChange || platformIRPMsipChange ||
1613f20002a0SZhaoyang You                                                        platformIRPSeipChange || platformIRPStipChange ||
1614f20002a0SZhaoyang You                                                        platformIRPVseipChange || platformIRPVstipChange ||
161574668295SsinceforYy                                                        fromAIAMeipChange || fromAIASeipChange ||
161669e67bbfSTang Haojin                                                        lcofiReqChange || RegNext(reset.asBool)) & !reset.asBool
161774668295SsinceforYy    diffNonRegInterruptPendingEvent.platformIRPMeip  := platformIRP.MEIP
1618f20002a0SZhaoyang You    diffNonRegInterruptPendingEvent.platformIRPMtip  := platformIRP.MTIP
1619f20002a0SZhaoyang You    diffNonRegInterruptPendingEvent.platformIRPMsip  := platformIRP.MSIP
162074668295SsinceforYy    diffNonRegInterruptPendingEvent.platformIRPSeip  := platformIRP.SEIP
1621f20002a0SZhaoyang You    diffNonRegInterruptPendingEvent.platformIRPStip  := sstcIRGen.o.STIP
1622f20002a0SZhaoyang You    diffNonRegInterruptPendingEvent.platformIRPVseip := platformIRP.VSEIP || hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)
1623f20002a0SZhaoyang You    diffNonRegInterruptPendingEvent.platformIRPVstip := sstcIRGen.o.VSTIP
162474668295SsinceforYy    diffNonRegInterruptPendingEvent.fromAIAMeip := fromAIA.meip
162574668295SsinceforYy    diffNonRegInterruptPendingEvent.fromAIASeip := fromAIA.seip
16269acb8f93SZhaoyang You    diffNonRegInterruptPendingEvent.localCounterOverflowInterruptReq  := mip.regOut.LCOFIP.asBool
1627f20002a0SZhaoyang You
162818d24ffbSsinceforYy    val diffMhpmeventOverflowEvent = DifftestModule(new DiffMhpmeventOverflowEvent)
162918d24ffbSsinceforYy    diffMhpmeventOverflowEvent.coreid := hartId
163018d24ffbSsinceforYy    diffMhpmeventOverflowEvent.valid  := Cat(mhpmevents.zipWithIndex.map{ case (event, i) =>
163118d24ffbSsinceforYy      !ofFromPerfCntVec(i) && RegNext(ofFromPerfCntVec(i)) || ofFromPerfCntVec(i) && !RegNext(ofFromPerfCntVec(i))
163218d24ffbSsinceforYy    }).orR
163318d24ffbSsinceforYy    diffMhpmeventOverflowEvent.mhpmeventOverflow := VecInit(mhpmevents.map(_.regOut.asInstanceOf[MhpmeventBundle].OF.asBool)).asUInt
163418d24ffbSsinceforYy
16356127035cSZhaoyang You    val mtopeiChange = RegNext(fromAIA.mtopei.asUInt) =/= fromAIA.mtopei.asUInt
16366127035cSZhaoyang You    val stopeiChange = RegNext(fromAIA.stopei.asUInt) =/= fromAIA.stopei.asUInt
16376127035cSZhaoyang You    val vstopeiChange = RegNext(hstatus.regOut.VGEIN.asUInt) =/= hstatus.regOut.VGEIN.asUInt
16386127035cSZhaoyang You    val hgeipChange = RegNext(fromAIA.vseip) =/= fromAIA.vseip
16396127035cSZhaoyang You
16409a35af65Slinzhida    val diffSyncAIAEvent = DifftestModule(new DiffSyncAIAEvent)
16419a35af65Slinzhida    diffSyncAIAEvent.coreid := hartId
16426127035cSZhaoyang You    diffSyncAIAEvent.valid := mtopeiChange || stopeiChange || vstopeiChange || hgeipChange
16439a35af65Slinzhida    diffSyncAIAEvent.mtopei := mtopei.rdata
16449a35af65Slinzhida    diffSyncAIAEvent.stopei := stopei.rdata
16459a35af65Slinzhida    diffSyncAIAEvent.vstopei := vstopei.rdata
16469a35af65Slinzhida    diffSyncAIAEvent.hgeip := hgeip.rdata
1647b7a63495SNewPaulWalker
1648b7a63495SNewPaulWalker    val diffCustomMflushpwr = DifftestModule(new DiffSyncCustomMflushpwrEvent)
1649b7a63495SNewPaulWalker    diffCustomMflushpwr.coreid := hartId
1650b7a63495SNewPaulWalker    diffCustomMflushpwr.valid := RegNext(io.fromTop.l2FlushDone) =/= io.fromTop.l2FlushDone
1651b7a63495SNewPaulWalker    diffCustomMflushpwr.l2FlushDone := io.fromTop.l2FlushDone
1652881eb731SXuan Hu  }
1653039cdc35SXuan Hu}
1654039cdc35SXuan Hu
16551d192ad8SXuan Hutrait IpIeAliasConnect {
16561d192ad8SXuan Hu  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
16571d192ad8SXuan Hu
1658039cdc35SXuan Hu  mip.fromMvip  := mvip.toMip
1659039cdc35SXuan Hu  mip.fromSip   := sip.toMip
16601d192ad8SXuan Hu  mip.fromVSip  := vsip.toMip
16611d192ad8SXuan Hu  mvip.fromMip  := mip.toMvip
16621d192ad8SXuan Hu  mvip.fromSip  := sip.toMvip
16631d192ad8SXuan Hu  mvip.fromVSip := vsip.toMvip
16641d192ad8SXuan Hu  hvip.fromMip  := mip.toHvip
16651d192ad8SXuan Hu  hvip.fromHip  := hip.toHvip
16661d192ad8SXuan Hu  hvip.fromVSip := vsip.toHvip
16671d192ad8SXuan Hu
16681d192ad8SXuan Hu  mie.fromHie  := hie.toMie
1669039cdc35SXuan Hu  mie.fromSie  := sie.toMie
16701d192ad8SXuan Hu  mie.fromVSie := vsie.toMie
16711d192ad8SXuan Hu  sie.fromVSie := vsie.toSie
1672039cdc35SXuan Hu}
1673039cdc35SXuan Hu
1674039cdc35SXuan Huobject NewCSRMain extends App {
1675039cdc35SXuan Hu  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1676039cdc35SXuan Hu    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1677039cdc35SXuan Hu
1678237d4cfdSXuan Hu  val defaultConfig = config.alterPartial({
1679237d4cfdSXuan Hu    // Get XSCoreParams and pass it to the "small module"
1680237d4cfdSXuan Hu    case XSCoreParamsKey => config(XSTileKey).head
1681237d4cfdSXuan Hu  })
1682237d4cfdSXuan Hu
1683039cdc35SXuan Hu  Generator.execute(
1684039cdc35SXuan Hu    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1685237d4cfdSXuan Hu    new NewCSR()(defaultConfig),
1686039cdc35SXuan Hu    firtoolOpts
1687039cdc35SXuan Hu  )
1688039cdc35SXuan Hu
1689039cdc35SXuan Hu  println("done")
1690039cdc35SXuan Hu}
1691