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