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