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