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