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