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