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