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