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