xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision c08f49a0dbf6e9ef292ad0b90193d3946d11b1b6)
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
681        in.satp  := satp.regOut
682        in.vsatp := vsatp.regOut
683        in.hgatp := hgatp.regOut
684
685        in.memExceptionVAddr := io.fromMem.excpVA
686        in.memExceptionGPAddr := io.fromMem.excpGPA
687        in.memExceptionIsForVSnonLeafPTE := io.fromMem.excpIsForVSnonLeafPTE
688
689        in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
690        in.hvictlIID := hvictl.regOut.IID.asUInt
691    }
692  }
693
694  mnretEvent.valid := legalMNret
695  mnretEvent.in match {
696    case in =>
697      in.mstatus := mstatus.regOut
698      in.mnepc   := mnepc.regOut
699      in.mnstatus:= mnstatus.regOut
700      in.satp := satp.regOut
701      in.vsatp := vsatp.regOut
702      in.hgatp := hgatp.regOut
703  }
704
705  mretEvent.valid := legalMret
706  mretEvent.in match {
707    case in =>
708      in.mstatus := mstatus.regOut
709      in.mepc := mepc.regOut
710      in.satp := satp.regOut
711      in.vsatp := vsatp.regOut
712      in.hgatp := hgatp.regOut
713  }
714
715  sretEvent.valid := legalSret
716  sretEvent.in match {
717    case in =>
718      in.privState := privState
719      in.sstatus := mstatus.sstatus
720      in.hstatus := hstatus.regOut
721      in.vsstatus := vsstatus.regOut
722      in.sepc := sepc.regOut
723      in.vsepc := vsepc.regOut
724      in.satp := satp.regOut
725      in.vsatp := vsatp.regOut
726      in.hgatp := hgatp.regOut
727  }
728
729  dretEvent.valid := legalDret
730  dretEvent.in match {
731    case in =>
732      in.dcsr := dcsr.regOut
733      in.dpc  := dpc.regOut
734      in.mstatus := mstatus.regOut
735      in.satp := satp.regOut
736      in.vsatp := vsatp.regOut
737      in.hgatp := hgatp.regOut
738  }
739
740  PRVM := MuxCase(
741    PRVM,
742    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
743      x => x.out match {
744        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
745      }
746    }
747  )
748
749  V := MuxCase(
750    V,
751    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
752      x => x.out match {
753        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
754      }
755    }
756  )
757
758  debugMode := MuxCase(
759    debugMode,
760    Seq(
761      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits,
762      trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits
763    )
764  )
765
766  debugIntrEnable := MuxCase(
767    debugIntrEnable,
768    Seq(
769      dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits,
770      trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits
771    )
772  )
773
774  // perf
775  val addrInPerfCnt = (wen || ren) && (
776    (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
777    (addr === mcountinhibit.addr.U) ||
778    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) ||
779    Cat(aiaSkipCSRs.map(_.addr.U === addr)).orR
780  )
781
782  // flush
783  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed
784
785  val floatStatusOnOff = mstatus.w.wen && (
786    mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
787    mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
788  ) || mstatus.wAliasSstatus.wen && (
789    mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
790    mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
791  ) || vsstatus.w.wen && (
792    vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off ||
793    vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off
794  )
795
796  val vectorStatusOnOff = mstatus.w.wen && (
797    mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
798    mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
799  ) || mstatus.wAliasSstatus.wen && (
800    mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
801    mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
802  ) || vsstatus.w.wen && (
803    vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off ||
804    vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off
805  )
806
807  val triggerFrontendChange = Wire(Bool())
808
809  val vstartChange = vstart.w.wen && (
810    vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U ||
811    vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U
812  )
813
814  // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved
815  val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR
816  val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR
817  val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR
818  val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) ||
819    fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved)
820
821  val flushPipe = resetSatp ||
822    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
823    vstartChange || frmChange
824
825  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
826    if (vsMapS.contains(id)) {
827      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
828    } else if (sMapVS.contains(id)) {
829      (!isModeVS && addr === id.U) -> rdata
830    } else {
831      (raddr === id.U) -> rdata
832    }
833  })
834
835  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
836    if (vsMapS.contains(id)) {
837      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
838    } else if (sMapVS.contains(id)) {
839      (!isModeVS && addr === id.U) -> regOut
840    } else {
841      (raddr === id.U) -> regOut
842    }
843  })
844
845  private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
846    trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
847
848  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
849
850  private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3)
851
852  /** the state machine of newCSR module */
853  private val state = RegInit(s_idle)
854  /** the next state of newCSR */
855  private val stateNext = WireInit(state)
856  state := stateNext
857
858  /**
859   * Asynchronous read operation of CSR. Check whether a read is asynchronous when read-enable is high.
860   * AIA registers are designed to be read asynchronously, so newCSR will wait for response.
861   **/
862  private val asyncRead = ren && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && (
863    mireg.addr.U === addr && miselect.inIMSICRange ||
864    sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) ||
865    vsireg.addr.U === addr && vsiselect.inIMSICRange
866  )
867
868  /** State machine of newCSR */
869  switch(state) {
870    is(s_idle) {
871      when(valid && asyncRead) {
872        stateNext := s_waitIMSIC
873      }.elsewhen(valid && !io.out.ready) {
874        stateNext := s_finish
875      }
876    }
877    is(s_waitIMSIC) {
878      when(fromAIA.rdata.valid) {
879        when(io.out.ready) {
880          stateNext := s_idle
881        }.otherwise {
882          stateNext := s_finish
883        }
884      }
885    }
886    is(s_finish) {
887      when(io.out.ready) {
888        stateNext := s_idle
889      }
890    }
891  }
892
893
894  // Todo: check IMSIC EX_II and EX_VI
895  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
896  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
897  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
898
899  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
900  io.in.ready := (state === s_idle)
901
902  /**
903   * Valid signal of newCSR output.
904   * When in IDLE state, when input_valid is high, we set it.
905   * When in waitIMSIC state, and the next state is IDLE, we set it.
906   **/
907
908  /** Data that have been read before,and should be stored because output not fired */
909  io.out.valid := state === s_idle && valid && !asyncRead ||
910                  state === s_waitIMSIC && fromAIA.rdata.valid ||
911                  state === s_finish
912  io.out.bits.EX_II := DataHoldBypass(permitMod.io.out.EX_II || noCSRIllegal, false.B, io.in.fire) ||
913                       DataHoldBypass(imsic_EX_II, false.B, fromAIA.rdata.valid)
914  io.out.bits.EX_VI := DataHoldBypass(permitMod.io.out.EX_VI, false.B, io.in.fire) ||
915                       DataHoldBypass(imsic_EX_VI, false.B, fromAIA.rdata.valid)
916  io.out.bits.flushPipe := DataHoldBypass(flushPipe, false.B, io.in.fire)
917
918  /** Prepare read data for output */
919  io.out.bits.rData := DataHoldBypass(
920    Mux1H(Seq(
921      io.in.fire -> rdata,
922      fromAIA.rdata.valid -> fromAIA.rdata.bits.data
923    )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid)
924  io.out.bits.regOut := regOut
925  io.out.bits.targetPc := DataHoldBypass(
926    Mux(trapEntryDEvent.out.targetPc.valid,
927      trapEntryDEvent.out.targetPc.bits,
928      Mux1H(Seq(
929        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
930        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
931        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
932        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
933        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
934        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
935        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
936        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
937      )
938    ),
939  needTargetUpdate)
940  io.out.bits.targetPcUpdate := DataHoldBypass(needTargetUpdate, false.B, io.in.fire)
941  io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire)
942
943  io.status.privState := privState
944  io.status.fpState.frm := fcsr.frm
945  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
946  io.status.vecState.vstart := vstart.rdata.asUInt
947  io.status.vecState.vxsat := vcsr.vxsat
948  io.status.vecState.vxrm := vcsr.vxrm
949  io.status.vecState.vcsr := vcsr.rdata.asUInt
950  io.status.vecState.vl := vl.rdata.asUInt
951  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
952  io.status.vecState.vlenb := vlenb.rdata.asUInt
953  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
954  io.status.interrupt := intrMod.io.out.interruptVec.valid
955  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
956  io.status.debugMode := debugMode
957  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
958
959  /**
960   * debug_begin
961   */
962  val tdata1Selected = Wire(new Tdata1Bundle)
963  tdata1Selected := tdata1.rdata
964  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
965  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
966  val tdata1Update  = tdata1.w.wen && triggerCanWrite
967  val tdata2Update  = tdata2.w.wen && triggerCanWrite
968  val tdata1Vec = tdata1RegVec.map{ mod => {
969    val tdata1Wire = Wire(new Tdata1Bundle)
970    tdata1Wire := mod.rdata
971    tdata1Wire
972  }}
973
974  val triggerCanRaiseBpExp = !(privState.isModeM && !mstatus.regOut.MIE ||
975    medeleg.regOut.EX_BP && privState.isModeHS && !mstatus.sstatus.SIE ||
976    medeleg.regOut.EX_BP && hedeleg.regOut.EX_BP && privState.isModeVS && !vsstatus.regOut.SIE)
977
978  val debugMod = Module(new Debug)
979  debugMod.io.in.trapInfo.valid            := hasTrap
980  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
981  debugMod.io.in.trapInfo.bits.intrVec     := intrVec
982  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
983  debugMod.io.in.trapInfo.bits.trigger     := trigger
984  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
985  debugMod.io.in.privState                 := privState
986  debugMod.io.in.debugMode                 := debugMode
987  debugMod.io.in.dcsr                      := dcsr.regOut
988  debugMod.io.in.tselect                   := tselect.regOut
989  debugMod.io.in.tdata1Vec                 := tdata1Vec
990  debugMod.io.in.tdata1Selected            := tdata1.rdata
991  debugMod.io.in.tdata2Selected            := tdata2.rdata
992  debugMod.io.in.tdata1Update              := tdata1Update
993  debugMod.io.in.tdata2Update              := tdata2Update
994  debugMod.io.in.tdata1Wdata               := wdata
995  debugMod.io.in.triggerCanRaiseBpExp      := triggerCanRaiseBpExp
996
997  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
998
999  trapEntryDEvent.valid                       := entryDebugMode
1000  trapEntryDEvent.in.hasDebugIntr             := debugMod.io.out.hasDebugIntr
1001  trapEntryDEvent.in.debugMode                := debugMode
1002  trapEntryDEvent.in.hasTrap                  := hasTrap
1003  trapEntryDEvent.in.hasSingleStep            := debugMod.io.out.hasSingleStep
1004  trapEntryDEvent.in.triggerEnterDebugMode    := debugMod.io.out.triggerEnterDebugMode
1005  trapEntryDEvent.in.hasDebugEbreakException  := debugMod.io.out.hasDebugEbreakException
1006  trapEntryDEvent.in.breakPoint               := debugMod.io.out.breakPoint
1007
1008  trapHandleMod.io.in.trapInfo.bits.singleStep  := debugMod.io.out.hasSingleStep
1009
1010  intrMod.io.in.debugMode := debugMode
1011  intrMod.io.in.debugIntr := debugIntr
1012  intrMod.io.in.dcsr      := dcsr.regOut
1013
1014  tdata1RegVec.foreach { mod =>
1015    mod match {
1016      case m: HasdebugModeBundle =>
1017        m.debugMode := debugMode
1018        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1019      case _ =>
1020    }
1021  }
1022  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1023    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
1024    mod1.w.wdata  := wdata
1025    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
1026    mod2.w.wdata  := wdata
1027  }}
1028
1029  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1030
1031  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
1032  io.status.memTrigger      := debugMod.io.out.memTrigger
1033  /**
1034   * debug_end
1035   */
1036
1037  /**
1038   * perf_begin
1039   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1040   */
1041  // tmp: mhpmevents is wrapper of perfEvents, read/write/update mhpmevents -> read/write/update perfEvents
1042  val csrevents = perfEvents.slice(24, 29)
1043
1044  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1045  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1046    hcEvents(i) := io.perf.perfEventsHc(i)
1047  }
1048
1049  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1050
1051  val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU)
1052  val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1053  for (i <-0 until perfCntNum) {
1054    countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR
1055  }
1056  val allPerfEvents = io.perf.perfEventsFrontend ++
1057    io.perf.perfEventsBackend ++
1058    io.perf.perfEventsLsu ++
1059    hpmHc.getPerf
1060
1061  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1062  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1063  for(i <- 0 until perfCntNum) {
1064    mhpmcounters(i) match {
1065      case m: HasPerfCounterBundle =>
1066        m.countingEn        := countingEn(i)
1067        m.perf              := allPerfEvents(i)
1068        ofFromPerfCntVec(i) := m.toMhpmeventOF
1069      case _ =>
1070    }
1071    perfEvents(i)  := Mux(mhpmevents(i).w.wen, wdata, (perfEvents(i).head(1).asBool || ofFromPerfCntVec(i)) ## perfEvents(i).tail(1))
1072    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1)
1073  }
1074
1075  val lcofiReq = lcofiReqVec.asUInt.orR
1076  mip match {
1077    case m: HasLocalInterruptReqBundle =>
1078      m.lcofiReq := lcofiReq
1079    case _ =>
1080  }
1081  /**
1082   * perf_end
1083   */
1084
1085  /**
1086   * [[io.status.custom]] connection
1087   */
1088  io.status.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1089  io.status.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1090  io.status.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1091  io.status.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1092  io.status.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1093  io.status.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1094  io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1095  io.status.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1096  io.status.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1097  io.status.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1098
1099  io.status.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
1100
1101  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1102  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1103  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1104  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1105  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1106
1107  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1108  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1109  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1110  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1111  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1112  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1113  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1114
1115  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1116  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1117  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1118  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1119  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1120  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
1121  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
1122
1123  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1124  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool
1125
1126  io.status.instrAddrTransType.bare := privState.isModeM ||
1127    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1128    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1129  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1130    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1131  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1132    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1133  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1134  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1135  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1136
1137  private val csrAccess = wen || ren
1138
1139  private val imsicAddrValid =
1140    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1141    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1142    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1143
1144  private val imsicAddr = Mux1H(Seq(
1145    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1146    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1147    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1148  ))
1149
1150  private val imsicAddrPrivState = Mux1H(Seq(
1151    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1152    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1153    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1154  ))
1155
1156  private val imsicWdataValid =
1157    mireg.w.wen  && miselect.inIMSICRange ||
1158    sireg.w.wen  && siselect.inIMSICRange ||
1159    vsireg.w.wen && vsiselect.inIMSICRange
1160
1161  toAIA.addr.valid     := imsicAddrValid
1162  toAIA.addr.bits.addr := imsicAddr
1163  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1164  toAIA.addr.bits.v    := imsicAddrPrivState.V
1165
1166  toAIA.wdata.valid := imsicWdataValid
1167  toAIA.wdata.bits.op := io.in.bits.op
1168  toAIA.wdata.bits.data := io.in.bits.src
1169  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1170  toAIA.mClaim  := mtopei.w.wen
1171  toAIA.sClaim  := stopei.w.wen
1172  toAIA.vsClaim := vstopei.w.wen
1173
1174  // tlb
1175  io.tlb.satpASIDChanged  := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1176  io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1177  io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1178  io.tlb.satp := satp.rdata
1179  io.tlb.vsatp := vsatp.rdata
1180  io.tlb.hgatp := hgatp.rdata
1181  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1182  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1183  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1184  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1185  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1186
1187  io.tlb.imode := PRVM.asUInt
1188  // when NMIE is zero, force to behave as MPRV is zero
1189  io.tlb.dmode := Mux(
1190    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1191    mstatus.regOut.MPP.asUInt,
1192    PRVM.asUInt
1193  )
1194  io.tlb.dvirt := Mux(
1195    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1196    mstatus.regOut.MPV.asUInt,
1197    V.asUInt
1198  )
1199  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
1200  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1201
1202  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1203  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1204  io.toDecode.illegalInst.sfencePart := isModeHU
1205  io.toDecode.virtualInst.sfencePart := isModeVU
1206  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1207  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1208  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1209  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
1210  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1211  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1212  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1213  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1214  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1215  io.toDecode.illegalInst.frm        := frmIsReserved
1216  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1217  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1218  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1219    isModeVS && !henvcfg.regOut.CBZE ||
1220    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1221  )
1222  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1223  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1224    isModeVS && !henvcfg.regOut.CBCFE ||
1225    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1226  )
1227  io.toDecode.illegalInst.cboI       :=
1228    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1229    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1230  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1231    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1232    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1233  )
1234  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1235    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1236    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1237    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1238  )
1239
1240  // Always instantiate basic difftest modules.
1241  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1242    // Delay trap passed to difftest until VecExcpMod is not busy
1243    val pendingTrap = RegInit(false.B)
1244    when (hasTrap) {
1245      pendingTrap := true.B
1246    }.elsewhen (!io.fromVecExcpMod.busy) {
1247      pendingTrap := false.B
1248    }
1249
1250    val hartId = io.fromTop.hartId
1251    val trapValid = pendingTrap && !io.fromVecExcpMod.busy
1252    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1253    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1254    val hasNMI = nmi && hasTrap
1255    val interruptNO = Mux(interrupt, trapNO, 0.U)
1256    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1257    val isSv39: Bool =
1258      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
1259      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
1260    val isSv48: Bool =
1261      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
1262      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
1263    val isBare = !isSv39 && !isSv48
1264    val sv39PC = SignExt(trapPC.take(39), XLEN)
1265    val sv48PC = SignExt(trapPC.take(48), XLEN)
1266    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1267    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1268    val exceptionPC = Mux1H(Seq(
1269      isSv39 -> sv39PC,
1270      isSv48 -> sv48PC,
1271      isBare -> barePC,
1272    ))
1273
1274    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1275    diffArchEvent.coreid := hartId
1276    diffArchEvent.valid := trapValid
1277    diffArchEvent.interrupt := RegEnable(interruptNO, hasTrap)
1278    diffArchEvent.exception := RegEnable(exceptionNO, hasTrap)
1279    diffArchEvent.exceptionPC := RegEnable(exceptionPC, hasTrap)
1280    diffArchEvent.hasNMI := RegEnable(hasNMI, hasTrap)
1281    diffArchEvent.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject && hasTrap
1282    if (env.EnableDifftest) {
1283      diffArchEvent.exceptionInst := RegEnable(io.fromRob.trap.bits.instr, hasTrap)
1284    }
1285
1286    val diffCSRState = DifftestModule(new DiffCSRState)
1287    diffCSRState.coreid         := hartId
1288    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1289    diffCSRState.mstatus        := mstatus.rdata.asUInt
1290    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1291    diffCSRState.mepc           := mepc.rdata.asUInt
1292    diffCSRState.sepc           := sepc.rdata.asUInt
1293    diffCSRState.mtval          := mtval.rdata.asUInt
1294    diffCSRState.stval          := stval.rdata.asUInt
1295    diffCSRState.mtvec          := mtvec.rdata.asUInt
1296    diffCSRState.stvec          := stvec.rdata.asUInt
1297    diffCSRState.mcause         := mcause.rdata.asUInt
1298    diffCSRState.scause         := scause.rdata.asUInt
1299    diffCSRState.satp           := satp.rdata.asUInt
1300    diffCSRState.mip            := mip.rdata.asUInt
1301    diffCSRState.mie            := mie.rdata.asUInt
1302    diffCSRState.mscratch       := mscratch.rdata.asUInt
1303    diffCSRState.sscratch       := sscratch.rdata.asUInt
1304    diffCSRState.mideleg        := mideleg.rdata.asUInt
1305    diffCSRState.medeleg        := medeleg.rdata.asUInt
1306
1307    val diffDebugMode = DifftestModule(new DiffDebugMode)
1308    diffDebugMode.coreid    := hartId
1309    diffDebugMode.debugMode := debugMode
1310    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1311    diffDebugMode.dpc       := dpc.rdata.asUInt
1312    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1313    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1314
1315    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1316    diffTriggerCSRState.coreid    := hartId
1317    diffTriggerCSRState.tselect   := tselect.rdata
1318    diffTriggerCSRState.tdata1    := tdata1.rdata
1319    diffTriggerCSRState.tinfo     := tinfo.rdata
1320
1321    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1322    diffVecCSRState.coreid := hartId
1323    diffVecCSRState.vstart := vstart.rdata.asUInt
1324    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1325    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1326    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1327    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1328    diffVecCSRState.vtype := vtype.rdata.asUInt
1329    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1330
1331    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1332    diffFpCSRState.coreid := hartId
1333    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1334
1335    val diffHCSRState = DifftestModule(new DiffHCSRState)
1336    diffHCSRState.coreid      := hartId
1337    diffHCSRState.virtMode    := privState.V.asBool
1338    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1339    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1340    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1341    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1342    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1343    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1344    diffHCSRState.htval       := htval.rdata.asUInt
1345    diffHCSRState.htinst      := htinst.rdata.asUInt
1346    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1347    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1348    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1349    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1350    diffHCSRState.vscause     := vscause.rdata.asUInt
1351    diffHCSRState.vstval      := vstval.rdata.asUInt
1352    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1353    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1354
1355    val platformIRPMeipChange = !platformIRP.MEIP &&  RegNext(platformIRP.MEIP) ||
1356                                 platformIRP.MEIP && !RegNext(platformIRP.MEIP) ||
1357                                !fromAIA.meip     &&  RegNext(fromAIA.meip)     ||
1358                                 fromAIA.meip     && !RegNext(fromAIA.meip)
1359    val platformIRPMtipChange = !platformIRP.MTIP &&  RegNext(platformIRP.MTIP) || platformIRP.MTIP && !RegNext(platformIRP.MTIP)
1360    val platformIRPMsipChange = !platformIRP.MSIP &&  RegNext(platformIRP.MSIP) || platformIRP.MSIP && !RegNext(platformIRP.MSIP)
1361    val platformIRPSeipChange = !platformIRP.SEIP &&  RegNext(platformIRP.SEIP) ||
1362                                 platformIRP.SEIP && !RegNext(platformIRP.SEIP) ||
1363                                !fromAIA.seip     &&  RegNext(fromAIA.seip)     ||
1364                                 fromAIA.seip     && !RegNext(fromAIA.seip)
1365    val platformIRPStipChange = !sstcIRGen.o.STIP &&  RegNext(sstcIRGen.o.STIP) || sstcIRGen.o.STIP && !RegNext(sstcIRGen.o.STIP)
1366    val platformIRPVseipChange = !platformIRP.VSEIP &&  RegNext(platformIRP.VSEIP) ||
1367                                  platformIRP.VSEIP && !RegNext(platformIRP.VSEIP) ||
1368                                 !hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) &&  RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) ||
1369                                  hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && !RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt))
1370    val platformIRPVstipChange = !sstcIRGen.o.VSTIP && RegNext(sstcIRGen.o.VSTIP) || sstcIRGen.o.VSTIP && !RegNext(sstcIRGen.o.VSTIP)
1371    val lcofiReqChange         = !lcofiReq && RegNext(lcofiReq) || lcofiReq && !RegNext(lcofiReq)
1372
1373    val diffNonRegInterruptPendingEvent = DifftestModule(new DiffNonRegInterruptPendingEvent)
1374    diffNonRegInterruptPendingEvent.coreid           := hartId
1375    diffNonRegInterruptPendingEvent.valid            := platformIRPMeipChange || platformIRPMtipChange || platformIRPMsipChange ||
1376                                                        platformIRPSeipChange || platformIRPStipChange ||
1377                                                        platformIRPVseipChange || platformIRPVstipChange ||
1378                                                        lcofiReqChange
1379    diffNonRegInterruptPendingEvent.platformIRPMeip  := platformIRP.MEIP || fromAIA.meip
1380    diffNonRegInterruptPendingEvent.platformIRPMtip  := platformIRP.MTIP
1381    diffNonRegInterruptPendingEvent.platformIRPMsip  := platformIRP.MSIP
1382    diffNonRegInterruptPendingEvent.platformIRPSeip  := platformIRP.SEIP || fromAIA.seip
1383    diffNonRegInterruptPendingEvent.platformIRPStip  := sstcIRGen.o.STIP
1384    diffNonRegInterruptPendingEvent.platformIRPVseip := platformIRP.VSEIP || hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)
1385    diffNonRegInterruptPendingEvent.platformIRPVstip := sstcIRGen.o.VSTIP
1386    diffNonRegInterruptPendingEvent.localCounterOverflowInterruptReq  := lcofiReq
1387
1388  }
1389}
1390
1391trait IpIeAliasConnect {
1392  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1393
1394  mip.fromMvip  := mvip.toMip
1395  mip.fromSip   := sip.toMip
1396  mip.fromVSip  := vsip.toMip
1397  mvip.fromMip  := mip.toMvip
1398  mvip.fromSip  := sip.toMvip
1399  mvip.fromVSip := vsip.toMvip
1400  hvip.fromMip  := mip.toHvip
1401  hvip.fromHip  := hip.toHvip
1402  hvip.fromVSip := vsip.toHvip
1403
1404  mie.fromHie  := hie.toMie
1405  mie.fromSie  := sie.toMie
1406  mie.fromVSie := vsie.toMie
1407  sie.fromVSie := vsie.toSie
1408}
1409
1410object NewCSRMain extends App {
1411  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1412    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1413
1414  val defaultConfig = config.alterPartial({
1415    // Get XSCoreParams and pass it to the "small module"
1416    case XSCoreParamsKey => config(XSTileKey).head
1417  })
1418
1419  Generator.execute(
1420    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1421    new NewCSR()(defaultConfig),
1422    firtoolOpts
1423  )
1424
1425  println("done")
1426}