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