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