xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision 5137113c032a3fad2a29f363b52fca52325191d2)
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
386  when(intrMod.io.out.nmi && intrMod.io.out.interruptVec.valid) {
387    nmip.NMI_31 := nmip.NMI_31 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_31)
388    nmip.NMI_43 := nmip.NMI_43 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_43)
389  }
390  val intrVec = RegEnable(intrMod.io.out.interruptVec.bits, 0.U, intrMod.io.out.interruptVec.valid)
391  val debug = RegEnable(intrMod.io.out.debug, false.B, intrMod.io.out.interruptVec.valid)
392  val nmi = RegEnable(intrMod.io.out.nmi, false.B, intrMod.io.out.interruptVec.valid)
393  val virtualInterruptIsHvictlInject = RegEnable(intrMod.io.out.virtualInterruptIsHvictlInject, false.B, intrMod.io.out.interruptVec.valid)
394  val irToHS = RegEnable(intrMod.io.out.irToHS, false.B, intrMod.io.out.interruptVec.valid)
395  val irToVS = RegEnable(intrMod.io.out.irToVS, false.B, intrMod.io.out.interruptVec.valid)
396
397  val trapHandleMod = Module(new TrapHandleModule)
398
399  trapHandleMod.io.in.trapInfo.valid := hasTrap
400  trapHandleMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt
401  trapHandleMod.io.in.trapInfo.bits.nmi := nmi
402  trapHandleMod.io.in.trapInfo.bits.intrVec := intrVec
403  trapHandleMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
404  trapHandleMod.io.in.trapInfo.bits.irToHS := irToHS
405  trapHandleMod.io.in.trapInfo.bits.irToVS := irToVS
406  trapHandleMod.io.in.privState := privState
407  trapHandleMod.io.in.mstatus  := mstatus.regOut
408  trapHandleMod.io.in.vsstatus := vsstatus.regOut
409  trapHandleMod.io.in.mnstatus := mnstatus.regOut
410  trapHandleMod.io.in.mideleg  := mideleg.regOut
411  trapHandleMod.io.in.medeleg  := medeleg.regOut
412  trapHandleMod.io.in.hideleg  := hideleg.regOut
413  trapHandleMod.io.in.hedeleg  := hedeleg.regOut
414  trapHandleMod.io.in.mvien := mvien.regOut
415  trapHandleMod.io.in.hvien := hvien.regOut
416  trapHandleMod.io.in.mtvec := mtvec.regOut
417  trapHandleMod.io.in.stvec := stvec.regOut
418  trapHandleMod.io.in.vstvec := vstvec.regOut
419  trapHandleMod.io.in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
420  trapHandleMod.io.in.trapInfo.bits.singleStep  := hasTrap && !trapIsInterrupt && singleStep
421
422  val entryPrivState = trapHandleMod.io.out.entryPrivState
423  val entryDebugMode = WireInit(false.B)
424  val dbltrpToMN     = trapHandleMod.io.out.dbltrpToMN
425  val hasDTExcp      = trapHandleMod.io.out.hasDTExcp
426
427  // PMP
428  val pmpEntryMod = Module(new PMPEntryHandleModule)
429  pmpEntryMod.io.in.pmpCfg  := cfgs.map(_.regOut.asInstanceOf[PMPCfgBundle])
430  pmpEntryMod.io.in.pmpAddr := pmpaddr.map(_.regOut.asInstanceOf[PMPAddrBundle])
431  pmpEntryMod.io.in.ren   := ren
432  pmpEntryMod.io.in.wen   := wenLegalReg
433  pmpEntryMod.io.in.addr  := addr
434  pmpEntryMod.io.in.wdata := wdata
435
436  // Todo: all wen and wdata of CSRModule assigned in this for loop
437  for ((id, (wBundle, _)) <- csrRwMap) {
438    if (vsMapS.contains(id)) {
439      // VS access CSR by S: privState.isModeVS && addrMappedToVS === sMapVS(id).U
440      wBundle.wen := wenLegalReg && ((isModeVS && addr === vsMapS(id).U) || (!isModeVS && addr === id.U))
441      wBundle.wdata := wdata
442    } else if (sMapVS.contains(id)) {
443      wBundle.wen := wenLegalReg && !isModeVS && addr === id.U
444      wBundle.wdata := wdata
445    } else {
446      wBundle.wen := wenLegalReg && addr === id.U
447      wBundle.wdata := wdata
448    }
449  }
450
451  private val writeFpLegal  = permitMod.io.out.hasLegalWriteFcsr
452  private val writeVecLegal = permitMod.io.out.hasLegalWriteVcsr
453
454  permitMod.io.in.csrAccess.ren := ren && valid
455  permitMod.io.in.csrAccess.wen := wen
456  permitMod.io.in.csrAccess.addr := addr
457
458  permitMod.io.in.privState := privState
459  permitMod.io.in.debugMode := debugMode
460
461  permitMod.io.in.xRet.mnret := io.in.bits.mnret && valid
462  permitMod.io.in.xRet.mret  := io.in.bits.mret  && valid
463  permitMod.io.in.xRet.sret  := io.in.bits.sret  && valid
464  permitMod.io.in.xRet.dret  := io.in.bits.dret  && valid
465
466  permitMod.io.in.status.tsr := mstatus.regOut.TSR.asBool
467  permitMod.io.in.status.vtsr := hstatus.regOut.VTSR.asBool
468
469  permitMod.io.in.status.tvm  := mstatus.regOut.TVM.asBool
470  permitMod.io.in.status.vtvm := hstatus.regOut.VTVM.asBool
471
472  permitMod.io.in.status.vgein := hstatus.regOut.VGEIN.asUInt
473
474  permitMod.io.in.xcounteren.mcounteren := mcounteren.rdata
475  permitMod.io.in.xcounteren.hcounteren := hcounteren.rdata
476  permitMod.io.in.xcounteren.scounteren := scounteren.rdata
477
478  permitMod.io.in.xstateen.mstateen0 := mstateen0.rdata
479  permitMod.io.in.xstateen.hstateen0 := hstateen0.rdata
480  permitMod.io.in.xstateen.sstateen0 := sstateen0.rdata
481
482  permitMod.io.in.xenvcfg.menvcfg := menvcfg.rdata
483  permitMod.io.in.xenvcfg.henvcfg := henvcfg.rdata
484
485  permitMod.io.in.status.mstatusFSOff  :=  mstatus.regOut.FS === ContextStatus.Off
486  permitMod.io.in.status.mstatusVSOff  :=  mstatus.regOut.VS === ContextStatus.Off
487  permitMod.io.in.status.vsstatusFSOff := vsstatus.regOut.FS === ContextStatus.Off
488  permitMod.io.in.status.vsstatusVSOff := vsstatus.regOut.VS === ContextStatus.Off
489
490  permitMod.io.in.aia.miselectIsIllegal  := miselect.isIllegal
491  permitMod.io.in.aia.siselectIsIllegal  := siselect.isIllegal
492  permitMod.io.in.aia.vsiselectIsIllegal := vsiselect.isIllegal
493  permitMod.io.in.aia.siselect := siselect.rdata
494  permitMod.io.in.aia.vsiselect := vsiselect.rdata
495  permitMod.io.in.aia.mvienSEIE := mvien.regOut.SEIE.asBool
496  permitMod.io.in.aia.hvictlVTI := hvictl.regOut.VTI.asBool
497
498  sstcIRGen.i.stime.valid := time.updated
499  sstcIRGen.i.stime.bits  := time.stime
500  sstcIRGen.i.vstime.valid := time.updated
501  sstcIRGen.i.vstime.bits  := time.vstime
502  sstcIRGen.i.stimecmp.wen := GatedValidRegNext(stimecmp.w.wen)
503  sstcIRGen.i.stimecmp.rdata  := stimecmp.rdata
504  sstcIRGen.i.vstimecmp.wen   := GatedValidRegNext(vstimecmp.w.wen)
505  sstcIRGen.i.vstimecmp.rdata := vstimecmp.rdata
506  sstcIRGen.i.menvcfg.wen   := GatedValidRegNext(menvcfg.w.wen)
507  sstcIRGen.i.menvcfg.STCE  := menvcfg.regOut.STCE.asBool
508  sstcIRGen.i.henvcfg.wen   := GatedValidRegNext(henvcfg.w.wen)
509  sstcIRGen.i.henvcfg.STCE  := henvcfg.regOut.STCE.asBool
510  sstcIRGen.i.htimedeltaWen := GatedValidRegNext(htimedelta.w.wen)
511
512  miregiprios.foreach { mod =>
513    mod.w.wen := mireg.w.wen && (miselect.regOut.ALL.asUInt === mod.addr.U)
514    mod.w.wdata := wdata
515  }
516
517  siregiprios.foreach { mod =>
518    mod.w.wen := sireg.w.wen && (siselect.regOut.ALL.asUInt === mod.addr.U)
519    mod.w.wdata := wdata
520  }
521
522  mhartid.hartid := this.io.fromTop.hartId
523
524  cfgs.zipWithIndex.foreach { case (mod, i) =>
525    mod.w.wen := wenLegalReg && (addr === (0x3A0 + i / 8 * 2).U)
526    mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8))
527  }
528
529  pmpaddr.zipWithIndex.foreach{ case(mod, i) =>
530    mod.w.wen := wenLegalReg && (addr === (0x3B0 + i).U)
531    mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i)
532  }
533
534  csrMods.foreach { mod =>
535    mod match {
536      case m: HypervisorBundle =>
537        m.hstatus := hstatus.regOut
538      case _ =>
539    }
540    mod match {
541      case m: VirtualSupervisorBundle =>
542        m.v := V.asUInt.asBool
543        m.hgatp := hgatp.regOut
544      case _ =>
545    }
546    mod match {
547      case m: HasMachineDelegBundle =>
548        m.mideleg := mideleg.regOut
549        m.medeleg := medeleg.regOut
550      case _ =>
551    }
552    mod match {
553      case m: HasMachineCounterControlBundle =>
554        m.mcountinhibit := mcountinhibit.regOut
555      case _ =>
556    }
557    mod match {
558      case m: HasExternalInterruptBundle =>
559        m.platformIRP := this.platformIRP
560        m.platformIRP.STIP  := sstcIRGen.o.STIP
561        m.platformIRP.VSTIP := sstcIRGen.o.VSTIP
562      case _ =>
563    }
564    mod match {
565      case m: HasRobCommitBundle =>
566        // Todo: move RegNext from ROB to CSR
567        m.robCommit.instNum := io.fromRob.commit.instNum
568        m.robCommit.fflags  := RegNextWithEnable(io.fromRob.commit.fflags)
569        m.robCommit.fsDirty := GatedValidRegNext(io.fromRob.commit.fsDirty)
570        m.robCommit.vsDirty := GatedValidRegNext(io.fromRob.commit.vsDirty)
571        m.robCommit.vxsat   := RegNextWithEnable(io.fromRob.commit.vxsat)
572        m.robCommit.vtype   := RegNextWithEnable(io.fromRob.commit.vtype)
573        m.robCommit.vl      := RegNext          (io.fromRob.commit.vl)
574        m.robCommit.vstart  := RegNextWithEnable(io.fromRob.commit.vstart)
575        m.writeFCSR         := writeFpLegal
576        m.writeVCSR         := writeVecLegal
577        m.isVirtMode        := V.asUInt.asBool
578      case _ =>
579    }
580    mod match {
581      case m: TrapEntryDEventSinkBundle =>
582        m.trapToD := trapEntryDEvent.out
583      case _ =>
584    }
585    mod match {
586      case m: TrapEntryMEventSinkBundle =>
587        m.trapToM := trapEntryMEvent.out
588      case _ =>
589    }
590    mod match {
591      case m: TrapEntryMNEventSinkBundle =>
592        m.trapToMN := trapEntryMNEvent.out
593      case _ =>
594    }
595    mod match {
596      case m: TrapEntryHSEventSinkBundle =>
597        m.trapToHS := trapEntryHSEvent.out
598      case _ =>
599    }
600    mod match {
601      case m: TrapEntryVSEventSinkBundle =>
602        m.trapToVS := trapEntryVSEvent.out
603      case _ =>
604    }
605    mod match {
606      case m: MretEventSinkBundle =>
607        m.retFromM := mretEvent.out
608      case _ =>
609    }
610    mod match {
611      case m: MNretEventSinkBundle =>
612        m.retFromMN := mnretEvent.out
613      case _ =>
614    }
615    mod match {
616      case m: SretEventSinkBundle =>
617        m.retFromS := sretEvent.out
618      case _ =>
619    }
620    mod match {
621      case m: DretEventSinkBundle =>
622        m.retFromD := dretEvent.out
623      case _ =>
624    }
625    mod match {
626      case m: HasAIABundle =>
627        m.aiaToCSR.rdata.valid := fromAIA.rdata.valid
628        m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data
629        m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal
630        m.aiaToCSR.meip    := fromAIA.meip
631        m.aiaToCSR.seip    := fromAIA.seip
632        m.aiaToCSR.vseip   := fromAIA.vseip
633        m.aiaToCSR.mtopei  := fromAIA.mtopei
634        m.aiaToCSR.stopei  := fromAIA.stopei
635        m.aiaToCSR.vstopei := fromAIA.vstopei
636      case _ =>
637    }
638    mod match {
639      case m: HasInterruptFilterSink =>
640        m.topIR.mtopi  := intrMod.io.out.mtopi
641        m.topIR.stopi  := intrMod.io.out.stopi
642        m.topIR.vstopi := intrMod.io.out.vstopi
643      case _ =>
644    }
645    mod match {
646      case m: HasPMPAddrSink =>
647        m.addrRData := pmpEntryMod.io.out.pmpAddrRData
648      case _ =>
649    }
650    mod match {
651      case m: HasMHPMSink =>
652        // cycle from mcycle
653        m.mHPM.cycle := mcycle.rdata
654        // time from clint
655        m.mHPM.time  := io.fromTop.clintTime
656        // instret from minstret
657        m.mHPM.instret := minstret.rdata
658        // VS-Mode or VU-Mode
659        m.v := privState.isVirtual
660        m.nextV := nextV.isOneOf(VirtMode.On)
661        m.htimedelta := htimedelta.rdata
662        m.mHPM.hpmcounters.zip(mhpmcounters).map{
663          case(counter, mcounter) => counter := mcounter.rdata
664        }
665      case _ =>
666    }
667    mod match {
668      case m: HasMachineEnvBundle =>
669        m.menvcfg := menvcfg.regOut
670      case _ =>
671    }
672    mod match {
673      case m: HasHypervisorEnvBundle =>
674        m.menvcfg := menvcfg.regOut
675      case _ =>
676    }
677    mod match {
678      case m: HasVirtualSupervisorEnvBundle =>
679        m.henvcfg := henvcfg.regOut
680        m.menvcfg := menvcfg.regOut
681      case _ =>
682    }
683    mod match {
684      case m: HasIpIeBundle =>
685        m.mideleg := mideleg.regOut
686        m.mip := mip.rdata
687        m.mie := mie.regOut
688        m.mvip := mvip.regOut
689        m.mvien := mvien.regOut
690        m.hideleg := hideleg.regOut
691        m.hip := hip.regOut
692        m.hie := hie.regOut
693        m.hvien := hvien.regOut
694        m.hvip := hvip.regOut
695        m.sip := sip.regOut
696        m.sie := sie.regOut
697        m.vsip := vsip.regOut
698        m.vsie := vsie.regOut
699        m.hgeip := hgeip.regOut
700        m.hgeie := hgeie.regOut
701        m.hstatusVGEIN := hstatus.regOut.VGEIN
702      case _ =>
703    }
704    mod match {
705      case m: HasMhpmeventOfBundle =>
706        m.ofVec := VecInit(mhpmevents.map{ event =>
707          val mhpmevent = Wire(new MhpmeventBundle)
708          mhpmevent := event.rdata
709          mhpmevent.OF.asBool
710        }).asUInt
711        m.privState := privState
712        m.mcounteren := mcounteren.rdata
713        m.hcounteren := hcounteren.rdata
714      case _ =>
715    }
716    mod match {
717      case m: HasStateen0Bundle =>
718        m.fromMstateen0 := mstateen0.regOut
719        m.fromHstateen0 := hstateen0.regOut
720        m.privState     := privState
721      case _ =>
722    }
723    mod match {
724      case m: HasDebugStopBundle =>
725        m.debugModeStopCount := debugModeStopCount
726        m.debugModeStopTime  := debugModeStopTimeNext
727        m.unprivCountUpdate  := unprivCountUpdate
728      case _ =>
729    }
730    mod match {
731      case m: HasNmipBundle =>
732        m.nmip := nmip.asUInt.orR
733      case _ =>
734    }
735    mod match {
736      case m: HasMachineFlushL2Bundle =>
737        m.l2FlushDone := io.fromTop.l2FlushDone
738      case _ =>
739    }
740  }
741
742  csrMods.foreach { mod =>
743    println(s"${mod.modName}: ")
744    println(mod.dumpFields)
745  }
746
747  trapEntryMNEvent.valid  := ((hasTrap && nmi) || dbltrpToMN) && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
748  trapEntryMEvent .valid  := hasTrap && entryPrivState.isModeM && !dbltrpToMN && !entryDebugMode && !debugMode && !nmi && mnstatus.regOut.NMIE
749  trapEntryHSEvent.valid  := hasTrap && entryPrivState.isModeHS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
750  trapEntryVSEvent.valid  := hasTrap && entryPrivState.isModeVS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE
751
752  Seq(trapEntryMEvent, trapEntryMNEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod =>
753    eMod.in match {
754      case in: TrapEntryEventInput =>
755        in.causeNO := trapHandleMod.io.out.causeNO
756        in.trapPc := trapPC
757        in.trapPcGPA := trapPCGPA // only used by trapEntryMEvent & trapEntryHSEvent
758        in.trapInst := io.trapInst
759        in.fetchMalTval := io.fetchMalTval
760        in.isCrossPageIPF := trapIsCrossPageIPF
761        in.isHls := trapIsHls
762        in.isFetchMalAddr := trapIsFetchMalAddr
763        in.isFetchBkpt := trapIsFetchBkpt
764        in.trapIsForVSnonLeafPTE := trapIsForVSnonLeafPTE
765        in.hasDTExcp := hasDTExcp
766
767        in.iMode.PRVM := PRVM
768        in.iMode.V := V
769        // when NMIE is zero, force to behave as MPRV is zero
770        in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool && mnstatus.regOut.NMIE.asBool, mstatus.regOut.MPP, PRVM)
771        in.dMode.V := V.asUInt.asBool || mstatus.regOut.MPRV && mnstatus.regOut.NMIE.asBool && (mstatus.regOut.MPP =/= PrivMode.M) && mstatus.regOut.MPV
772
773        in.privState := privState
774        in.mstatus := mstatus.regOut
775        in.hstatus := hstatus.regOut
776        in.sstatus := mstatus.sstatus
777        in.vsstatus := vsstatus.regOut
778        in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec
779
780        in.menvcfg := menvcfg.regOut
781        in.henvcfg := henvcfg.regOut
782
783        in.satp  := satp.regOut
784        in.vsatp := vsatp.regOut
785        in.hgatp := hgatp.regOut
786
787        in.memExceptionVAddr := io.fromMem.excpVA
788        in.memExceptionGPAddr := io.fromMem.excpGPA
789        in.memExceptionIsForVSnonLeafPTE := io.fromMem.excpIsForVSnonLeafPTE
790
791        in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
792        in.hvictlIID := hvictl.regOut.IID.asUInt
793    }
794  }
795
796  mnretEvent.valid := legalMNret
797  mnretEvent.in match {
798    case in =>
799      in.mstatus := mstatus.regOut
800      in.vsstatus := vsstatus.regOut
801      in.mnepc   := mnepc.regOut
802      in.mnstatus:= mnstatus.regOut
803      in.satp := satp.regOut
804      in.vsatp := vsatp.regOut
805      in.hgatp := hgatp.regOut
806  }
807
808  mretEvent.valid := legalMret
809  mretEvent.in match {
810    case in =>
811      in.mstatus := mstatus.regOut
812      in.vsstatus := vsstatus.regOut
813      in.mepc := mepc.regOut
814      in.satp := satp.regOut
815      in.vsatp := vsatp.regOut
816      in.hgatp := hgatp.regOut
817  }
818
819  sretEvent.valid := legalSret
820  sretEvent.in match {
821    case in =>
822      in.privState := privState
823      in.mstatus := mstatus.regOut
824      in.hstatus := hstatus.regOut
825      in.vsstatus := vsstatus.regOut
826      in.sepc := sepc.regOut
827      in.vsepc := vsepc.regOut
828      in.satp := satp.regOut
829      in.vsatp := vsatp.regOut
830      in.hgatp := hgatp.regOut
831  }
832
833  dretEvent.valid := legalDret
834  dretEvent.in match {
835    case in =>
836      in.dcsr := dcsr.regOut
837      in.dpc  := dpc.regOut
838      in.mstatus := mstatus.regOut
839      in.vsstatus := vsstatus.regOut
840      in.satp := satp.regOut
841      in.vsatp := vsatp.regOut
842      in.hgatp := hgatp.regOut
843  }
844
845  PRVM := MuxCase(
846    PRVM,
847    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
848      x => x.out match {
849        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
850      }
851    }
852  )
853
854  nextV := MuxCase(
855    V,
856    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
857      x => x.out match {
858        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
859      }
860    }
861  )
862
863  debugMode := MuxCase(
864    debugMode,
865    Seq(
866      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits,
867      trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits
868    )
869  )
870
871  debugIntrEnable := MuxCase(
872    debugIntrEnable,
873    Seq(
874      dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits,
875      trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits
876    )
877  )
878
879  // perf
880  val addrInPerfCnt = (wenLegal || ren) && (
881    (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
882    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U)
883  )
884
885  // flush
886  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegalReg // write to satp will cause the pipeline be flushed
887
888  val floatStatusOnOff = mstatus.w.wen && (
889    mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
890    mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
891  ) || mstatus.wAliasSstatus.wen && (
892    mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
893    mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
894  ) || vsstatus.w.wen && (
895    vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off ||
896    vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off
897  )
898
899  val vectorStatusOnOff = mstatus.w.wen && (
900    mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
901    mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
902  ) || mstatus.wAliasSstatus.wen && (
903    mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
904    mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
905  ) || vsstatus.w.wen && (
906    vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off ||
907    vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off
908  )
909
910  val triggerFrontendChange = Wire(Bool())
911
912  val vstartChange = vstart.w.wen && (
913    vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U ||
914    vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U
915  )
916
917  // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved
918  val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR
919  val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR
920  val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR
921  val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) ||
922    fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved)
923
924  val flushPipe = resetSatp ||
925    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
926    vstartChange || frmChange
927
928  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
929    if (vsMapS.contains(id)) {
930      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
931    } else if (sMapVS.contains(id)) {
932      (!isModeVS && addr === id.U) -> rdata
933    } else {
934      (raddr === id.U) -> rdata
935    }
936  })
937
938  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
939    if (vsMapS.contains(id)) {
940      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
941    } else if (sMapVS.contains(id)) {
942      (!isModeVS && addr === id.U) -> regOut
943    } else {
944      (raddr === id.U) -> regOut
945    }
946  })
947
948  private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
949    trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
950
951  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
952
953  private val noCSRIllegalReg = RegEnable(noCSRIllegal, ren || wen)
954
955  private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3)
956
957  /** the state machine of newCSR module */
958  private val state = RegInit(s_idle)
959  /** the next state of newCSR */
960  private val stateNext = WireInit(state)
961  state := stateNext
962
963  /**
964   * Asynchronous access operation of CSR. Check whether an access is asynchronous when read/write-enable is high.
965   * AIA registers are designed to be access asynchronously, so newCSR will wait for response.
966   **/
967  private val asyncAccess = (wen || ren) && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && (
968    mireg.addr.U === addr && miselect.inIMSICRange ||
969    sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) ||
970    vsireg.addr.U === addr && vsiselect.inIMSICRange
971  )
972
973  /** State machine of newCSR */
974  switch(state) {
975    is(s_idle) {
976      when(valid && redirectFlush) {
977        stateNext := s_idle
978      }.elsewhen(valid && asyncAccess) {
979        stateNext := s_waitIMSIC
980      }.elsewhen(valid) {
981        stateNext := s_finish
982      }
983    }
984    is(s_waitIMSIC) {
985      when(redirectFlush) {
986        stateNext := s_idle
987      }.elsewhen(fromAIA.rdata.valid) {
988        when(io.out.ready) {
989          stateNext := s_idle
990        }.otherwise {
991          stateNext := s_finish
992        }
993      }
994    }
995    is(s_finish) {
996      when(redirectFlush || io.out.ready) {
997        stateNext := s_idle
998      }
999    }
1000  }
1001
1002
1003  // Todo: check IMSIC EX_II and EX_VI
1004  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
1005  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
1006  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
1007
1008  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
1009  io.in.ready := (state === s_idle)
1010
1011  /**
1012   * Valid signal of newCSR output.
1013   * When in IDLE state, when input_valid is high, we set it.
1014   * When in waitIMSIC state, and the next state is IDLE, we set it.
1015   **/
1016
1017  /** Data that have been read before,and should be stored because output not fired */
1018  val normalCSRValid = state === s_idle && valid && !asyncAccess
1019  val waitIMSICValid = state === s_waitIMSIC && fromAIA.rdata.valid
1020
1021  io.out.valid := (waitIMSICValid || state === s_finish) && !redirectFlush
1022  io.out.bits.EX_II := DataHoldBypass(Mux1H(Seq(
1023    normalCSRValid -> (permitMod.io.out.EX_II || noCSRIllegal),
1024    waitIMSICValid -> imsic_EX_II,
1025  )), false.B, normalCSRValid || waitIMSICValid)
1026  io.out.bits.EX_VI := DataHoldBypass(Mux1H(Seq(
1027    normalCSRValid -> permitMod.io.out.EX_VI,
1028    waitIMSICValid -> imsic_EX_VI,
1029  )), false.B, normalCSRValid || waitIMSICValid)
1030  io.out.bits.flushPipe := flushPipe
1031
1032  /** Prepare read data for output */
1033  io.out.bits.rData := DataHoldBypass(
1034    Mux1H(Seq(
1035      io.in.fire -> rdata,
1036      fromAIA.rdata.valid -> fromAIA.rdata.bits.data
1037    )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid)
1038  io.out.bits.regOut := regOut
1039  io.out.bits.targetPc := DataHoldBypass(
1040    Mux(trapEntryDEvent.out.targetPc.valid,
1041      trapEntryDEvent.out.targetPc.bits,
1042      Mux1H(Seq(
1043        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
1044        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
1045        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
1046        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
1047        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
1048        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
1049        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
1050        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
1051      )
1052    ),
1053  needTargetUpdate)
1054  io.out.bits.targetPcUpdate := needTargetUpdate
1055  io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire)
1056
1057  io.status.privState := privState
1058  io.status.fpState.frm := fcsr.frm
1059  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
1060  io.status.vecState.vstart := vstart.rdata.asUInt
1061  io.status.vecState.vxsat := vcsr.vxsat
1062  io.status.vecState.vxrm := vcsr.vxrm
1063  io.status.vecState.vcsr := vcsr.rdata.asUInt
1064  io.status.vecState.vl := vl.rdata.asUInt
1065  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
1066  io.status.vecState.vlenb := vlenb.rdata.asUInt
1067  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
1068  io.status.interrupt := intrMod.io.out.interruptVec.valid
1069  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
1070  io.status.debugMode := debugMode
1071  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
1072
1073  /**
1074   * debug_begin
1075   */
1076  val tdata1Selected = Wire(new Tdata1Bundle)
1077  tdata1Selected := tdata1.rdata
1078  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
1079  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
1080  val tdata1Update  = tdata1.w.wen && triggerCanWrite
1081  val tdata2Update  = tdata2.w.wen && triggerCanWrite
1082  val tdata1Vec = tdata1RegVec.map{ mod => {
1083    val tdata1Wire = Wire(new Tdata1Bundle)
1084    tdata1Wire := mod.rdata
1085    tdata1Wire
1086  }}
1087
1088  val triggerCanRaiseBpExp = !(privState.isModeM && !mstatus.regOut.MIE ||
1089    medeleg.regOut.EX_BP && privState.isModeHS && !mstatus.sstatus.SIE ||
1090    medeleg.regOut.EX_BP && hedeleg.regOut.EX_BP && privState.isModeVS && !vsstatus.regOut.SIE)
1091
1092  val debugMod = Module(new Debug)
1093  debugMod.io.in.trapInfo.valid            := hasTrap
1094  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
1095  debugMod.io.in.trapInfo.bits.isDebugIntr := debug
1096  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
1097  debugMod.io.in.trapInfo.bits.trigger     := trigger
1098  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
1099  debugMod.io.in.trapInfo.bits.criticalErrorState := criticalErrorState
1100  debugMod.io.in.privState                 := privState
1101  debugMod.io.in.debugMode                 := debugMode
1102  debugMod.io.in.dcsr                      := dcsr.regOut
1103  debugMod.io.in.tselect                   := tselect.regOut
1104  debugMod.io.in.tdata1Vec                 := tdata1Vec
1105  debugMod.io.in.tdata1Selected            := tdata1.rdata
1106  debugMod.io.in.tdata2Selected            := tdata2.rdata
1107  debugMod.io.in.tdata1Update              := tdata1Update
1108  debugMod.io.in.tdata2Update              := tdata2Update
1109  debugMod.io.in.tdata1Wdata               := wdata
1110  debugMod.io.in.triggerCanRaiseBpExp      := triggerCanRaiseBpExp
1111
1112  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
1113
1114  trapEntryDEvent.valid                           := entryDebugMode
1115  trapEntryDEvent.in.hasDebugIntr                 := debugMod.io.out.hasDebugIntr
1116  trapEntryDEvent.in.debugMode                    := debugMode
1117  trapEntryDEvent.in.hasTrap                      := hasTrap
1118  trapEntryDEvent.in.hasSingleStep                := debugMod.io.out.hasSingleStep
1119  trapEntryDEvent.in.triggerEnterDebugMode        := debugMod.io.out.triggerEnterDebugMode
1120  trapEntryDEvent.in.hasDebugEbreakException      := debugMod.io.out.hasDebugEbreakException
1121  trapEntryDEvent.in.breakPoint                   := debugMod.io.out.breakPoint
1122  trapEntryDEvent.in.criticalErrorStateEnterDebug := debugMod.io.out.criticalErrorStateEnterDebug
1123
1124  tdata1RegVec.foreach { mod =>
1125    mod match {
1126      case m: HasdebugModeBundle =>
1127        m.debugMode := debugMode
1128        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1129      case _ =>
1130    }
1131  }
1132  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1133    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
1134    mod1.w.wdata  := wdata
1135    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
1136    mod2.w.wdata  := wdata
1137  }}
1138
1139  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1140
1141  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
1142  io.status.memTrigger      := debugMod.io.out.memTrigger
1143  /**
1144   * debug_end
1145   */
1146
1147  // trace
1148  val privForTrace = Mux(debugMode,
1149    Priv.D,
1150    Mux1H(
1151      Seq(privState.isModeM, privState.isModeHS, privState.isModeVS, privState.isModeHU, privState.isModeVU),
1152      Seq(Priv.M,            Priv.HS,            Priv.VS,            Priv.HU,            Priv.VU)
1153    )
1154  )
1155  val xret = legalDret || legalMNret || legalMret || legalSret
1156  val currentPriv = privForTrace
1157  val lastPriv = RegEnable(privForTrace, Priv.M, (xret || io.fromRob.trap.valid))
1158
1159  io.status.traceCSR.lastPriv       := lastPriv
1160  io.status.traceCSR.currentPriv    := privForTrace
1161  io.status.traceCSR.cause := Mux1H(
1162    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1163    Seq(mcause.rdata,      scause.rdata,       vscause.rdata)
1164  )
1165  io.status.traceCSR.tval  := Mux1H(
1166    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1167    Seq(mtval.rdata,       stval.rdata,        vstval.rdata)
1168  )
1169
1170  /**
1171   * perf_begin
1172   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1173   */
1174  val csrevents = mhpmevents.slice(24, 29).map(_.rdata)
1175
1176  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1177  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1178    hcEvents(i) := io.perf.perfEventsHc(i)
1179  }
1180
1181  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1182  val allPerfEvents = io.perf.perfEventsFrontend ++
1183    io.perf.perfEventsBackend ++
1184    io.perf.perfEventsLsu ++
1185    hpmHc.getPerf
1186
1187  val countingEn        = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1188  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1189  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1190
1191  for(i <- 0 until perfCntNum) {
1192    mhpmcounters(i) match {
1193      case m: HasPerfCounterBundle =>
1194        m.countingEn        := countingEn(i)
1195        m.perf              := allPerfEvents(i)
1196        ofFromPerfCntVec(i) := m.toMhpmeventOF
1197      case _ =>
1198    }
1199
1200    mhpmevents(i) match {
1201      case m: HasOfFromPerfCntBundle =>
1202        m.ofFromPerfCnt := ofFromPerfCntVec(i)
1203      case _ =>
1204    }
1205
1206    val mhpmevent = Wire(new MhpmeventBundle)
1207    mhpmevent := mhpmevents(i).rdata
1208    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevent.OF.asBool
1209
1210    countingEn(i) := (privState.isModeM && !mhpmevent.MINH) ||
1211      (privState.isModeHS && !mhpmevent.SINH)  ||
1212      (privState.isModeHU && !mhpmevent.UINH)  ||
1213      (privState.isModeVS && !mhpmevent.VSINH) ||
1214      (privState.isModeVU && !mhpmevent.VUINH)
1215  }
1216
1217  val lcofiReq = lcofiReqVec.asUInt.orR
1218  mip match {
1219    case m: HasLocalInterruptReqBundle =>
1220      m.lcofiReq := lcofiReq
1221    case _ =>
1222  }
1223  /**
1224   * perf_end
1225   */
1226
1227  /**
1228   * [[io.status.custom]] connection
1229   */
1230  io.status.custom.pf_ctrl.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1231  io.status.custom.pf_ctrl.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1232  io.status.custom.pf_ctrl.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1233  io.status.custom.pf_ctrl.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1234  io.status.custom.pf_ctrl.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1235  io.status.custom.pf_ctrl.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1236  io.status.custom.pf_ctrl.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1237  io.status.custom.pf_ctrl.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1238  io.status.custom.pf_ctrl.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1239  io.status.custom.pf_ctrl.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1240  io.status.custom.pf_ctrl.l2_pf_recv_enable       := spfctl.regOut.L2_PF_RECV_ENABLE.asBool
1241  io.status.custom.pf_ctrl.l2_pf_pbop_enable       := spfctl.regOut.L2_PF_PBOP_ENABLE.asBool
1242  io.status.custom.pf_ctrl.l2_pf_vbop_enable       := spfctl.regOut.L2_PF_VBOP_ENABLE.asBool
1243  io.status.custom.pf_ctrl.l2_pf_tp_enable         := spfctl.regOut.L2_PF_TP_ENABLE.asBool
1244
1245  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1246  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1247  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1248  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1249  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1250
1251  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1252  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1253  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1254  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1255  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1256  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1257  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1258
1259  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1260  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1261  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1262  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1263  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1264  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
1265  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
1266
1267  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1268  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool && (!io.status.singleStepFlag) && !debugMode
1269
1270  io.status.custom.power_down_enable := mcorepwr.regOut.POWER_DOWN_ENABLE.asBool
1271
1272  io.status.custom.flush_l2_enable := mflushpwr.regOut.FLUSH_L2_ENABLE.asBool
1273
1274  io.status.instrAddrTransType.bare := privState.isModeM ||
1275    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1276    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1277  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1278    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1279  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1280    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1281  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1282  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1283  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1284
1285  private val csrAccess = wenLegalReg || RegNext(ren)
1286
1287  private val imsicAddrValid =
1288    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1289    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1290    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1291
1292  private val imsicAddr = Mux1H(Seq(
1293    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1294    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1295    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1296  ))
1297
1298  private val imsicAddrPrivState = Mux1H(Seq(
1299    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1300    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1301    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1302  ))
1303
1304  private val imsicWdataValid =
1305    mireg.w.wen  && miselect.inIMSICRange ||
1306    sireg.w.wen  && siselect.inIMSICRange ||
1307    vsireg.w.wen && vsiselect.inIMSICRange
1308
1309  toAIA.addr.valid     := imsicAddrValid
1310  toAIA.addr.bits.addr := imsicAddr
1311  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1312  toAIA.addr.bits.v    := imsicAddrPrivState.V
1313
1314  toAIA.wdata.valid := imsicWdataValid
1315  toAIA.wdata.bits.op := RegNext(io.in.bits.op)
1316  toAIA.wdata.bits.data := RegNext(io.in.bits.src)
1317  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1318  toAIA.mClaim  := mtopei.w.wen
1319  toAIA.sClaim  := stopei.w.wen
1320  toAIA.vsClaim := vstopei.w.wen
1321
1322  // tlb
1323  io.tlb.satpASIDChanged  := GatedValidRegNext(satp.w.wen  && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1324  io.tlb.vsatpASIDChanged := GatedValidRegNext(vsatp.w.wen && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1325  io.tlb.hgatpVMIDChanged := GatedValidRegNext(hgatp.w.wen && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1326  io.tlb.satp := satp.rdata
1327  io.tlb.vsatp := vsatp.rdata
1328  io.tlb.hgatp := hgatp.rdata
1329  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1330  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1331  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1332  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1333  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1334
1335  io.tlb.imode := PRVM.asUInt
1336  // when NMIE is zero, force to behave as MPRV is zero
1337  io.tlb.dmode := Mux(
1338    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1339    mstatus.regOut.MPP.asUInt,
1340    PRVM.asUInt
1341  )
1342  io.tlb.dvirt := Mux(
1343    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1344    mstatus.regOut.MPV.asUInt,
1345    V.asUInt
1346  )
1347  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
1348  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1349  io.tlb.pmm.mseccfg := RegNext(mseccfg.regOut.PMM.asUInt)
1350  io.tlb.pmm.menvcfg := RegNext(menvcfg.regOut.PMM.asUInt)
1351  io.tlb.pmm.henvcfg := RegNext(henvcfg.regOut.PMM.asUInt)
1352  io.tlb.pmm.hstatus := RegNext(hstatus.regOut.HUPMM.asUInt)
1353  io.tlb.pmm.senvcfg := RegNext(senvcfg.regOut.PMM.asUInt)
1354
1355  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1356  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1357  io.toDecode.illegalInst.sfencePart := isModeHU
1358  io.toDecode.virtualInst.sfencePart := isModeVU
1359  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1360  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1361  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1362  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
1363  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1364  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1365  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1366  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1367  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1368  io.toDecode.illegalInst.wrs_nto    := !isModeM && mstatus.regOut.TW
1369  io.toDecode.virtualInst.wrs_nto    := privState.V && !mstatus.regOut.TW && hstatus.regOut.VTW
1370  io.toDecode.illegalInst.frm        := frmIsReserved
1371  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1372  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1373  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1374    isModeVS && !henvcfg.regOut.CBZE ||
1375    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1376  )
1377  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1378  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1379    isModeVS && !henvcfg.regOut.CBCFE ||
1380    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1381  )
1382  io.toDecode.illegalInst.cboI       :=
1383    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1384    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1385  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1386    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1387    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1388  )
1389  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1390    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1391    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1392    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1393  )
1394
1395  io.distributedWenLegal := wenLegalReg && !noCSRIllegalReg
1396  io.status.criticalErrorState := criticalErrorState && !dcsr.regOut.CETRIG.asBool
1397
1398  val criticalErrors = Seq(
1399    ("csr_dbltrp_inMN", !mnstatus.regOut.NMIE && hasTrap && !entryDebugMode),
1400  )
1401  criticalErrorStateInCSR := criticalErrors.map(criticalError => criticalError._2).reduce(_ || _).asBool
1402  generateCriticalErrors()
1403
1404  // Always instantiate basic difftest modules.
1405  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1406    // Delay trap passed to difftest until VecExcpMod is not busy
1407    val pendingTrap = RegInit(false.B)
1408    when (hasTrap) {
1409      pendingTrap := true.B
1410    }.elsewhen (!io.fromVecExcpMod.busy) {
1411      pendingTrap := false.B
1412    }
1413
1414    val hartId = io.fromTop.hartId
1415    val trapValid = pendingTrap && !io.fromVecExcpMod.busy
1416    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1417    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1418    val hasNMI = nmi && hasTrap
1419    val interruptNO = Mux(interrupt, trapNO, 0.U)
1420    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1421    val isSv39: Bool =
1422      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
1423      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
1424    val isSv48: Bool =
1425      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
1426      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
1427    val isBare = !isSv39 && !isSv48
1428    val sv39PC = SignExt(trapPC.take(39), XLEN)
1429    val sv48PC = SignExt(trapPC.take(48), XLEN)
1430    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1431    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1432    val exceptionPC = Mux1H(Seq(
1433      isSv39 -> sv39PC,
1434      isSv48 -> sv48PC,
1435      isBare -> barePC,
1436    ))
1437
1438    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1439    diffArchEvent.coreid := hartId
1440    diffArchEvent.valid := trapValid
1441    diffArchEvent.interrupt := RegEnable(interruptNO, hasTrap)
1442    diffArchEvent.exception := RegEnable(exceptionNO, hasTrap)
1443    diffArchEvent.exceptionPC := RegEnable(exceptionPC, hasTrap)
1444    diffArchEvent.hasNMI := RegEnable(hasNMI, hasTrap)
1445    diffArchEvent.virtualInterruptIsHvictlInject := RegNext(virtualInterruptIsHvictlInject && hasTrap)
1446    if (env.EnableDifftest) {
1447      diffArchEvent.exceptionInst := RegEnable(io.fromRob.trap.bits.instr, hasTrap)
1448    }
1449
1450    val diffCriticalErrorEvent = DifftestModule(new DiffCriticalErrorEvent, delay = 4, dontCare = true)
1451    diffCriticalErrorEvent.valid := io.status.criticalErrorState && trapValid
1452    diffCriticalErrorEvent.coreid := hartId
1453    diffCriticalErrorEvent.criticalError := io.status.criticalErrorState
1454
1455    val diffCSRState = DifftestModule(new DiffCSRState)
1456    diffCSRState.coreid         := hartId
1457    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1458    diffCSRState.mstatus        := mstatus.rdata.asUInt
1459    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1460    diffCSRState.mepc           := mepc.rdata.asUInt
1461    diffCSRState.sepc           := sepc.rdata.asUInt
1462    diffCSRState.mtval          := mtval.rdata.asUInt
1463    diffCSRState.stval          := stval.rdata.asUInt
1464    diffCSRState.mtvec          := mtvec.rdata.asUInt
1465    diffCSRState.stvec          := stvec.rdata.asUInt
1466    diffCSRState.mcause         := mcause.rdata.asUInt
1467    diffCSRState.scause         := scause.rdata.asUInt
1468    diffCSRState.satp           := satp.rdata.asUInt
1469    diffCSRState.mip            := mip.rdata.asUInt
1470    diffCSRState.mie            := mie.rdata.asUInt
1471    diffCSRState.mscratch       := mscratch.rdata.asUInt
1472    diffCSRState.sscratch       := sscratch.rdata.asUInt
1473    diffCSRState.mideleg        := mideleg.rdata.asUInt
1474    diffCSRState.medeleg        := medeleg.rdata.asUInt
1475
1476    val diffDebugMode = DifftestModule(new DiffDebugMode)
1477    diffDebugMode.coreid    := hartId
1478    diffDebugMode.debugMode := debugMode
1479    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1480    diffDebugMode.dpc       := dpc.rdata.asUInt
1481    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1482    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1483
1484    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1485    diffTriggerCSRState.coreid    := hartId
1486    diffTriggerCSRState.tselect   := tselect.rdata
1487    diffTriggerCSRState.tdata1    := tdata1.rdata
1488    diffTriggerCSRState.tinfo     := tinfo.rdata
1489
1490    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1491    diffVecCSRState.coreid := hartId
1492    diffVecCSRState.vstart := vstart.rdata.asUInt
1493    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1494    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1495    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1496    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1497    diffVecCSRState.vtype := vtype.rdata.asUInt
1498    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1499
1500    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1501    diffFpCSRState.coreid := hartId
1502    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1503
1504    val diffHCSRState = DifftestModule(new DiffHCSRState)
1505    diffHCSRState.coreid      := hartId
1506    diffHCSRState.virtMode    := privState.V.asBool
1507    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1508    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1509    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1510    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1511    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1512    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1513    diffHCSRState.htval       := htval.rdata.asUInt
1514    diffHCSRState.htinst      := htinst.rdata.asUInt
1515    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1516    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1517    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1518    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1519    diffHCSRState.vscause     := vscause.rdata.asUInt
1520    diffHCSRState.vstval      := vstval.rdata.asUInt
1521    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1522    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1523
1524    val platformIRPMeipChange = !platformIRP.MEIP &&  RegNext(platformIRP.MEIP) ||
1525                                 platformIRP.MEIP && !RegNext(platformIRP.MEIP) ||
1526                                !fromAIA.meip     &&  RegNext(fromAIA.meip)     ||
1527                                 fromAIA.meip     && !RegNext(fromAIA.meip)
1528    val platformIRPMtipChange = !platformIRP.MTIP &&  RegNext(platformIRP.MTIP) || platformIRP.MTIP && !RegNext(platformIRP.MTIP)
1529    val platformIRPMsipChange = !platformIRP.MSIP &&  RegNext(platformIRP.MSIP) || platformIRP.MSIP && !RegNext(platformIRP.MSIP)
1530    val platformIRPSeipChange = !platformIRP.SEIP &&  RegNext(platformIRP.SEIP) ||
1531                                 platformIRP.SEIP && !RegNext(platformIRP.SEIP) ||
1532                                !fromAIA.seip     &&  RegNext(fromAIA.seip)     ||
1533                                 fromAIA.seip     && !RegNext(fromAIA.seip)
1534    val platformIRPStipChange = !sstcIRGen.o.STIP &&  RegNext(sstcIRGen.o.STIP) || sstcIRGen.o.STIP && !RegNext(sstcIRGen.o.STIP)
1535    val platformIRPVseipChange = !platformIRP.VSEIP &&  RegNext(platformIRP.VSEIP) ||
1536                                  platformIRP.VSEIP && !RegNext(platformIRP.VSEIP) ||
1537                                 !hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) &&  RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) ||
1538                                  hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && !RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt))
1539    val platformIRPVstipChange = !sstcIRGen.o.VSTIP && RegNext(sstcIRGen.o.VSTIP) || sstcIRGen.o.VSTIP && !RegNext(sstcIRGen.o.VSTIP)
1540    val lcofiReqChange         = !lcofiReq && RegNext(lcofiReq) || lcofiReq && !RegNext(lcofiReq)
1541
1542    val diffNonRegInterruptPendingEvent = DifftestModule(new DiffNonRegInterruptPendingEvent)
1543    diffNonRegInterruptPendingEvent.coreid           := hartId
1544    diffNonRegInterruptPendingEvent.valid            := platformIRPMeipChange || platformIRPMtipChange || platformIRPMsipChange ||
1545                                                        platformIRPSeipChange || platformIRPStipChange ||
1546                                                        platformIRPVseipChange || platformIRPVstipChange ||
1547                                                        lcofiReqChange
1548    diffNonRegInterruptPendingEvent.platformIRPMeip  := platformIRP.MEIP || fromAIA.meip
1549    diffNonRegInterruptPendingEvent.platformIRPMtip  := platformIRP.MTIP
1550    diffNonRegInterruptPendingEvent.platformIRPMsip  := platformIRP.MSIP
1551    diffNonRegInterruptPendingEvent.platformIRPSeip  := platformIRP.SEIP || fromAIA.seip
1552    diffNonRegInterruptPendingEvent.platformIRPStip  := sstcIRGen.o.STIP
1553    diffNonRegInterruptPendingEvent.platformIRPVseip := platformIRP.VSEIP || hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)
1554    diffNonRegInterruptPendingEvent.platformIRPVstip := sstcIRGen.o.VSTIP
1555    diffNonRegInterruptPendingEvent.localCounterOverflowInterruptReq  := mip.regOut.LCOFIP.asBool
1556
1557    val diffMhpmeventOverflowEvent = DifftestModule(new DiffMhpmeventOverflowEvent)
1558    diffMhpmeventOverflowEvent.coreid := hartId
1559    diffMhpmeventOverflowEvent.valid  := Cat(mhpmevents.zipWithIndex.map{ case (event, i) =>
1560      !ofFromPerfCntVec(i) && RegNext(ofFromPerfCntVec(i)) || ofFromPerfCntVec(i) && !RegNext(ofFromPerfCntVec(i))
1561    }).orR
1562    diffMhpmeventOverflowEvent.mhpmeventOverflow := VecInit(mhpmevents.map(_.regOut.asInstanceOf[MhpmeventBundle].OF.asBool)).asUInt
1563
1564    val diffSyncAIAEvent = DifftestModule(new DiffSyncAIAEvent)
1565    diffSyncAIAEvent.coreid := hartId
1566    diffSyncAIAEvent.valid := fromAIA.rdata.valid
1567    diffSyncAIAEvent.mtopei := mtopei.rdata
1568    diffSyncAIAEvent.stopei := stopei.rdata
1569    diffSyncAIAEvent.vstopei := vstopei.rdata
1570    diffSyncAIAEvent.hgeip := hgeip.rdata
1571
1572    val diffCustomMflushpwr = DifftestModule(new DiffSyncCustomMflushpwrEvent)
1573    diffCustomMflushpwr.coreid := hartId
1574    diffCustomMflushpwr.valid := RegNext(io.fromTop.l2FlushDone) =/= io.fromTop.l2FlushDone
1575    diffCustomMflushpwr.l2FlushDone := io.fromTop.l2FlushDone
1576  }
1577}
1578
1579trait IpIeAliasConnect {
1580  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1581
1582  mip.fromMvip  := mvip.toMip
1583  mip.fromSip   := sip.toMip
1584  mip.fromVSip  := vsip.toMip
1585  mvip.fromMip  := mip.toMvip
1586  mvip.fromSip  := sip.toMvip
1587  mvip.fromVSip := vsip.toMvip
1588  hvip.fromMip  := mip.toHvip
1589  hvip.fromHip  := hip.toHvip
1590  hvip.fromVSip := vsip.toHvip
1591
1592  mie.fromHie  := hie.toMie
1593  mie.fromSie  := sie.toMie
1594  mie.fromVSie := vsie.toMie
1595  sie.fromVSie := vsie.toSie
1596}
1597
1598object NewCSRMain extends App {
1599  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1600    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1601
1602  val defaultConfig = config.alterPartial({
1603    // Get XSCoreParams and pass it to the "small module"
1604    case XSCoreParamsKey => config(XSTileKey).head
1605  })
1606
1607  Generator.execute(
1608    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1609    new NewCSR()(defaultConfig),
1610    firtoolOpts
1611  )
1612
1613  println("done")
1614}