xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision a5cb9e821c8d7e4064be724f0d482d4666f30182)
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    Cat(aiaSkipCSRs.map(_.addr.U === addr)).orR
852  )
853
854  // flush
855  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed
856
857  val floatStatusOnOff = mstatus.w.wen && (
858    mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
859    mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
860  ) || mstatus.wAliasSstatus.wen && (
861    mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
862    mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
863  ) || vsstatus.w.wen && (
864    vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off ||
865    vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off
866  )
867
868  val vectorStatusOnOff = mstatus.w.wen && (
869    mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
870    mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
871  ) || mstatus.wAliasSstatus.wen && (
872    mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
873    mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
874  ) || vsstatus.w.wen && (
875    vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off ||
876    vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off
877  )
878
879  val triggerFrontendChange = Wire(Bool())
880
881  val vstartChange = vstart.w.wen && (
882    vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U ||
883    vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U
884  )
885
886  // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved
887  val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR
888  val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR
889  val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR
890  val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) ||
891    fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved)
892
893  val flushPipe = resetSatp ||
894    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
895    vstartChange || frmChange
896
897  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
898    if (vsMapS.contains(id)) {
899      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
900    } else if (sMapVS.contains(id)) {
901      (!isModeVS && addr === id.U) -> rdata
902    } else {
903      (raddr === id.U) -> rdata
904    }
905  })
906
907  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
908    if (vsMapS.contains(id)) {
909      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
910    } else if (sMapVS.contains(id)) {
911      (!isModeVS && addr === id.U) -> regOut
912    } else {
913      (raddr === id.U) -> regOut
914    }
915  })
916
917  private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
918    trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
919
920  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
921
922  private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3)
923
924  /** the state machine of newCSR module */
925  private val state = RegInit(s_idle)
926  /** the next state of newCSR */
927  private val stateNext = WireInit(state)
928  state := stateNext
929
930  /**
931   * Asynchronous access operation of CSR. Check whether an access is asynchronous when read/write-enable is high.
932   * AIA registers are designed to be access asynchronously, so newCSR will wait for response.
933   **/
934  private val asyncAccess = (wen || ren) && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && (
935    mireg.addr.U === addr && miselect.inIMSICRange ||
936    sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) ||
937    vsireg.addr.U === addr && vsiselect.inIMSICRange
938  )
939
940  /** State machine of newCSR */
941  switch(state) {
942    is(s_idle) {
943      when(valid && asyncAccess) {
944        stateNext := s_waitIMSIC
945      }.elsewhen(valid && !io.out.ready) {
946        stateNext := s_finish
947      }
948    }
949    is(s_waitIMSIC) {
950      when(fromAIA.rdata.valid) {
951        when(io.out.ready) {
952          stateNext := s_idle
953        }.otherwise {
954          stateNext := s_finish
955        }
956      }
957    }
958    is(s_finish) {
959      when(io.out.ready) {
960        stateNext := s_idle
961      }
962    }
963  }
964
965
966  // Todo: check IMSIC EX_II and EX_VI
967  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
968  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
969  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
970
971  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
972  io.in.ready := (state === s_idle)
973
974  /**
975   * Valid signal of newCSR output.
976   * When in IDLE state, when input_valid is high, we set it.
977   * When in waitIMSIC state, and the next state is IDLE, we set it.
978   **/
979
980  /** Data that have been read before,and should be stored because output not fired */
981  val normalCSRValid = state === s_idle && valid && !asyncAccess
982  val waitIMSICValid = state === s_waitIMSIC && fromAIA.rdata.valid
983
984  io.out.valid := normalCSRValid ||
985                  waitIMSICValid ||
986                  state === s_finish
987  io.out.bits.EX_II := DataHoldBypass(Mux1H(Seq(
988    normalCSRValid -> (permitMod.io.out.EX_II || noCSRIllegal),
989    waitIMSICValid -> imsic_EX_II,
990  )), false.B, normalCSRValid || waitIMSICValid)
991  io.out.bits.EX_VI := DataHoldBypass(Mux1H(Seq(
992    normalCSRValid -> permitMod.io.out.EX_VI,
993    waitIMSICValid -> imsic_EX_VI,
994  )), false.B, normalCSRValid || waitIMSICValid)
995  io.out.bits.flushPipe := DataHoldBypass(flushPipe, false.B, io.in.fire)
996
997  /** Prepare read data for output */
998  io.out.bits.rData := DataHoldBypass(
999    Mux1H(Seq(
1000      io.in.fire -> rdata,
1001      fromAIA.rdata.valid -> fromAIA.rdata.bits.data
1002    )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid)
1003  io.out.bits.regOut := regOut
1004  io.out.bits.targetPc := DataHoldBypass(
1005    Mux(trapEntryDEvent.out.targetPc.valid,
1006      trapEntryDEvent.out.targetPc.bits,
1007      Mux1H(Seq(
1008        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
1009        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
1010        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
1011        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
1012        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
1013        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
1014        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
1015        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
1016      )
1017    ),
1018  needTargetUpdate)
1019  io.out.bits.targetPcUpdate := needTargetUpdate
1020  io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire)
1021
1022  io.status.privState := privState
1023  io.status.fpState.frm := fcsr.frm
1024  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
1025  io.status.vecState.vstart := vstart.rdata.asUInt
1026  io.status.vecState.vxsat := vcsr.vxsat
1027  io.status.vecState.vxrm := vcsr.vxrm
1028  io.status.vecState.vcsr := vcsr.rdata.asUInt
1029  io.status.vecState.vl := vl.rdata.asUInt
1030  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
1031  io.status.vecState.vlenb := vlenb.rdata.asUInt
1032  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
1033  io.status.interrupt := intrMod.io.out.interruptVec.valid
1034  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
1035  io.status.debugMode := debugMode
1036  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
1037
1038  /**
1039   * debug_begin
1040   */
1041  val tdata1Selected = Wire(new Tdata1Bundle)
1042  tdata1Selected := tdata1.rdata
1043  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
1044  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
1045  val tdata1Update  = tdata1.w.wen && triggerCanWrite
1046  val tdata2Update  = tdata2.w.wen && triggerCanWrite
1047  val tdata1Vec = tdata1RegVec.map{ mod => {
1048    val tdata1Wire = Wire(new Tdata1Bundle)
1049    tdata1Wire := mod.rdata
1050    tdata1Wire
1051  }}
1052
1053  val triggerCanRaiseBpExp = !(privState.isModeM && !mstatus.regOut.MIE ||
1054    medeleg.regOut.EX_BP && privState.isModeHS && !mstatus.sstatus.SIE ||
1055    medeleg.regOut.EX_BP && hedeleg.regOut.EX_BP && privState.isModeVS && !vsstatus.regOut.SIE)
1056
1057  val debugMod = Module(new Debug)
1058  debugMod.io.in.trapInfo.valid            := hasTrap
1059  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
1060  debugMod.io.in.trapInfo.bits.intrVec     := intrVec
1061  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
1062  debugMod.io.in.trapInfo.bits.trigger     := trigger
1063  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
1064  debugMod.io.in.trapInfo.bits.criticalErrorState := criticalErrorState
1065  debugMod.io.in.privState                 := privState
1066  debugMod.io.in.debugMode                 := debugMode
1067  debugMod.io.in.dcsr                      := dcsr.regOut
1068  debugMod.io.in.tselect                   := tselect.regOut
1069  debugMod.io.in.tdata1Vec                 := tdata1Vec
1070  debugMod.io.in.tdata1Selected            := tdata1.rdata
1071  debugMod.io.in.tdata2Selected            := tdata2.rdata
1072  debugMod.io.in.tdata1Update              := tdata1Update
1073  debugMod.io.in.tdata2Update              := tdata2Update
1074  debugMod.io.in.tdata1Wdata               := wdata
1075  debugMod.io.in.triggerCanRaiseBpExp      := triggerCanRaiseBpExp
1076
1077  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
1078
1079  trapEntryDEvent.valid                           := entryDebugMode
1080  trapEntryDEvent.in.hasDebugIntr                 := debugMod.io.out.hasDebugIntr
1081  trapEntryDEvent.in.debugMode                    := debugMode
1082  trapEntryDEvent.in.hasTrap                      := hasTrap
1083  trapEntryDEvent.in.hasSingleStep                := debugMod.io.out.hasSingleStep
1084  trapEntryDEvent.in.triggerEnterDebugMode        := debugMod.io.out.triggerEnterDebugMode
1085  trapEntryDEvent.in.hasDebugEbreakException      := debugMod.io.out.hasDebugEbreakException
1086  trapEntryDEvent.in.breakPoint                   := debugMod.io.out.breakPoint
1087  trapEntryDEvent.in.criticalErrorStateEnterDebug := debugMod.io.out.criticalErrorStateEnterDebug
1088
1089  tdata1RegVec.foreach { mod =>
1090    mod match {
1091      case m: HasdebugModeBundle =>
1092        m.debugMode := debugMode
1093        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1094      case _ =>
1095    }
1096  }
1097  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1098    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
1099    mod1.w.wdata  := wdata
1100    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
1101    mod2.w.wdata  := wdata
1102  }}
1103
1104  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1105
1106  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
1107  io.status.memTrigger      := debugMod.io.out.memTrigger
1108  /**
1109   * debug_end
1110   */
1111
1112  /**
1113   * perf_begin
1114   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1115   */
1116  val csrevents = mhpmevents.slice(24, 29).map(_.rdata)
1117
1118  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1119  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1120    hcEvents(i) := io.perf.perfEventsHc(i)
1121  }
1122
1123  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1124  val allPerfEvents = io.perf.perfEventsFrontend ++
1125    io.perf.perfEventsBackend ++
1126    io.perf.perfEventsLsu ++
1127    hpmHc.getPerf
1128
1129  val countingEn        = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1130  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1131  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1132
1133  for(i <- 0 until perfCntNum) {
1134    mhpmcounters(i) match {
1135      case m: HasPerfCounterBundle =>
1136        m.countingEn        := countingEn(i)
1137        m.perf              := allPerfEvents(i)
1138        ofFromPerfCntVec(i) := m.toMhpmeventOF
1139      case _ =>
1140    }
1141
1142    mhpmevents(i) match {
1143      case m: HasOfFromPerfCntBundle =>
1144        m.ofFromPerfCnt := ofFromPerfCntVec(i)
1145      case _ =>
1146    }
1147
1148    val mhpmevent = Wire(new MhpmeventBundle)
1149    mhpmevent := mhpmevents(i).rdata
1150    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevent.OF.asBool
1151
1152    countingEn(i) := (privState.isModeM && !mhpmevent.MINH) ||
1153      (privState.isModeHS && !mhpmevent.SINH)  ||
1154      (privState.isModeHU && !mhpmevent.UINH)  ||
1155      (privState.isModeVS && !mhpmevent.VSINH) ||
1156      (privState.isModeVU && !mhpmevent.VUINH)
1157  }
1158
1159  val lcofiReq = lcofiReqVec.asUInt.orR
1160  mip match {
1161    case m: HasLocalInterruptReqBundle =>
1162      m.lcofiReq := lcofiReq
1163    case _ =>
1164  }
1165  /**
1166   * perf_end
1167   */
1168
1169  /**
1170   * [[io.status.custom]] connection
1171   */
1172  io.status.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1173  io.status.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1174  io.status.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1175  io.status.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1176  io.status.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1177  io.status.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1178  io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1179  io.status.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1180  io.status.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1181  io.status.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1182
1183  io.status.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
1184
1185  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1186  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1187  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1188  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1189  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1190
1191  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1192  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1193  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1194  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1195  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1196  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1197  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1198
1199  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1200  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1201  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1202  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1203  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1204  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
1205  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
1206
1207  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1208  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool && (!io.status.singleStepFlag) && !debugMode
1209
1210  io.status.instrAddrTransType.bare := privState.isModeM ||
1211    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1212    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1213  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1214    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1215  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1216    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1217  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1218  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1219  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1220
1221  private val csrAccess = wenLegal || ren
1222
1223  private val imsicAddrValid =
1224    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1225    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1226    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1227
1228  private val imsicAddr = Mux1H(Seq(
1229    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1230    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1231    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1232  ))
1233
1234  private val imsicAddrPrivState = Mux1H(Seq(
1235    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1236    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1237    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1238  ))
1239
1240  private val imsicWdataValid =
1241    mireg.w.wen  && miselect.inIMSICRange ||
1242    sireg.w.wen  && siselect.inIMSICRange ||
1243    vsireg.w.wen && vsiselect.inIMSICRange
1244
1245  toAIA.addr.valid     := imsicAddrValid
1246  toAIA.addr.bits.addr := imsicAddr
1247  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1248  toAIA.addr.bits.v    := imsicAddrPrivState.V
1249
1250  toAIA.wdata.valid := imsicWdataValid
1251  toAIA.wdata.bits.op := io.in.bits.op
1252  toAIA.wdata.bits.data := io.in.bits.src
1253  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1254  toAIA.mClaim  := mtopei.w.wen
1255  toAIA.sClaim  := stopei.w.wen
1256  toAIA.vsClaim := vstopei.w.wen
1257
1258  // tlb
1259  io.tlb.satpASIDChanged  := GatedValidRegNext(satp.w.wen  && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1260  io.tlb.vsatpASIDChanged := GatedValidRegNext(vsatp.w.wen && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1261  io.tlb.hgatpVMIDChanged := GatedValidRegNext(hgatp.w.wen && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1262  io.tlb.satp := satp.rdata
1263  io.tlb.vsatp := vsatp.rdata
1264  io.tlb.hgatp := hgatp.rdata
1265  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1266  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1267  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1268  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1269  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1270
1271  io.tlb.imode := PRVM.asUInt
1272  // when NMIE is zero, force to behave as MPRV is zero
1273  io.tlb.dmode := Mux(
1274    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1275    mstatus.regOut.MPP.asUInt,
1276    PRVM.asUInt
1277  )
1278  io.tlb.dvirt := Mux(
1279    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1280    mstatus.regOut.MPV.asUInt,
1281    V.asUInt
1282  )
1283  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
1284  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1285
1286  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1287  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1288  io.toDecode.illegalInst.sfencePart := isModeHU
1289  io.toDecode.virtualInst.sfencePart := isModeVU
1290  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1291  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1292  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1293  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
1294  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1295  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1296  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1297  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1298  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1299  io.toDecode.illegalInst.frm        := frmIsReserved
1300  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1301  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1302  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1303    isModeVS && !henvcfg.regOut.CBZE ||
1304    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1305  )
1306  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1307  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1308    isModeVS && !henvcfg.regOut.CBCFE ||
1309    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1310  )
1311  io.toDecode.illegalInst.cboI       :=
1312    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1313    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1314  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1315    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1316    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1317  )
1318  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1319    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1320    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1321    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1322  )
1323
1324  io.distributedWenLegal := wenLegal
1325  io.status.criticalErrorState := criticalErrorState && !dcsr.regOut.CETRIG.asBool
1326
1327  val criticalErrors = Seq(
1328    ("csr_dbltrp_inMN", !mnstatus.regOut.NMIE && hasTrap && !entryDebugMode),
1329  )
1330  criticalErrorStateInCSR := criticalErrors.map(criticalError => criticalError._2).reduce(_ || _).asBool
1331  generateCriticalErrors()
1332
1333  // Always instantiate basic difftest modules.
1334  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1335    // Delay trap passed to difftest until VecExcpMod is not busy
1336    val pendingTrap = RegInit(false.B)
1337    when (hasTrap) {
1338      pendingTrap := true.B
1339    }.elsewhen (!io.fromVecExcpMod.busy) {
1340      pendingTrap := false.B
1341    }
1342
1343    val hartId = io.fromTop.hartId
1344    val trapValid = pendingTrap && !io.fromVecExcpMod.busy
1345    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1346    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1347    val hasNMI = nmi && hasTrap
1348    val interruptNO = Mux(interrupt, trapNO, 0.U)
1349    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1350    val isSv39: Bool =
1351      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
1352      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
1353    val isSv48: Bool =
1354      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
1355      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
1356    val isBare = !isSv39 && !isSv48
1357    val sv39PC = SignExt(trapPC.take(39), XLEN)
1358    val sv48PC = SignExt(trapPC.take(48), XLEN)
1359    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1360    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1361    val exceptionPC = Mux1H(Seq(
1362      isSv39 -> sv39PC,
1363      isSv48 -> sv48PC,
1364      isBare -> barePC,
1365    ))
1366
1367    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1368    diffArchEvent.coreid := hartId
1369    diffArchEvent.valid := trapValid
1370    diffArchEvent.interrupt := RegEnable(interruptNO, hasTrap)
1371    diffArchEvent.exception := RegEnable(exceptionNO, hasTrap)
1372    diffArchEvent.exceptionPC := RegEnable(exceptionPC, hasTrap)
1373    diffArchEvent.hasNMI := RegEnable(hasNMI, hasTrap)
1374    diffArchEvent.virtualInterruptIsHvictlInject := RegNext(virtualInterruptIsHvictlInject && hasTrap)
1375    if (env.EnableDifftest) {
1376      diffArchEvent.exceptionInst := RegEnable(io.fromRob.trap.bits.instr, hasTrap)
1377    }
1378
1379    val diffCriticalErrorEvent = DifftestModule(new DiffCriticalErrorEvent, delay = 4, dontCare = true)
1380    diffCriticalErrorEvent.valid := io.status.criticalErrorState && trapValid
1381    diffCriticalErrorEvent.coreid := hartId
1382    diffCriticalErrorEvent.criticalError := io.status.criticalErrorState
1383
1384    val diffCSRState = DifftestModule(new DiffCSRState)
1385    diffCSRState.coreid         := hartId
1386    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1387    diffCSRState.mstatus        := mstatus.rdata.asUInt
1388    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1389    diffCSRState.mepc           := mepc.rdata.asUInt
1390    diffCSRState.sepc           := sepc.rdata.asUInt
1391    diffCSRState.mtval          := mtval.rdata.asUInt
1392    diffCSRState.stval          := stval.rdata.asUInt
1393    diffCSRState.mtvec          := mtvec.rdata.asUInt
1394    diffCSRState.stvec          := stvec.rdata.asUInt
1395    diffCSRState.mcause         := mcause.rdata.asUInt
1396    diffCSRState.scause         := scause.rdata.asUInt
1397    diffCSRState.satp           := satp.rdata.asUInt
1398    diffCSRState.mip            := mip.rdata.asUInt
1399    diffCSRState.mie            := mie.rdata.asUInt
1400    diffCSRState.mscratch       := mscratch.rdata.asUInt
1401    diffCSRState.sscratch       := sscratch.rdata.asUInt
1402    diffCSRState.mideleg        := mideleg.rdata.asUInt
1403    diffCSRState.medeleg        := medeleg.rdata.asUInt
1404
1405    val diffDebugMode = DifftestModule(new DiffDebugMode)
1406    diffDebugMode.coreid    := hartId
1407    diffDebugMode.debugMode := debugMode
1408    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1409    diffDebugMode.dpc       := dpc.rdata.asUInt
1410    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1411    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1412
1413    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1414    diffTriggerCSRState.coreid    := hartId
1415    diffTriggerCSRState.tselect   := tselect.rdata
1416    diffTriggerCSRState.tdata1    := tdata1.rdata
1417    diffTriggerCSRState.tinfo     := tinfo.rdata
1418
1419    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1420    diffVecCSRState.coreid := hartId
1421    diffVecCSRState.vstart := vstart.rdata.asUInt
1422    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1423    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1424    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1425    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1426    diffVecCSRState.vtype := vtype.rdata.asUInt
1427    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1428
1429    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1430    diffFpCSRState.coreid := hartId
1431    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1432
1433    val diffHCSRState = DifftestModule(new DiffHCSRState)
1434    diffHCSRState.coreid      := hartId
1435    diffHCSRState.virtMode    := privState.V.asBool
1436    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1437    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1438    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1439    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1440    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1441    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1442    diffHCSRState.htval       := htval.rdata.asUInt
1443    diffHCSRState.htinst      := htinst.rdata.asUInt
1444    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1445    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1446    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1447    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1448    diffHCSRState.vscause     := vscause.rdata.asUInt
1449    diffHCSRState.vstval      := vstval.rdata.asUInt
1450    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1451    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1452
1453    val platformIRPMeipChange = !platformIRP.MEIP &&  RegNext(platformIRP.MEIP) ||
1454                                 platformIRP.MEIP && !RegNext(platformIRP.MEIP) ||
1455                                !fromAIA.meip     &&  RegNext(fromAIA.meip)     ||
1456                                 fromAIA.meip     && !RegNext(fromAIA.meip)
1457    val platformIRPMtipChange = !platformIRP.MTIP &&  RegNext(platformIRP.MTIP) || platformIRP.MTIP && !RegNext(platformIRP.MTIP)
1458    val platformIRPMsipChange = !platformIRP.MSIP &&  RegNext(platformIRP.MSIP) || platformIRP.MSIP && !RegNext(platformIRP.MSIP)
1459    val platformIRPSeipChange = !platformIRP.SEIP &&  RegNext(platformIRP.SEIP) ||
1460                                 platformIRP.SEIP && !RegNext(platformIRP.SEIP) ||
1461                                !fromAIA.seip     &&  RegNext(fromAIA.seip)     ||
1462                                 fromAIA.seip     && !RegNext(fromAIA.seip)
1463    val platformIRPStipChange = !sstcIRGen.o.STIP &&  RegNext(sstcIRGen.o.STIP) || sstcIRGen.o.STIP && !RegNext(sstcIRGen.o.STIP)
1464    val platformIRPVseipChange = !platformIRP.VSEIP &&  RegNext(platformIRP.VSEIP) ||
1465                                  platformIRP.VSEIP && !RegNext(platformIRP.VSEIP) ||
1466                                 !hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) &&  RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) ||
1467                                  hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && !RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt))
1468    val platformIRPVstipChange = !sstcIRGen.o.VSTIP && RegNext(sstcIRGen.o.VSTIP) || sstcIRGen.o.VSTIP && !RegNext(sstcIRGen.o.VSTIP)
1469    val lcofiReqChange         = !lcofiReq && RegNext(lcofiReq) || lcofiReq && !RegNext(lcofiReq)
1470
1471    val diffNonRegInterruptPendingEvent = DifftestModule(new DiffNonRegInterruptPendingEvent)
1472    diffNonRegInterruptPendingEvent.coreid           := hartId
1473    diffNonRegInterruptPendingEvent.valid            := platformIRPMeipChange || platformIRPMtipChange || platformIRPMsipChange ||
1474                                                        platformIRPSeipChange || platformIRPStipChange ||
1475                                                        platformIRPVseipChange || platformIRPVstipChange ||
1476                                                        lcofiReqChange
1477    diffNonRegInterruptPendingEvent.platformIRPMeip  := platformIRP.MEIP || fromAIA.meip
1478    diffNonRegInterruptPendingEvent.platformIRPMtip  := platformIRP.MTIP
1479    diffNonRegInterruptPendingEvent.platformIRPMsip  := platformIRP.MSIP
1480    diffNonRegInterruptPendingEvent.platformIRPSeip  := platformIRP.SEIP || fromAIA.seip
1481    diffNonRegInterruptPendingEvent.platformIRPStip  := sstcIRGen.o.STIP
1482    diffNonRegInterruptPendingEvent.platformIRPVseip := platformIRP.VSEIP || hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)
1483    diffNonRegInterruptPendingEvent.platformIRPVstip := sstcIRGen.o.VSTIP
1484    diffNonRegInterruptPendingEvent.localCounterOverflowInterruptReq  := mip.regOut.LCOFIP.asBool
1485
1486    val diffMhpmeventOverflowEvent = DifftestModule(new DiffMhpmeventOverflowEvent)
1487    diffMhpmeventOverflowEvent.coreid := hartId
1488    diffMhpmeventOverflowEvent.valid  := Cat(mhpmevents.zipWithIndex.map{ case (event, i) =>
1489      !ofFromPerfCntVec(i) && RegNext(ofFromPerfCntVec(i)) || ofFromPerfCntVec(i) && !RegNext(ofFromPerfCntVec(i))
1490    }).orR
1491    diffMhpmeventOverflowEvent.mhpmeventOverflow := VecInit(mhpmevents.map(_.regOut.asInstanceOf[MhpmeventBundle].OF.asBool)).asUInt
1492
1493  }
1494}
1495
1496trait IpIeAliasConnect {
1497  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1498
1499  mip.fromMvip  := mvip.toMip
1500  mip.fromSip   := sip.toMip
1501  mip.fromVSip  := vsip.toMip
1502  mvip.fromMip  := mip.toMvip
1503  mvip.fromSip  := sip.toMvip
1504  mvip.fromVSip := vsip.toMvip
1505  hvip.fromMip  := mip.toHvip
1506  hvip.fromHip  := hip.toHvip
1507  hvip.fromVSip := vsip.toHvip
1508
1509  mie.fromHie  := hie.toMie
1510  mie.fromSie  := sie.toMie
1511  mie.fromVSie := vsie.toMie
1512  sie.fromVSie := vsie.toSie
1513}
1514
1515object NewCSRMain extends App {
1516  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1517    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1518
1519  val defaultConfig = config.alterPartial({
1520    // Get XSCoreParams and pass it to the "small module"
1521    case XSCoreParamsKey => config(XSTileKey).head
1522  })
1523
1524  Generator.execute(
1525    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1526    new NewCSR()(defaultConfig),
1527    firtoolOpts
1528  )
1529
1530  println("done")
1531}