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