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