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