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