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