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