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