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