xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision c41f725a91c55e75c95c55b4bb0d2649f43e4c83)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import difftest._
6import freechips.rocketchip.rocket.CSRs
7import org.chipsalliance.cde.config.Parameters
8import top.{ArgParser, Generator}
9import utility._
10import utils.OptionWrapper
11import xiangshan.backend.fu.NewCSR.CSRBundles.{CSRCustomState, PrivState, RobCommitCSR}
12import xiangshan.backend.fu.NewCSR.CSRDefines._
13import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
14import xiangshan.backend.fu.NewCSR.CSREvents.{CSREvents, DretEventSinkBundle, EventUpdatePrivStateOutput, MNretEventSinkBundle, MretEventSinkBundle, SretEventSinkBundle, TargetPCBundle, TrapEntryDEventSinkBundle, TrapEntryEventInput, TrapEntryHSEventSinkBundle, TrapEntryMEventSinkBundle, TrapEntryMNEventSinkBundle, TrapEntryVSEventSinkBundle}
15import xiangshan.backend.fu.fpu.Bundles.Frm
16import xiangshan.backend.fu.util.CSRConst
17import xiangshan.backend.fu.vector.Bundles.{Vl, Vstart, Vxrm, Vxsat}
18import xiangshan.backend.fu.wrapper.CSRToDecode
19import xiangshan.backend.rob.RobPtr
20import xiangshan._
21import xiangshan.backend.fu.PerfCounterIO
22import xiangshan.ExceptionNO._
23import xiangshan.backend.trace._
24
25import scala.collection.immutable.SeqMap
26
27object CSRConfig {
28  final val GEILEN = 5 // m,s,5vs
29
30  final val ASIDLEN = 16 // the length of ASID of XS implementation
31
32  final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec
33
34  final val HIIDWidth = 12 // support Hvictl[27:16](IID)
35
36  final val VMIDLEN = 14 // the length of VMID of XS implementation
37
38  final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec
39
40  // the width of VGEIN
41  final val VGEINWidth = 6
42
43  final val VaddrMaxWidth = 48 + 2 // support Sv39/Sv48/Sv39x4/Sv48x4
44
45  final val InstWidth = 32
46
47  final val XLEN = 64 // Todo: use XSParams
48
49  final val VLEN = 128
50
51  // Since we need macro to compute the width of CSR field, the input of macro should be the value that can be computed
52  // at compile time. The log2Up function cannot be used as meta-programming function, so we use litral value here
53  // log2Up(128 + 1), hold 0~128
54  final val VlWidth = 8
55
56  final val PAddrWidth = 48
57
58  final val AddrWidthInPage = 12
59
60  final val PMPAddrWidth = 48
61
62  final val PMPOffBits = 2
63
64  final val PMPAddrBits = PMPAddrWidth - PMPOffBits
65
66  // perf
67  final val perfCntNum = 29       // in Spec
68
69  final val EXT_SSTC = true
70
71  final val EXT_DBLTRP = true
72
73  final val PPNLength = 44
74  // TODO: as current test not support clean mdt , we set mstatus->mdt = 0 to allow exception in m-mode
75  final val mdtInit = 0
76
77}
78
79class NewCSRInput(implicit p: Parameters) extends Bundle {
80  val wen = Bool()
81  val ren = Bool()
82  val op = UInt(2.W)
83  val addr = UInt(12.W)
84  val src = UInt(64.W)
85  val wdata = UInt(64.W)
86  val mnret = Input(Bool())
87  val mret = Input(Bool())
88  val sret = Input(Bool())
89  val dret = Input(Bool())
90  val redirectFlush = Input(Bool())
91}
92
93class NewCSROutput(implicit p: Parameters) extends Bundle {
94  val EX_II = Bool()
95  val EX_VI = Bool()
96  val flushPipe = Bool()
97  val rData = UInt(64.W)
98  val targetPcUpdate = Bool()
99  val targetPc = new TargetPCBundle
100  val regOut = UInt(64.W)
101  // perf
102  val isPerfCnt = Bool()
103}
104
105class NewCSR(implicit val p: Parameters) extends Module
106  with HasXSParameter
107  with MachineLevel
108  with SupervisorLevel
109  with HypervisorLevel
110  with VirtualSupervisorLevel
111  with Unprivileged
112  with CSRAIA
113  with HasExternalInterruptBundle
114  with HasNonMaskableIRPBundle
115  with CSREvents
116  with DebugLevel
117  with CSRCustom
118  with CSRPMP
119  with HasCriticalErrors
120  with IpIeAliasConnect
121{
122
123  import CSRConfig._
124
125  val io = IO(new Bundle {
126    val fromTop = Input(new Bundle {
127      val hartId = UInt(hartIdLen.W)
128      val clintTime = Input(ValidIO(UInt(64.W)))
129      val l2FlushDone = Input(Bool())
130      val criticalErrorState = Input(Bool())
131    })
132    val in = Flipped(DecoupledIO(new NewCSRInput))
133    val trapInst = Input(ValidIO(UInt(InstWidth.W)))
134    val fromMem = Input(new Bundle {
135      val excpVA  = UInt(XLEN.W)
136      val excpGPA = UInt(XLEN.W)
137      val excpIsForVSnonLeafPTE = Bool()
138    })
139    val fromRob = Input(new Bundle {
140      val trap = ValidIO(new Bundle {
141        val pc = UInt(VaddrMaxWidth.W)
142        val pcGPA = UInt(PAddrBitsMax.W)
143        val instr = UInt(InstWidth.W)
144        val trapVec = UInt(64.W)
145        val isFetchBkpt = Bool()
146        val singleStep = Bool()
147        val trigger = TriggerAction()
148        val crossPageIPFFix = Bool()
149        val isInterrupt = Bool()
150        val isHls = Bool()
151        val isFetchMalAddr = Bool()
152        val isForVSnonLeafPTE = Bool()
153      })
154      val commit = Input(new RobCommitCSR)
155      val robDeqPtr = Input(new RobPtr)
156    })
157
158    val fromVecExcpMod = Input(new Bundle {
159      val busy = Bool()
160    })
161
162    val perf = Input(new PerfCounterIO)
163
164    /** Output should be a DecoupledIO, since now CSR writing to integer register file might be blocked (by arbiter) */
165    val out = DecoupledIO(new NewCSROutput)
166    val status = Output(new Bundle {
167      val privState = new PrivState
168      val interrupt = Bool()
169      val wfiEvent = Bool()
170      // fp
171      val fpState = new Bundle {
172        val off = Bool()
173        val frm = Frm()
174      }
175      // vec
176      val vecState = new Bundle {
177        val vstart = Vstart()
178        val vxsat = Vxsat()
179        val vxrm = Vxrm()
180        val vcsr = UInt(XLEN.W)
181        val vl = Vl()
182        val vtype = UInt(XLEN.W)
183        val vlenb = UInt(XLEN.W)
184        val off = Bool()
185      }
186      // debug
187      val debugMode = Bool()
188      val singleStepFlag = Bool()
189      // trigger
190      val frontendTrigger = new FrontendTdataDistributeIO()
191      val memTrigger = new MemTdataDistributeIO()
192      // Instruction fetch address translation type
193      val instrAddrTransType = new AddrTransType
194      // trace
195      val traceCSR = Output(new TraceCSR)
196      // custom
197      val custom = new CSRCustomState
198      val criticalErrorState = Bool()
199    })
200    // tlb
201    val tlb = Output(new Bundle {
202      val satpASIDChanged = Bool()
203      val vsatpASIDChanged = Bool()
204      val hgatpVMIDChanged = Bool()
205      val satp = new SatpBundle
206      val vsatp = new SatpBundle
207      val hgatp = new HgatpBundle
208      val mxr = Bool()
209      val sum = Bool()
210      val vmxr = Bool()
211      val vsum = Bool()
212      val spvp = Bool()
213      val imode = UInt(2.W)
214      val dmode = UInt(2.W)
215      val dvirt = Bool()
216      val mPBMTE = Bool()
217      val hPBMTE = Bool()
218      val pmm = new Bundle {
219        val mseccfg = UInt(2.W)
220        val menvcfg = UInt(2.W)
221        val henvcfg = UInt(2.W)
222        val hstatus = UInt(2.W)
223        val senvcfg = UInt(2.W)
224      }
225    })
226
227    val toDecode = new CSRToDecode
228
229    val fetchMalTval = Input(UInt(XLEN.W))
230
231    val distributedWenLegal = Output(Bool())
232  })
233
234  val toAIA   = IO(Output(new CSRToAIABundle))
235  val fromAIA = IO(Flipped(Output(new AIAToCSRBundle)))
236
237  dontTouch(toAIA)
238  dontTouch(fromAIA)
239  dontTouch(io.fromTop.clintTime)
240
241  /* Alias of input valid/ready */
242  val valid = io.in.valid
243
244  /* Alias of input signals */
245  val wen   = io.in.bits.wen && valid
246  val addr  = io.in.bits.addr
247  val wdata = io.in.bits.wdata
248
249  val ren   = io.in.bits.ren && valid
250  val raddr = io.in.bits.addr
251
252  // flush
253  val redirectFlush = io.in.bits.redirectFlush
254
255  val hasTrap = io.fromRob.trap.valid
256  val trapVec = io.fromRob.trap.bits.trapVec
257  val trapPC = io.fromRob.trap.bits.pc
258  val trapPCGPA = io.fromRob.trap.bits.pcGPA
259  val trapIsInterrupt = io.fromRob.trap.bits.isInterrupt
260  val trapIsCrossPageIPF = io.fromRob.trap.bits.crossPageIPFFix
261  val trigger = io.fromRob.trap.bits.trigger
262  val singleStep = io.fromRob.trap.bits.singleStep
263  val trapIsHls = io.fromRob.trap.bits.isHls
264  val trapIsFetchMalAddr = io.fromRob.trap.bits.isFetchMalAddr
265  val trapIsFetchBkpt = io.fromRob.trap.bits.isFetchBkpt
266  val trapIsForVSnonLeafPTE = io.fromRob.trap.bits.isForVSnonLeafPTE
267
268  // debug_intrrupt
269  val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable
270  val debugIntr = platformIRP.debugIP && debugIntrEnable
271
272  // CSR Privilege State
273  val PRVM = RegInit(PrivMode(1, 0), PrivMode.M)
274  val V = RegInit(VirtMode(0), VirtMode.Off)
275  val debugMode = RegInit(false.B)
276  private val nextV = WireInit(VirtMode(0), VirtMode.Off)
277  V := nextV
278  // dcsr stopcount
279  val debugModeStopCountNext = debugMode && dcsr.regOut.STOPCOUNT
280  val debugModeStopTimeNext  = debugMode && dcsr.regOut.STOPTIME
281  val debugModeStopCount = RegNext(debugModeStopCountNext)
282  val unprivCountUpdate  = !debugModeStopCount && debugModeStopCountNext
283
284  val criticalErrorStateInCSR = Wire(Bool())
285  val criticalErrorState = RegEnable(true.B, false.B, io.fromTop.criticalErrorState || criticalErrorStateInCSR)
286
287  private val privState = Wire(new PrivState)
288  privState.PRVM := PRVM
289  privState.V := V
290
291  private val isModeM              = privState.isModeM
292  private val (isModeHS, isModeHU) = (privState.isModeHS, privState.isModeHU)
293  private val (isModeVS, isModeVU) = (privState.isModeVS, privState.isModeVU)
294
295  val permitMod = Module(new CSRPermitModule)
296  val sstcIRGen = Module(new SstcInterruptGen)
297  val commidIdMod = Module(new CommitIDModule(40))
298
299  val gitCommitSHA = WireInit(commidIdMod.io.commitID)
300  val gitDirty     = WireInit(commidIdMod.io.dirty)
301  dontTouch(gitCommitSHA)
302  dontTouch(gitDirty)
303
304  private val wenLegal = permitMod.io.out.hasLegalWen
305
306  val legalSret  = permitMod.io.out.hasLegalSret
307  val legalMret  = permitMod.io.out.hasLegalMret
308  val legalMNret = permitMod.io.out.hasLegalMNret
309  val legalDret  = permitMod.io.out.hasLegalDret
310
311  private val wenLegalReg = GatedValidRegNext(wenLegal)
312
313  var csrRwMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] =
314    machineLevelCSRMap ++
315    supervisorLevelCSRMap ++
316    hypervisorCSRMap ++
317    virtualSupervisorCSRMap ++
318    unprivilegedCSRMap ++
319    debugCSRMap ++
320    aiaCSRMap ++
321    customCSRMap ++
322    pmpCSRMap
323
324  val csrMods: Seq[CSRModule[_]] =
325    machineLevelCSRMods ++
326    supervisorLevelCSRMods ++
327    hypervisorCSRMods ++
328    virtualSupervisorCSRMods ++
329    unprivilegedCSRMods ++
330    debugCSRMods ++
331    aiaCSRMods ++
332    customCSRMods ++
333    pmpCSRMods
334
335  var csrOutMap: SeqMap[Int, UInt] =
336    machineLevelCSROutMap ++
337    supervisorLevelCSROutMap ++
338    hypervisorCSROutMap ++
339    virtualSupervisorCSROutMap ++
340    unprivilegedCSROutMap ++
341    debugCSROutMap ++
342    aiaCSROutMap ++
343    customCSROutMap ++
344    pmpCSROutMap
345
346  // interrupt
347  val nmip = RegInit(new NonMaskableIRPendingBundle, (new NonMaskableIRPendingBundle).init)
348  when(nonMaskableIRP.NMI_43) {
349    nmip.NMI_43 := true.B
350  }
351  when(nonMaskableIRP.NMI_31) {
352    nmip.NMI_31 := true.B
353  }
354
355  val intrMod = Module(new InterruptFilter)
356  intrMod.io.in.privState := privState
357  intrMod.io.in.mstatusMIE := mstatus.regOut.MIE.asBool
358  intrMod.io.in.sstatusSIE := mstatus.regOut.SIE.asBool
359  intrMod.io.in.vsstatusSIE := vsstatus.regOut.SIE.asBool
360  intrMod.io.in.mip := mip.rdataFields
361  intrMod.io.in.mie := mie.regOut
362  intrMod.io.in.mideleg := mideleg.regOut
363  intrMod.io.in.sip := sip.regOut
364  intrMod.io.in.sie := sie.regOut
365  intrMod.io.in.hip := hip.regOut
366  intrMod.io.in.hie := hie.regOut
367  intrMod.io.in.hideleg := hideleg.regOut
368  intrMod.io.in.vsip := vsip.regOut
369  intrMod.io.in.vsie := vsie.regOut
370  intrMod.io.in.hvictl := hvictl.regOut
371  intrMod.io.in.hstatus := hstatus.regOut
372  intrMod.io.in.mtopei := mtopei.regOut
373  intrMod.io.in.stopei := stopei.regOut
374  intrMod.io.in.vstopei := vstopei.regOut
375  intrMod.io.in.hviprio1 := hviprio1.regOut
376  intrMod.io.in.hviprio2 := hviprio2.regOut
377  intrMod.io.in.miprios := Cat(miregiprios.map(_.rdata).reverse)
378  intrMod.io.in.hsiprios := Cat(siregiprios.map(_.rdata).reverse)
379  intrMod.io.in.mnstatusNMIE := mnstatus.regOut.NMIE.asBool
380  intrMod.io.in.nmi := nmip.asUInt.orR
381  intrMod.io.in.nmiVec := nmip.asUInt
382  intrMod.io.in.debugMode := debugMode
383  intrMod.io.in.debugIntr := debugIntr
384  intrMod.io.in.dcsr      := dcsr.regOut
385  intrMod.io.in.platform.meip := platformIRP.MEIP
386  intrMod.io.in.platform.seip := platformIRP.SEIP
387  intrMod.io.in.fromAIA.meip := fromAIA.meip
388  intrMod.io.in.fromAIA.seip := fromAIA.seip
389
390  when(intrMod.io.out.nmi && intrMod.io.out.interruptVec.valid) {
391    nmip.NMI_31 := nmip.NMI_31 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_31)
392    nmip.NMI_43 := nmip.NMI_43 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_43)
393  }
394  val intrVec = RegEnable(intrMod.io.out.interruptVec.bits, 0.U, intrMod.io.out.interruptVec.valid)
395  val debug = RegEnable(intrMod.io.out.debug, false.B, intrMod.io.out.interruptVec.valid)
396  val nmi = RegEnable(intrMod.io.out.nmi, false.B, intrMod.io.out.interruptVec.valid)
397  val virtualInterruptIsHvictlInject = RegEnable(intrMod.io.out.virtualInterruptIsHvictlInject, false.B, intrMod.io.out.interruptVec.valid)
398  val irToHS = RegEnable(intrMod.io.out.irToHS, false.B, intrMod.io.out.interruptVec.valid)
399  val irToVS = RegEnable(intrMod.io.out.irToVS, false.B, intrMod.io.out.interruptVec.valid)
400
401  val trapHandleMod = Module(new TrapHandleModule)
402
403  trapHandleMod.io.in.trapInfo.valid := hasTrap
404  trapHandleMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt
405  trapHandleMod.io.in.trapInfo.bits.nmi := nmi
406  trapHandleMod.io.in.trapInfo.bits.intrVec := intrVec
407  trapHandleMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
408  trapHandleMod.io.in.trapInfo.bits.irToHS := irToHS
409  trapHandleMod.io.in.trapInfo.bits.irToVS := irToVS
410  trapHandleMod.io.in.privState := privState
411  trapHandleMod.io.in.mstatus  := mstatus.regOut
412  trapHandleMod.io.in.vsstatus := vsstatus.regOut
413  trapHandleMod.io.in.mnstatus := mnstatus.regOut
414  trapHandleMod.io.in.mideleg  := mideleg.regOut
415  trapHandleMod.io.in.medeleg  := medeleg.regOut
416  trapHandleMod.io.in.hideleg  := hideleg.regOut
417  trapHandleMod.io.in.hedeleg  := hedeleg.regOut
418  trapHandleMod.io.in.mvien := mvien.regOut
419  trapHandleMod.io.in.hvien := hvien.regOut
420  trapHandleMod.io.in.mtvec := mtvec.regOut
421  trapHandleMod.io.in.stvec := stvec.regOut
422  trapHandleMod.io.in.vstvec := vstvec.regOut
423  trapHandleMod.io.in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
424  trapHandleMod.io.in.trapInfo.bits.singleStep  := hasTrap && !trapIsInterrupt && singleStep
425
426  val entryPrivState = trapHandleMod.io.out.entryPrivState
427  val entryDebugMode = WireInit(false.B)
428  val dbltrpToMN     = trapHandleMod.io.out.dbltrpToMN
429  val hasDTExcp      = trapHandleMod.io.out.hasDTExcp
430
431  // PMP
432  val pmpEntryMod = Module(new PMPEntryHandleModule)
433  pmpEntryMod.io.in.pmpCfg  := cfgs.map(_.regOut.asInstanceOf[PMPCfgBundle])
434  pmpEntryMod.io.in.pmpAddr := pmpaddr.map(_.regOut.asInstanceOf[PMPAddrBundle])
435  pmpEntryMod.io.in.ren   := ren
436  pmpEntryMod.io.in.wen   := wenLegalReg
437  pmpEntryMod.io.in.addr  := addr
438  pmpEntryMod.io.in.wdata := wdata
439
440  // Todo: all wen and wdata of CSRModule assigned in this for loop
441  for ((id, (wBundle, _)) <- csrRwMap) {
442    if (vsMapS.contains(id)) {
443      // VS access CSR by S: privState.isModeVS && addrMappedToVS === sMapVS(id).U
444      wBundle.wen := wenLegalReg && ((isModeVS && addr === vsMapS(id).U) || (!isModeVS && addr === id.U))
445      wBundle.wdata := wdata
446    } else if (sMapVS.contains(id)) {
447      wBundle.wen := wenLegalReg && !isModeVS && addr === id.U
448      wBundle.wdata := wdata
449    } else {
450      wBundle.wen := wenLegalReg && addr === id.U
451      wBundle.wdata := wdata
452    }
453  }
454
455  private val writeFpLegal  = permitMod.io.out.hasLegalWriteFcsr
456  private val writeVecLegal = permitMod.io.out.hasLegalWriteVcsr
457
458  permitMod.io.in.csrAccess.ren := ren && valid
459  permitMod.io.in.csrAccess.wen := wen
460  permitMod.io.in.csrAccess.addr := addr
461
462  permitMod.io.in.privState := privState
463  permitMod.io.in.debugMode := debugMode
464
465  permitMod.io.in.xRet.mnret := io.in.bits.mnret && valid
466  permitMod.io.in.xRet.mret  := io.in.bits.mret  && valid
467  permitMod.io.in.xRet.sret  := io.in.bits.sret  && valid
468  permitMod.io.in.xRet.dret  := io.in.bits.dret  && valid
469
470  permitMod.io.in.status.tsr := mstatus.regOut.TSR.asBool
471  permitMod.io.in.status.vtsr := hstatus.regOut.VTSR.asBool
472
473  permitMod.io.in.status.tvm  := mstatus.regOut.TVM.asBool
474  permitMod.io.in.status.vtvm := hstatus.regOut.VTVM.asBool
475
476  permitMod.io.in.status.vgein := hstatus.regOut.VGEIN.asUInt
477
478  permitMod.io.in.xcounteren.mcounteren := mcounteren.rdata
479  permitMod.io.in.xcounteren.hcounteren := hcounteren.rdata
480  permitMod.io.in.xcounteren.scounteren := scounteren.rdata
481
482  permitMod.io.in.xstateen.mstateen0 := mstateen0.rdata
483  permitMod.io.in.xstateen.hstateen0 := hstateen0.rdata
484  permitMod.io.in.xstateen.sstateen0 := sstateen0.rdata
485
486  permitMod.io.in.xenvcfg.menvcfg := menvcfg.rdata
487  permitMod.io.in.xenvcfg.henvcfg := henvcfg.rdata
488
489  permitMod.io.in.status.mstatusFSOff  :=  mstatus.regOut.FS === ContextStatus.Off
490  permitMod.io.in.status.mstatusVSOff  :=  mstatus.regOut.VS === ContextStatus.Off
491  permitMod.io.in.status.vsstatusFSOff := vsstatus.regOut.FS === ContextStatus.Off
492  permitMod.io.in.status.vsstatusVSOff := vsstatus.regOut.VS === ContextStatus.Off
493
494  permitMod.io.in.aia.miselectIsIllegal  := miselect.isIllegal
495  permitMod.io.in.aia.siselectIsIllegal  := siselect.isIllegal
496  permitMod.io.in.aia.vsiselectIsIllegal := vsiselect.isIllegal
497  permitMod.io.in.aia.siselect := siselect.rdata
498  permitMod.io.in.aia.vsiselect := vsiselect.rdata
499  permitMod.io.in.aia.mvienSEIE := mvien.regOut.SEIE.asBool
500  permitMod.io.in.aia.hvictlVTI := hvictl.regOut.VTI.asBool
501
502  sstcIRGen.i.stime.valid := time.updated
503  sstcIRGen.i.stime.bits  := time.stime
504  sstcIRGen.i.vstime.valid := time.updated
505  sstcIRGen.i.vstime.bits  := time.vstime
506  sstcIRGen.i.stimecmp.wen := GatedValidRegNext(stimecmp.w.wen)
507  sstcIRGen.i.stimecmp.rdata  := stimecmp.rdata
508  sstcIRGen.i.vstimecmp.wen   := GatedValidRegNext(vstimecmp.w.wen)
509  sstcIRGen.i.vstimecmp.rdata := vstimecmp.rdata
510  sstcIRGen.i.menvcfg.wen   := GatedValidRegNext(menvcfg.w.wen)
511  sstcIRGen.i.menvcfg.STCE  := menvcfg.regOut.STCE.asBool
512  sstcIRGen.i.henvcfg.wen   := GatedValidRegNext(henvcfg.w.wen)
513  sstcIRGen.i.henvcfg.STCE  := henvcfg.regOut.STCE.asBool
514  sstcIRGen.i.htimedeltaWen := GatedValidRegNext(htimedelta.w.wen)
515
516  miregiprios.foreach { mod =>
517    mod.w.wen := mireg.w.wen && (miselect.regOut.ALL.asUInt === mod.addr.U)
518    mod.w.wdata := wdata
519  }
520
521  siregiprios.foreach { mod =>
522    mod.w.wen := sireg.w.wen && (siselect.regOut.ALL.asUInt === mod.addr.U)
523    mod.w.wdata := wdata
524  }
525
526  iregiprios.foreach { mod =>
527    mod match {
528      case m: HasIeBundle =>
529        m.mie := mie.regOut
530        m.sie := sie.regOut
531      case _ =>
532    }
533  }
534
535  mhartid.hartid := this.io.fromTop.hartId
536
537  cfgs.zipWithIndex.foreach { case (mod, i) =>
538    mod.w.wen := wenLegalReg && (addr === (0x3A0 + i / 8 * 2).U)
539    mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8))
540  }
541
542  pmpaddr.zipWithIndex.foreach{ case(mod, i) =>
543    mod.w.wen := wenLegalReg && (addr === (0x3B0 + i).U)
544    mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i)
545  }
546
547  csrMods.foreach { mod =>
548    mod match {
549      case m: HypervisorBundle =>
550        m.hstatus := hstatus.regOut
551      case _ =>
552    }
553    mod match {
554      case m: VirtualSupervisorBundle =>
555        m.v := V.asUInt.asBool
556        m.hgatp := hgatp.regOut
557      case _ =>
558    }
559    mod match {
560      case m: HasMachineDelegBundle =>
561        m.mideleg := mideleg.regOut
562        m.medeleg := medeleg.regOut
563      case _ =>
564    }
565    mod match {
566      case m: HasMachineCounterControlBundle =>
567        m.mcountinhibit := mcountinhibit.regOut
568      case _ =>
569    }
570    mod match {
571      case m: HasExternalInterruptBundle =>
572        m.platformIRP := this.platformIRP
573        m.platformIRP.STIP  := sstcIRGen.o.STIP
574        m.platformIRP.VSTIP := sstcIRGen.o.VSTIP
575      case _ =>
576    }
577    mod match {
578      case m: HasRobCommitBundle =>
579        // Todo: move RegNext from ROB to CSR
580        m.robCommit.instNum := io.fromRob.commit.instNum
581        m.robCommit.fflags  := RegNextWithEnable(io.fromRob.commit.fflags)
582        m.robCommit.fsDirty := GatedValidRegNext(io.fromRob.commit.fsDirty)
583        m.robCommit.vsDirty := GatedValidRegNext(io.fromRob.commit.vsDirty)
584        m.robCommit.vxsat   := RegNextWithEnable(io.fromRob.commit.vxsat)
585        m.robCommit.vtype   := RegNextWithEnable(io.fromRob.commit.vtype)
586        m.robCommit.vl      := RegNext          (io.fromRob.commit.vl)
587        m.robCommit.vstart  := RegNextWithEnable(io.fromRob.commit.vstart)
588        m.writeFCSR         := writeFpLegal
589        m.writeVCSR         := writeVecLegal
590        m.isVirtMode        := V.asUInt.asBool
591      case _ =>
592    }
593    mod match {
594      case m: TrapEntryDEventSinkBundle =>
595        m.trapToD := trapEntryDEvent.out
596      case _ =>
597    }
598    mod match {
599      case m: TrapEntryMEventSinkBundle =>
600        m.trapToM := trapEntryMEvent.out
601      case _ =>
602    }
603    mod match {
604      case m: TrapEntryMNEventSinkBundle =>
605        m.trapToMN := trapEntryMNEvent.out
606      case _ =>
607    }
608    mod match {
609      case m: TrapEntryHSEventSinkBundle =>
610        m.trapToHS := trapEntryHSEvent.out
611      case _ =>
612    }
613    mod match {
614      case m: TrapEntryVSEventSinkBundle =>
615        m.trapToVS := trapEntryVSEvent.out
616      case _ =>
617    }
618    mod match {
619      case m: MretEventSinkBundle =>
620        m.retFromM := mretEvent.out
621      case _ =>
622    }
623    mod match {
624      case m: MNretEventSinkBundle =>
625        m.retFromMN := mnretEvent.out
626      case _ =>
627    }
628    mod match {
629      case m: SretEventSinkBundle =>
630        m.retFromS := sretEvent.out
631      case _ =>
632    }
633    mod match {
634      case m: DretEventSinkBundle =>
635        m.retFromD := dretEvent.out
636      case _ =>
637    }
638    mod match {
639      case m: HasAIABundle =>
640        m.aiaToCSR.rdata.valid := fromAIA.rdata.valid
641        m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data
642        m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal
643        m.aiaToCSR.meip    := fromAIA.meip
644        m.aiaToCSR.seip    := fromAIA.seip
645        m.aiaToCSR.vseip   := fromAIA.vseip
646        m.aiaToCSR.mtopei  := fromAIA.mtopei
647        m.aiaToCSR.stopei  := fromAIA.stopei
648        m.aiaToCSR.vstopei := fromAIA.vstopei
649      case _ =>
650    }
651    mod match {
652      case m: HasInterruptFilterSink =>
653        m.topIR.mtopi  := intrMod.io.out.mtopi
654        m.topIR.stopi  := intrMod.io.out.stopi
655        m.topIR.vstopi := intrMod.io.out.vstopi
656      case _ =>
657    }
658    mod match {
659      case m: HasPMPAddrSink =>
660        m.addrRData := pmpEntryMod.io.out.pmpAddrRData
661      case _ =>
662    }
663    mod match {
664      case m: HasMHPMSink =>
665        // cycle from mcycle
666        m.mHPM.cycle := mcycle.rdata
667        // time from clint
668        m.mHPM.time  := io.fromTop.clintTime
669        // instret from minstret
670        m.mHPM.instret := minstret.rdata
671        // VS-Mode or VU-Mode
672        m.v := privState.isVirtual
673        m.nextV := nextV.isOneOf(VirtMode.On)
674        m.htimedelta := htimedelta.rdata
675        m.mHPM.hpmcounters.zip(mhpmcounters).map{
676          case(counter, mcounter) => counter := mcounter.rdata
677        }
678      case _ =>
679    }
680    mod match {
681      case m: HasMachineEnvBundle =>
682        m.menvcfg := menvcfg.regOut
683      case _ =>
684    }
685    mod match {
686      case m: HasHypervisorEnvBundle =>
687        m.menvcfg := menvcfg.regOut
688      case _ =>
689    }
690    mod match {
691      case m: HasVirtualSupervisorEnvBundle =>
692        m.henvcfg := henvcfg.regOut
693        m.menvcfg := menvcfg.regOut
694      case _ =>
695    }
696    mod match {
697      case m: HasIpIeBundle =>
698        m.mideleg := mideleg.regOut
699        m.mip := mip.rdata
700        m.mie := mie.regOut
701        m.mvip := mvip.regOut
702        m.mvien := mvien.regOut
703        m.hideleg := hideleg.regOut
704        m.hip := hip.regOut
705        m.hie := hie.regOut
706        m.hvien := hvien.regOut
707        m.hvip := hvip.regOut
708        m.sip := sip.regOut
709        m.sie := sie.regOut
710        m.vsip := vsip.regOut
711        m.vsie := vsie.regOut
712        m.hgeip := hgeip.regOut
713        m.hgeie := hgeie.regOut
714        m.hstatusVGEIN := hstatus.regOut.VGEIN
715      case _ =>
716    }
717    mod match {
718      case m: HasMhpmeventOfBundle =>
719        m.ofVec := VecInit(mhpmevents.map{ event =>
720          val mhpmevent = Wire(new MhpmeventBundle)
721          mhpmevent := event.rdata
722          mhpmevent.OF.asBool
723        }).asUInt
724        m.privState := privState
725        m.mcounteren := mcounteren.rdata
726        m.hcounteren := hcounteren.rdata
727      case _ =>
728    }
729    mod match {
730      case m: HasStateen0Bundle =>
731        m.fromMstateen0 := mstateen0.regOut
732        m.fromHstateen0 := hstateen0.regOut
733        m.privState     := privState
734      case _ =>
735    }
736    mod match {
737      case m: HasDebugStopBundle =>
738        m.debugModeStopCount := debugModeStopCount
739        m.debugModeStopTime  := debugModeStopTimeNext
740        m.unprivCountUpdate  := unprivCountUpdate
741      case _ =>
742    }
743    mod match {
744      case m: HasNmipBundle =>
745        m.nmip := nmip.asUInt.orR
746      case _ =>
747    }
748    mod match {
749      case m: HasMachineFlushL2Bundle =>
750        m.l2FlushDone := io.fromTop.l2FlushDone
751      case _ =>
752    }
753  }
754
755  csrMods.foreach { mod =>
756    println(s"${mod.modName}: ")
757    println(mod.dumpFields)
758  }
759
760  trapEntryMNEvent.valid  := ((hasTrap && nmi) || dbltrpToMN) && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
761  trapEntryMEvent .valid  := hasTrap && entryPrivState.isModeM && !dbltrpToMN && !entryDebugMode && !debugMode && !nmi && mnstatus.regOut.NMIE
762  trapEntryHSEvent.valid  := hasTrap && entryPrivState.isModeHS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
763  trapEntryVSEvent.valid  := hasTrap && entryPrivState.isModeVS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
764
765  Seq(trapEntryMEvent, trapEntryMNEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod =>
766    eMod.in match {
767      case in: TrapEntryEventInput =>
768        in.causeNO := trapHandleMod.io.out.causeNO
769        in.trapPc := trapPC
770        in.trapPcGPA := trapPCGPA // only used by trapEntryMEvent & trapEntryHSEvent
771        in.trapInst := io.trapInst
772        in.fetchMalTval := io.fetchMalTval
773        in.isCrossPageIPF := trapIsCrossPageIPF
774        in.isHls := trapIsHls
775        in.isFetchMalAddr := trapIsFetchMalAddr
776        in.isFetchBkpt := trapIsFetchBkpt
777        in.trapIsForVSnonLeafPTE := trapIsForVSnonLeafPTE
778        in.hasDTExcp := hasDTExcp
779
780        in.iMode.PRVM := PRVM
781        in.iMode.V := V
782        // when NMIE is zero, force to behave as MPRV is zero
783        in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool && mnstatus.regOut.NMIE.asBool, mstatus.regOut.MPP, PRVM)
784        in.dMode.V := V.asUInt.asBool || mstatus.regOut.MPRV && mnstatus.regOut.NMIE.asBool && (mstatus.regOut.MPP =/= PrivMode.M) && mstatus.regOut.MPV
785
786        in.privState := privState
787        in.mstatus := mstatus.regOut
788        in.hstatus := hstatus.regOut
789        in.sstatus := mstatus.sstatus
790        in.vsstatus := vsstatus.regOut
791        in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec
792
793        in.menvcfg := menvcfg.regOut
794        in.henvcfg := henvcfg.regOut
795
796        in.satp  := satp.regOut
797        in.vsatp := vsatp.regOut
798        in.hgatp := hgatp.regOut
799
800        in.memExceptionVAddr := io.fromMem.excpVA
801        in.memExceptionGPAddr := io.fromMem.excpGPA
802        in.memExceptionIsForVSnonLeafPTE := io.fromMem.excpIsForVSnonLeafPTE
803
804        in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
805        in.hvictlIID := hvictl.regOut.IID.asUInt
806    }
807  }
808
809  mnretEvent.valid := legalMNret
810  mnretEvent.in match {
811    case in =>
812      in.mstatus := mstatus.regOut
813      in.vsstatus := vsstatus.regOut
814      in.mnepc   := mnepc.regOut
815      in.mnstatus:= mnstatus.regOut
816      in.satp := satp.regOut
817      in.vsatp := vsatp.regOut
818      in.hgatp := hgatp.regOut
819  }
820
821  mretEvent.valid := legalMret
822  mretEvent.in match {
823    case in =>
824      in.mstatus := mstatus.regOut
825      in.vsstatus := vsstatus.regOut
826      in.mepc := mepc.regOut
827      in.satp := satp.regOut
828      in.vsatp := vsatp.regOut
829      in.hgatp := hgatp.regOut
830  }
831
832  sretEvent.valid := legalSret
833  sretEvent.in match {
834    case in =>
835      in.privState := privState
836      in.mstatus := mstatus.regOut
837      in.hstatus := hstatus.regOut
838      in.vsstatus := vsstatus.regOut
839      in.sepc := sepc.regOut
840      in.vsepc := vsepc.regOut
841      in.satp := satp.regOut
842      in.vsatp := vsatp.regOut
843      in.hgatp := hgatp.regOut
844  }
845
846  dretEvent.valid := legalDret
847  dretEvent.in match {
848    case in =>
849      in.dcsr := dcsr.regOut
850      in.dpc  := dpc.regOut
851      in.mstatus := mstatus.regOut
852      in.vsstatus := vsstatus.regOut
853      in.satp := satp.regOut
854      in.vsatp := vsatp.regOut
855      in.hgatp := hgatp.regOut
856  }
857
858  PRVM := MuxCase(
859    PRVM,
860    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
861      x => x.out match {
862        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
863      }
864    }
865  )
866
867  nextV := MuxCase(
868    V,
869    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
870      x => x.out match {
871        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
872      }
873    }
874  )
875
876  debugMode := MuxCase(
877    debugMode,
878    Seq(
879      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits,
880      trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits
881    )
882  )
883
884  debugIntrEnable := MuxCase(
885    debugIntrEnable,
886    Seq(
887      dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits,
888      trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits
889    )
890  )
891
892  // perf
893  val addrInPerfCnt = (wenLegal || ren) && (
894    (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
895    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U)
896  )
897
898  // flush
899  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegalReg // write to satp will cause the pipeline be flushed
900
901  val floatStatusOnOff = mstatus.w.wen && (
902    mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
903    mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
904  ) || mstatus.wAliasSstatus.wen && (
905    mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
906    mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
907  ) || vsstatus.w.wen && (
908    vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off ||
909    vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off
910  )
911
912  val vectorStatusOnOff = mstatus.w.wen && (
913    mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
914    mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
915  ) || mstatus.wAliasSstatus.wen && (
916    mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
917    mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
918  ) || vsstatus.w.wen && (
919    vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off ||
920    vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off
921  )
922
923  val triggerFrontendChange = Wire(Bool())
924
925  val vstartChange = vstart.w.wen && (
926    vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U ||
927    vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U
928  )
929
930  // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved
931  val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR
932  val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR
933  val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR
934  val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) ||
935    fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved)
936
937  val flushPipe = resetSatp ||
938    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
939    vstartChange || frmChange
940
941  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
942    if (vsMapS.contains(id)) {
943      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
944    } else if (sMapVS.contains(id)) {
945      (!isModeVS && addr === id.U) -> rdata
946    } else {
947      (raddr === id.U) -> rdata
948    }
949  })
950
951  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
952    if (vsMapS.contains(id)) {
953      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
954    } else if (sMapVS.contains(id)) {
955      (!isModeVS && addr === id.U) -> regOut
956    } else {
957      (raddr === id.U) -> regOut
958    }
959  })
960
961  private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
962    trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
963
964  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
965
966  private val noCSRIllegalReg = RegEnable(noCSRIllegal, ren || wen)
967
968  private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3)
969
970  /** the state machine of newCSR module */
971  private val state = RegInit(s_idle)
972  /** the next state of newCSR */
973  private val stateNext = WireInit(state)
974  state := stateNext
975
976  /**
977   * Asynchronous access operation of CSR. Check whether an access is asynchronous when read/write-enable is high.
978   * AIA registers are designed to be access asynchronously, so newCSR will wait for response.
979   **/
980  private val asyncAccess = (wen || ren) && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && (
981    mireg.addr.U === addr && miselect.inIMSICRange ||
982    sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) ||
983    vsireg.addr.U === addr && vsiselect.inIMSICRange
984  )
985
986  /** State machine of newCSR */
987  switch(state) {
988    is(s_idle) {
989      when(valid && redirectFlush) {
990        stateNext := s_idle
991      }.elsewhen(valid && asyncAccess) {
992        stateNext := s_waitIMSIC
993      }.elsewhen(valid) {
994        stateNext := s_finish
995      }
996    }
997    is(s_waitIMSIC) {
998      when(redirectFlush) {
999        stateNext := s_idle
1000      }.elsewhen(fromAIA.rdata.valid) {
1001        when(io.out.ready) {
1002          stateNext := s_idle
1003        }.otherwise {
1004          stateNext := s_finish
1005        }
1006      }
1007    }
1008    is(s_finish) {
1009      when(redirectFlush || io.out.ready) {
1010        stateNext := s_idle
1011      }
1012    }
1013  }
1014
1015
1016  // Todo: check IMSIC EX_II and EX_VI
1017  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
1018  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
1019  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
1020
1021  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
1022  io.in.ready := (state === s_idle)
1023
1024  /**
1025   * Valid signal of newCSR output.
1026   * When in IDLE state, when input_valid is high, we set it.
1027   * When in waitIMSIC state, and the next state is IDLE, we set it.
1028   **/
1029
1030  /** Data that have been read before,and should be stored because output not fired */
1031  val normalCSRValid = state === s_idle && valid && !asyncAccess
1032  val waitIMSICValid = state === s_waitIMSIC && fromAIA.rdata.valid
1033
1034  io.out.valid := (waitIMSICValid || state === s_finish) && !redirectFlush
1035  io.out.bits.EX_II := DataHoldBypass(Mux1H(Seq(
1036    normalCSRValid -> (permitMod.io.out.EX_II || noCSRIllegal),
1037    waitIMSICValid -> imsic_EX_II,
1038  )), false.B, normalCSRValid || waitIMSICValid)
1039  io.out.bits.EX_VI := DataHoldBypass(Mux1H(Seq(
1040    normalCSRValid -> permitMod.io.out.EX_VI,
1041    waitIMSICValid -> imsic_EX_VI,
1042  )), false.B, normalCSRValid || waitIMSICValid)
1043  io.out.bits.flushPipe := flushPipe
1044
1045  /** Prepare read data for output */
1046  io.out.bits.rData := DataHoldBypass(
1047    Mux1H(Seq(
1048      io.in.fire -> rdata,
1049      fromAIA.rdata.valid -> fromAIA.rdata.bits.data
1050    )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid)
1051  io.out.bits.regOut := regOut
1052  io.out.bits.targetPc := DataHoldBypass(
1053    Mux(trapEntryDEvent.out.targetPc.valid,
1054      trapEntryDEvent.out.targetPc.bits,
1055      Mux1H(Seq(
1056        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
1057        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
1058        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
1059        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
1060        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
1061        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
1062        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
1063        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
1064      )
1065    ),
1066  needTargetUpdate)
1067  io.out.bits.targetPcUpdate := needTargetUpdate
1068  io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire)
1069
1070  io.status.privState := privState
1071  io.status.fpState.frm := fcsr.frm
1072  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
1073  io.status.vecState.vstart := vstart.rdata.asUInt
1074  io.status.vecState.vxsat := vcsr.vxsat
1075  io.status.vecState.vxrm := vcsr.vxrm
1076  io.status.vecState.vcsr := vcsr.rdata.asUInt
1077  io.status.vecState.vl := vl.rdata.asUInt
1078  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
1079  io.status.vecState.vlenb := vlenb.rdata.asUInt
1080  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
1081  io.status.interrupt := intrMod.io.out.interruptVec.valid
1082  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
1083  io.status.debugMode := debugMode
1084  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
1085
1086  /**
1087   * debug_begin
1088   */
1089  val tdata1Selected = Wire(new Tdata1Bundle)
1090  tdata1Selected := tdata1.rdata
1091  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
1092  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
1093  val tdata1Update  = tdata1.w.wen && triggerCanWrite
1094  val tdata2Update  = tdata2.w.wen && triggerCanWrite
1095  val tdata1Vec = tdata1RegVec.map{ mod => {
1096    val tdata1Wire = Wire(new Tdata1Bundle)
1097    tdata1Wire := mod.rdata
1098    tdata1Wire
1099  }}
1100
1101  val triggerCanRaiseBpExp = !(privState.isModeM && !mstatus.regOut.MIE ||
1102    medeleg.regOut.EX_BP && privState.isModeHS && !mstatus.sstatus.SIE ||
1103    medeleg.regOut.EX_BP && hedeleg.regOut.EX_BP && privState.isModeVS && !vsstatus.regOut.SIE)
1104
1105  val debugMod = Module(new Debug)
1106  debugMod.io.in.trapInfo.valid            := hasTrap
1107  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
1108  debugMod.io.in.trapInfo.bits.isDebugIntr := debug
1109  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
1110  debugMod.io.in.trapInfo.bits.trigger     := trigger
1111  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
1112  debugMod.io.in.trapInfo.bits.criticalErrorState := criticalErrorState
1113  debugMod.io.in.privState                 := privState
1114  debugMod.io.in.debugMode                 := debugMode
1115  debugMod.io.in.dcsr                      := dcsr.regOut
1116  debugMod.io.in.tselect                   := tselect.regOut
1117  debugMod.io.in.tdata1Vec                 := tdata1Vec
1118  debugMod.io.in.tdata1Selected            := tdata1.rdata
1119  debugMod.io.in.tdata2Selected            := tdata2.rdata
1120  debugMod.io.in.tdata1Update              := tdata1Update
1121  debugMod.io.in.tdata2Update              := tdata2Update
1122  debugMod.io.in.tdata1Wdata               := wdata
1123  debugMod.io.in.triggerCanRaiseBpExp      := triggerCanRaiseBpExp
1124
1125  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
1126
1127  trapEntryDEvent.valid                           := entryDebugMode
1128  trapEntryDEvent.in.hasDebugIntr                 := debugMod.io.out.hasDebugIntr
1129  trapEntryDEvent.in.debugMode                    := debugMode
1130  trapEntryDEvent.in.hasTrap                      := hasTrap
1131  trapEntryDEvent.in.hasSingleStep                := debugMod.io.out.hasSingleStep
1132  trapEntryDEvent.in.triggerEnterDebugMode        := debugMod.io.out.triggerEnterDebugMode
1133  trapEntryDEvent.in.hasDebugEbreakException      := debugMod.io.out.hasDebugEbreakException
1134  trapEntryDEvent.in.breakPoint                   := debugMod.io.out.breakPoint
1135  trapEntryDEvent.in.criticalErrorStateEnterDebug := debugMod.io.out.criticalErrorStateEnterDebug
1136
1137  tdata1RegVec.foreach { mod =>
1138    mod match {
1139      case m: HasdebugModeBundle =>
1140        m.debugMode := debugMode
1141        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1142      case _ =>
1143    }
1144  }
1145  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1146    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
1147    mod1.w.wdata  := wdata
1148    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
1149    mod2.w.wdata  := wdata
1150  }}
1151
1152  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1153
1154  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
1155  io.status.memTrigger      := debugMod.io.out.memTrigger
1156  /**
1157   * debug_end
1158   */
1159
1160  // trace
1161  val privForTrace = Mux(debugMode,
1162    Priv.D,
1163    Mux1H(
1164      Seq(privState.isModeM, privState.isModeHS, privState.isModeVS, privState.isModeHU, privState.isModeVU),
1165      Seq(Priv.M,            Priv.HS,            Priv.VS,            Priv.HU,            Priv.VU)
1166    )
1167  )
1168  val xret = legalDret || legalMNret || legalMret || legalSret
1169  val currentPriv = privForTrace
1170  val lastPriv = RegEnable(privForTrace, Priv.M, (xret || io.fromRob.trap.valid))
1171
1172  io.status.traceCSR.lastPriv       := lastPriv
1173  io.status.traceCSR.currentPriv    := privForTrace
1174  io.status.traceCSR.cause := Mux1H(
1175    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1176    Seq(mcause.rdata,      scause.rdata,       vscause.rdata)
1177  )
1178  io.status.traceCSR.tval  := Mux1H(
1179    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1180    Seq(mtval.rdata,       stval.rdata,        vstval.rdata)
1181  )
1182
1183  /**
1184   * perf_begin
1185   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1186   */
1187  val csrevents = mhpmevents.slice(24, 29).map(_.rdata)
1188
1189  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1190  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1191    hcEvents(i) := io.perf.perfEventsHc(i)
1192  }
1193
1194  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1195  val allPerfEvents = io.perf.perfEventsFrontend ++
1196    io.perf.perfEventsBackend ++
1197    io.perf.perfEventsLsu ++
1198    hpmHc.getPerf
1199
1200  val countingEn        = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1201  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1202  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1203
1204  for(i <- 0 until perfCntNum) {
1205    mhpmcounters(i) match {
1206      case m: HasPerfCounterBundle =>
1207        m.countingEn        := countingEn(i)
1208        m.perf              := allPerfEvents(i)
1209        ofFromPerfCntVec(i) := m.toMhpmeventOF
1210      case _ =>
1211    }
1212
1213    mhpmevents(i) match {
1214      case m: HasOfFromPerfCntBundle =>
1215        m.ofFromPerfCnt := ofFromPerfCntVec(i)
1216      case _ =>
1217    }
1218
1219    val mhpmevent = Wire(new MhpmeventBundle)
1220    mhpmevent := mhpmevents(i).rdata
1221    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevent.OF.asBool
1222
1223    countingEn(i) := (privState.isModeM && !mhpmevent.MINH) ||
1224      (privState.isModeHS && !mhpmevent.SINH)  ||
1225      (privState.isModeHU && !mhpmevent.UINH)  ||
1226      (privState.isModeVS && !mhpmevent.VSINH) ||
1227      (privState.isModeVU && !mhpmevent.VUINH)
1228  }
1229
1230  val lcofiReq = lcofiReqVec.asUInt.orR
1231  mip match {
1232    case m: HasLocalInterruptReqBundle =>
1233      m.lcofiReq := lcofiReq
1234    case _ =>
1235  }
1236  /**
1237   * perf_end
1238   */
1239
1240  /**
1241   * [[io.status.custom]] connection
1242   */
1243  io.status.custom.pf_ctrl.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1244  io.status.custom.pf_ctrl.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1245  io.status.custom.pf_ctrl.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1246  io.status.custom.pf_ctrl.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1247  io.status.custom.pf_ctrl.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1248  io.status.custom.pf_ctrl.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1249  io.status.custom.pf_ctrl.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1250  io.status.custom.pf_ctrl.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1251  io.status.custom.pf_ctrl.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1252  io.status.custom.pf_ctrl.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1253  io.status.custom.pf_ctrl.l2_pf_recv_enable       := spfctl.regOut.L2_PF_RECV_ENABLE.asBool
1254  io.status.custom.pf_ctrl.l2_pf_pbop_enable       := spfctl.regOut.L2_PF_PBOP_ENABLE.asBool
1255  io.status.custom.pf_ctrl.l2_pf_vbop_enable       := spfctl.regOut.L2_PF_VBOP_ENABLE.asBool
1256  io.status.custom.pf_ctrl.l2_pf_tp_enable         := spfctl.regOut.L2_PF_TP_ENABLE.asBool
1257
1258  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1259  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1260  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1261  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1262  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1263
1264  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1265  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1266  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1267  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1268  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1269  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1270  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1271
1272  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1273  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1274  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1275  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1276  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1277  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
1278  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
1279
1280  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1281  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool && (!io.status.singleStepFlag) && !debugMode
1282
1283  io.status.custom.power_down_enable := mcorepwr.regOut.POWER_DOWN_ENABLE.asBool
1284
1285  io.status.custom.flush_l2_enable := mflushpwr.regOut.FLUSH_L2_ENABLE.asBool
1286
1287  io.status.instrAddrTransType.bare := privState.isModeM ||
1288    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1289    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1290  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1291    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1292  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1293    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1294  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1295  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1296  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1297
1298  private val csrAccess = wenLegalReg || RegNext(ren)
1299
1300  private val imsicAddrValid =
1301    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1302    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1303    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1304
1305  private val imsicAddr = Mux1H(Seq(
1306    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1307    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1308    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1309  ))
1310
1311  private val imsicAddrPrivState = Mux1H(Seq(
1312    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1313    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1314    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1315  ))
1316
1317  private val imsicWdataValid =
1318    mireg.w.wen  && miselect.inIMSICRange ||
1319    sireg.w.wen  && siselect.inIMSICRange ||
1320    vsireg.w.wen && vsiselect.inIMSICRange
1321
1322  toAIA.addr.valid     := imsicAddrValid
1323  toAIA.addr.bits.addr := imsicAddr
1324  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1325  toAIA.addr.bits.v    := imsicAddrPrivState.V
1326
1327  toAIA.wdata.valid := imsicWdataValid
1328  toAIA.wdata.bits.op := RegNext(io.in.bits.op)
1329  toAIA.wdata.bits.data := RegNext(io.in.bits.src)
1330  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1331  toAIA.mClaim  := mtopei.w.wen
1332  toAIA.sClaim  := stopei.w.wen
1333  toAIA.vsClaim := vstopei.w.wen
1334
1335  // tlb
1336  io.tlb.satpASIDChanged  := GatedValidRegNext(satp.w.wen  && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1337  io.tlb.vsatpASIDChanged := GatedValidRegNext(vsatp.w.wen && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1338  io.tlb.hgatpVMIDChanged := GatedValidRegNext(hgatp.w.wen && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1339  io.tlb.satp := satp.rdata
1340  io.tlb.vsatp := vsatp.rdata
1341  io.tlb.hgatp := hgatp.rdata
1342  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1343  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1344  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1345  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1346  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1347
1348  io.tlb.imode := PRVM.asUInt
1349  // when NMIE is zero, force to behave as MPRV is zero
1350  io.tlb.dmode := Mux(
1351    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1352    mstatus.regOut.MPP.asUInt,
1353    PRVM.asUInt
1354  )
1355  io.tlb.dvirt := Mux(
1356    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1357    mstatus.regOut.MPV.asUInt,
1358    V.asUInt
1359  )
1360  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
1361  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1362  io.tlb.pmm.mseccfg := RegNext(mseccfg.regOut.PMM.asUInt)
1363  io.tlb.pmm.menvcfg := RegNext(menvcfg.regOut.PMM.asUInt)
1364  io.tlb.pmm.henvcfg := RegNext(henvcfg.regOut.PMM.asUInt)
1365  io.tlb.pmm.hstatus := RegNext(hstatus.regOut.HUPMM.asUInt)
1366  io.tlb.pmm.senvcfg := RegNext(senvcfg.regOut.PMM.asUInt)
1367
1368  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1369  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1370  io.toDecode.illegalInst.sfencePart := isModeHU
1371  io.toDecode.virtualInst.sfencePart := isModeVU
1372  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1373  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1374  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1375  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
1376  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1377  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1378  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1379  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1380  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1381  io.toDecode.illegalInst.wrs_nto    := !isModeM && mstatus.regOut.TW
1382  io.toDecode.virtualInst.wrs_nto    := privState.V && !mstatus.regOut.TW && hstatus.regOut.VTW
1383  io.toDecode.illegalInst.frm        := frmIsReserved
1384  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1385  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1386  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1387    isModeVS && !henvcfg.regOut.CBZE ||
1388    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1389  )
1390  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1391  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1392    isModeVS && !henvcfg.regOut.CBCFE ||
1393    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1394  )
1395  io.toDecode.illegalInst.cboI       :=
1396    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1397    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1398  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1399    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1400    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1401  )
1402  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1403    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1404    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1405    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1406  )
1407
1408  io.distributedWenLegal := wenLegalReg && !noCSRIllegalReg
1409  io.status.criticalErrorState := criticalErrorState && !dcsr.regOut.CETRIG.asBool
1410
1411  val criticalErrors = Seq(
1412    ("csr_dbltrp_inMN", !mnstatus.regOut.NMIE && hasTrap && !entryDebugMode),
1413  )
1414  criticalErrorStateInCSR := criticalErrors.map(criticalError => criticalError._2).reduce(_ || _).asBool
1415  generateCriticalErrors()
1416
1417  // Always instantiate basic difftest modules.
1418  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1419    // Delay trap passed to difftest until VecExcpMod is not busy
1420    val pendingTrap = RegInit(false.B)
1421    when (hasTrap) {
1422      pendingTrap := true.B
1423    }.elsewhen (!io.fromVecExcpMod.busy) {
1424      pendingTrap := false.B
1425    }
1426
1427    val hartId = io.fromTop.hartId
1428    val trapValid = pendingTrap && !io.fromVecExcpMod.busy
1429    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1430    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1431    val hasNMI = nmi && hasTrap
1432    val interruptNO = Mux(interrupt, trapNO, 0.U)
1433    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1434    val isSv39: Bool =
1435      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
1436      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
1437    val isSv48: Bool =
1438      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
1439      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
1440    val isBare = !isSv39 && !isSv48
1441    val sv39PC = SignExt(trapPC.take(39), XLEN)
1442    val sv48PC = SignExt(trapPC.take(48), XLEN)
1443    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1444    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1445    val exceptionPC = Mux1H(Seq(
1446      isSv39 -> sv39PC,
1447      isSv48 -> sv48PC,
1448      isBare -> barePC,
1449    ))
1450
1451    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1452    diffArchEvent.coreid := hartId
1453    diffArchEvent.valid := trapValid
1454    diffArchEvent.interrupt := RegEnable(interruptNO, hasTrap)
1455    diffArchEvent.exception := RegEnable(exceptionNO, hasTrap)
1456    diffArchEvent.exceptionPC := RegEnable(exceptionPC, hasTrap)
1457    diffArchEvent.hasNMI := RegEnable(hasNMI, hasTrap)
1458    diffArchEvent.virtualInterruptIsHvictlInject := RegNext(virtualInterruptIsHvictlInject && hasTrap)
1459    if (env.EnableDifftest) {
1460      diffArchEvent.exceptionInst := RegEnable(io.fromRob.trap.bits.instr, hasTrap)
1461    }
1462
1463    val diffCriticalErrorEvent = DifftestModule(new DiffCriticalErrorEvent, delay = 4, dontCare = true)
1464    diffCriticalErrorEvent.valid := io.status.criticalErrorState && trapValid
1465    diffCriticalErrorEvent.coreid := hartId
1466    diffCriticalErrorEvent.criticalError := io.status.criticalErrorState
1467
1468    val diffCSRState = DifftestModule(new DiffCSRState)
1469    diffCSRState.coreid         := hartId
1470    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1471    diffCSRState.mstatus        := mstatus.rdata.asUInt
1472    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1473    diffCSRState.mepc           := mepc.rdata.asUInt
1474    diffCSRState.sepc           := sepc.rdata.asUInt
1475    diffCSRState.mtval          := mtval.rdata.asUInt
1476    diffCSRState.stval          := stval.rdata.asUInt
1477    diffCSRState.mtvec          := mtvec.rdata.asUInt
1478    diffCSRState.stvec          := stvec.rdata.asUInt
1479    diffCSRState.mcause         := mcause.rdata.asUInt
1480    diffCSRState.scause         := scause.rdata.asUInt
1481    diffCSRState.satp           := satp.rdata.asUInt
1482    diffCSRState.mip            := mip.rdata.asUInt
1483    diffCSRState.mie            := mie.rdata.asUInt
1484    diffCSRState.mscratch       := mscratch.rdata.asUInt
1485    diffCSRState.sscratch       := sscratch.rdata.asUInt
1486    diffCSRState.mideleg        := mideleg.rdata.asUInt
1487    diffCSRState.medeleg        := medeleg.rdata.asUInt
1488
1489    val diffDebugMode = DifftestModule(new DiffDebugMode)
1490    diffDebugMode.coreid    := hartId
1491    diffDebugMode.debugMode := debugMode
1492    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1493    diffDebugMode.dpc       := dpc.rdata.asUInt
1494    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1495    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1496
1497    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1498    diffTriggerCSRState.coreid    := hartId
1499    diffTriggerCSRState.tselect   := tselect.rdata
1500    diffTriggerCSRState.tdata1    := tdata1.rdata
1501    diffTriggerCSRState.tinfo     := tinfo.rdata
1502
1503    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1504    diffVecCSRState.coreid := hartId
1505    diffVecCSRState.vstart := vstart.rdata.asUInt
1506    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1507    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1508    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1509    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1510    diffVecCSRState.vtype := vtype.rdata.asUInt
1511    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1512
1513    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1514    diffFpCSRState.coreid := hartId
1515    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1516
1517    val diffHCSRState = DifftestModule(new DiffHCSRState)
1518    diffHCSRState.coreid      := hartId
1519    diffHCSRState.virtMode    := privState.V.asBool
1520    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1521    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1522    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1523    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1524    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1525    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1526    diffHCSRState.htval       := htval.rdata.asUInt
1527    diffHCSRState.htinst      := htinst.rdata.asUInt
1528    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1529    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1530    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1531    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1532    diffHCSRState.vscause     := vscause.rdata.asUInt
1533    diffHCSRState.vstval      := vstval.rdata.asUInt
1534    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1535    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1536
1537    val platformIRPMeipChange = !platformIRP.MEIP &&  RegNext(platformIRP.MEIP) || platformIRP.MEIP && !RegNext(platformIRP.MEIP)
1538    val platformIRPMtipChange = !platformIRP.MTIP &&  RegNext(platformIRP.MTIP) || platformIRP.MTIP && !RegNext(platformIRP.MTIP)
1539    val platformIRPMsipChange = !platformIRP.MSIP &&  RegNext(platformIRP.MSIP) || platformIRP.MSIP && !RegNext(platformIRP.MSIP)
1540    val platformIRPSeipChange = !platformIRP.SEIP &&  RegNext(platformIRP.SEIP) || platformIRP.SEIP && !RegNext(platformIRP.SEIP)
1541    val platformIRPStipChange = !sstcIRGen.o.STIP &&  RegNext(sstcIRGen.o.STIP) || sstcIRGen.o.STIP && !RegNext(sstcIRGen.o.STIP)
1542    val platformIRPVseipChange = !platformIRP.VSEIP &&  RegNext(platformIRP.VSEIP) ||
1543                                  platformIRP.VSEIP && !RegNext(platformIRP.VSEIP) ||
1544                                 !hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) &&  RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) ||
1545                                  hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && !RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt))
1546    val platformIRPVstipChange = !sstcIRGen.o.VSTIP && RegNext(sstcIRGen.o.VSTIP) || sstcIRGen.o.VSTIP && !RegNext(sstcIRGen.o.VSTIP)
1547    val fromAIAMeipChange = !fromAIA.meip && RegNext(fromAIA.meip) || fromAIA.meip && !RegNext(fromAIA.meip)
1548    val fromAIASeipChange = !fromAIA.seip && RegNext(fromAIA.seip) || fromAIA.seip && !RegNext(fromAIA.seip)
1549    val lcofiReqChange = !lcofiReq && RegNext(lcofiReq) || lcofiReq && !RegNext(lcofiReq)
1550
1551    val diffNonRegInterruptPendingEvent = DifftestModule(new DiffNonRegInterruptPendingEvent)
1552    diffNonRegInterruptPendingEvent.coreid           := hartId
1553    diffNonRegInterruptPendingEvent.valid            := platformIRPMeipChange || platformIRPMtipChange || platformIRPMsipChange ||
1554                                                        platformIRPSeipChange || platformIRPStipChange ||
1555                                                        platformIRPVseipChange || platformIRPVstipChange ||
1556                                                        fromAIAMeipChange || fromAIASeipChange ||
1557                                                        lcofiReqChange
1558    diffNonRegInterruptPendingEvent.platformIRPMeip  := platformIRP.MEIP
1559    diffNonRegInterruptPendingEvent.platformIRPMtip  := platformIRP.MTIP
1560    diffNonRegInterruptPendingEvent.platformIRPMsip  := platformIRP.MSIP
1561    diffNonRegInterruptPendingEvent.platformIRPSeip  := platformIRP.SEIP
1562    diffNonRegInterruptPendingEvent.platformIRPStip  := sstcIRGen.o.STIP
1563    diffNonRegInterruptPendingEvent.platformIRPVseip := platformIRP.VSEIP || hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)
1564    diffNonRegInterruptPendingEvent.platformIRPVstip := sstcIRGen.o.VSTIP
1565    diffNonRegInterruptPendingEvent.fromAIAMeip := fromAIA.meip
1566    diffNonRegInterruptPendingEvent.fromAIASeip := fromAIA.seip
1567    diffNonRegInterruptPendingEvent.localCounterOverflowInterruptReq  := mip.regOut.LCOFIP.asBool
1568
1569    val diffMhpmeventOverflowEvent = DifftestModule(new DiffMhpmeventOverflowEvent)
1570    diffMhpmeventOverflowEvent.coreid := hartId
1571    diffMhpmeventOverflowEvent.valid  := Cat(mhpmevents.zipWithIndex.map{ case (event, i) =>
1572      !ofFromPerfCntVec(i) && RegNext(ofFromPerfCntVec(i)) || ofFromPerfCntVec(i) && !RegNext(ofFromPerfCntVec(i))
1573    }).orR
1574    diffMhpmeventOverflowEvent.mhpmeventOverflow := VecInit(mhpmevents.map(_.regOut.asInstanceOf[MhpmeventBundle].OF.asBool)).asUInt
1575
1576    val diffSyncAIAEvent = DifftestModule(new DiffSyncAIAEvent)
1577    diffSyncAIAEvent.coreid := hartId
1578    diffSyncAIAEvent.valid := fromAIA.rdata.valid
1579    diffSyncAIAEvent.mtopei := mtopei.rdata
1580    diffSyncAIAEvent.stopei := stopei.rdata
1581    diffSyncAIAEvent.vstopei := vstopei.rdata
1582    diffSyncAIAEvent.hgeip := hgeip.rdata
1583
1584    val diffCustomMflushpwr = DifftestModule(new DiffSyncCustomMflushpwrEvent)
1585    diffCustomMflushpwr.coreid := hartId
1586    diffCustomMflushpwr.valid := RegNext(io.fromTop.l2FlushDone) =/= io.fromTop.l2FlushDone
1587    diffCustomMflushpwr.l2FlushDone := io.fromTop.l2FlushDone
1588  }
1589}
1590
1591trait IpIeAliasConnect {
1592  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1593
1594  mip.fromMvip  := mvip.toMip
1595  mip.fromSip   := sip.toMip
1596  mip.fromVSip  := vsip.toMip
1597  mvip.fromMip  := mip.toMvip
1598  mvip.fromSip  := sip.toMvip
1599  mvip.fromVSip := vsip.toMvip
1600  hvip.fromMip  := mip.toHvip
1601  hvip.fromHip  := hip.toHvip
1602  hvip.fromVSip := vsip.toHvip
1603
1604  mie.fromHie  := hie.toMie
1605  mie.fromSie  := sie.toMie
1606  mie.fromVSie := vsie.toMie
1607  sie.fromVSie := vsie.toSie
1608}
1609
1610object NewCSRMain extends App {
1611  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1612    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1613
1614  val defaultConfig = config.alterPartial({
1615    // Get XSCoreParams and pass it to the "small module"
1616    case XSCoreParamsKey => config(XSTileKey).head
1617  })
1618
1619  Generator.execute(
1620    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1621    new NewCSR()(defaultConfig),
1622    firtoolOpts
1623  )
1624
1625  println("done")
1626}