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