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