xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision 6683fc49ec7b83860c24b77ed5d96eb0bee19928)
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 rwMask = 0xc00
994  private val csrOutMapFilter = csrOutMap.filter { case (id, _) => (id & rwMask) != rwMask }
995
996  private val regOut = Mux1H(csrOutMapFilter.map { case (id, regOut) =>
997    if (vsMapS.contains(id)) {
998      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
999    } else if (sMapVS.contains(id)) {
1000      (!isModeVS && addr === id.U) -> regOut
1001    } else {
1002      (raddr === id.U) -> regOut
1003    }
1004  })
1005
1006  private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
1007    trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
1008
1009  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
1010
1011  private val noCSRIllegalReg = RegEnable(noCSRIllegal, ren || wen)
1012
1013  private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3)
1014
1015  /** the state machine of newCSR module */
1016  private val state = RegInit(s_idle)
1017  /** the next state of newCSR */
1018  private val stateNext = WireInit(state)
1019  state := stateNext
1020
1021  /**
1022   * Asynchronous access operation of CSR. Check whether an access is asynchronous when read/write-enable is high.
1023   * AIA registers are designed to be access asynchronously, so newCSR will wait for response.
1024   **/
1025  private val asyncAccess = (wen || ren) && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && (
1026    mireg.addr.U === addr && miselect.inIMSICRange ||
1027    sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) ||
1028    vsireg.addr.U === addr && vsiselect.inIMSICRange
1029  )
1030
1031  /** State machine of newCSR */
1032  switch(state) {
1033    is(s_idle) {
1034      when(valid && redirectFlush) {
1035        stateNext := s_idle
1036      }.elsewhen(valid && asyncAccess) {
1037        stateNext := s_waitIMSIC
1038      }.elsewhen(valid) {
1039        stateNext := s_finish
1040      }
1041    }
1042    is(s_waitIMSIC) {
1043      when(redirectFlush) {
1044        stateNext := s_idle
1045      }.elsewhen(fromAIA.rdata.valid) {
1046        when(io.out.ready) {
1047          stateNext := s_idle
1048        }.otherwise {
1049          stateNext := s_finish
1050        }
1051      }
1052    }
1053    is(s_finish) {
1054      when(redirectFlush || io.out.ready) {
1055        stateNext := s_idle
1056      }
1057    }
1058  }
1059
1060
1061  // Todo: check IMSIC EX_II and EX_VI
1062  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
1063  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
1064  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
1065
1066  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
1067  io.in.ready := (state === s_idle)
1068
1069  /**
1070   * Valid signal of newCSR output.
1071   * When in IDLE state, when input_valid is high, we set it.
1072   * When in waitIMSIC state, and the next state is IDLE, we set it.
1073   **/
1074
1075  /** Data that have been read before,and should be stored because output not fired */
1076  val normalCSRValid = state === s_idle && valid && !asyncAccess
1077  val waitIMSICValid = state === s_waitIMSIC && fromAIA.rdata.valid
1078
1079  io.out.valid := (waitIMSICValid || state === s_finish) && !redirectFlush
1080  io.out.bits.EX_II := DataHoldBypass(Mux1H(Seq(
1081    normalCSRValid -> (permitMod.io.out.EX_II || noCSRIllegal),
1082    waitIMSICValid -> imsic_EX_II,
1083  )), false.B, normalCSRValid || waitIMSICValid)
1084  io.out.bits.EX_VI := DataHoldBypass(Mux1H(Seq(
1085    normalCSRValid -> permitMod.io.out.EX_VI,
1086    waitIMSICValid -> imsic_EX_VI,
1087  )), false.B, normalCSRValid || waitIMSICValid)
1088  io.out.bits.flushPipe := flushPipe
1089
1090  /** Prepare read data for output */
1091  io.out.bits.rData := DataHoldBypass(
1092    Mux1H(Seq(
1093      io.in.fire -> rdata,
1094      fromAIA.rdata.valid -> fromAIA.rdata.bits.data
1095    )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid)
1096  io.out.bits.regOut := regOut
1097  io.out.bits.targetPc := DataHoldBypass(
1098    Mux(trapEntryDEvent.out.targetPc.valid,
1099      trapEntryDEvent.out.targetPc.bits,
1100      Mux1H(Seq(
1101        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
1102        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
1103        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
1104        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
1105        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
1106        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
1107        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
1108        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
1109      )
1110    ),
1111  needTargetUpdate)
1112  io.out.bits.targetPcUpdate := needTargetUpdate
1113  io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire)
1114
1115  io.status.privState := privState
1116  io.status.fpState.frm := fcsr.frm
1117  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
1118  io.status.vecState.vstart := vstart.rdata.asUInt
1119  io.status.vecState.vxsat := vcsr.vxsat
1120  io.status.vecState.vxrm := vcsr.vxrm
1121  io.status.vecState.vcsr := vcsr.rdata.asUInt
1122  io.status.vecState.vl := vl.rdata.asUInt
1123  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
1124  io.status.vecState.vlenb := vlenb.rdata.asUInt
1125  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
1126  io.status.interrupt := intrMod.io.out.interruptVec.valid
1127  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
1128  io.status.debugMode := debugMode
1129  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
1130
1131  /**
1132   * debug_begin
1133   */
1134  val tdata1Selected = Wire(new Tdata1Bundle)
1135  tdata1Selected := tdata1.rdata
1136  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
1137  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
1138  val tdata1Update  = tdata1.w.wen && triggerCanWrite
1139  val tdata2Update  = tdata2.w.wen && triggerCanWrite
1140  val tdata1Vec = tdata1RegVec.map{ mod => {
1141    val tdata1Wire = Wire(new Tdata1Bundle)
1142    tdata1Wire := mod.rdata
1143    tdata1Wire
1144  }}
1145
1146  val triggerCanRaiseBpExp = !(privState.isModeM && !mstatus.regOut.MIE ||
1147    medeleg.regOut.EX_BP && privState.isModeHS && !mstatus.sstatus.SIE ||
1148    medeleg.regOut.EX_BP && hedeleg.regOut.EX_BP && privState.isModeVS && !vsstatus.regOut.SIE)
1149
1150  val debugMod = Module(new Debug)
1151  debugMod.io.in.trapInfo.valid            := hasTrap
1152  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
1153  debugMod.io.in.trapInfo.bits.isDebugIntr := debug
1154  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
1155  debugMod.io.in.trapInfo.bits.trigger     := trigger
1156  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
1157  debugMod.io.in.trapInfo.bits.criticalErrorState := criticalErrorState
1158  debugMod.io.in.privState                 := privState
1159  debugMod.io.in.debugMode                 := debugMode
1160  debugMod.io.in.dcsr                      := dcsr.regOut
1161  debugMod.io.in.tselect                   := tselect.regOut
1162  debugMod.io.in.tdata1Vec                 := tdata1Vec
1163  debugMod.io.in.tdata1Selected            := tdata1.rdata
1164  debugMod.io.in.tdata2Selected            := tdata2.rdata
1165  debugMod.io.in.tdata1Update              := tdata1Update
1166  debugMod.io.in.tdata2Update              := tdata2Update
1167  debugMod.io.in.tdata1Wdata               := wdata
1168  debugMod.io.in.triggerCanRaiseBpExp      := triggerCanRaiseBpExp
1169
1170  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
1171
1172  trapEntryDEvent.valid                           := entryDebugMode
1173  trapEntryDEvent.in.hasDebugIntr                 := debugMod.io.out.hasDebugIntr
1174  trapEntryDEvent.in.debugMode                    := debugMode
1175  trapEntryDEvent.in.hasTrap                      := hasTrap
1176  trapEntryDEvent.in.hasSingleStep                := debugMod.io.out.hasSingleStep
1177  trapEntryDEvent.in.triggerEnterDebugMode        := debugMod.io.out.triggerEnterDebugMode
1178  trapEntryDEvent.in.hasDebugEbreakException      := debugMod.io.out.hasDebugEbreakException
1179  trapEntryDEvent.in.breakPoint                   := debugMod.io.out.breakPoint
1180  trapEntryDEvent.in.criticalErrorStateEnterDebug := debugMod.io.out.criticalErrorStateEnterDebug
1181
1182  for(idx <- 0 until TriggerNum) {
1183    val tdata1Pre = Wire(new Tdata1Bundle)
1184    val mcontrol6Pre = Wire(new Mcontrol6)
1185    tdata1Pre := (if (idx > 0) tdata1RegVec(idx - 1) else tdata1RegVec(idx)).rdata.asUInt
1186    mcontrol6Pre := tdata1Pre.DATA.asUInt
1187    val canWriteDmode = WireInit(false.B)
1188    canWriteDmode := (if(idx > 0) (Mux(mcontrol6Pre.CHAIN.asBool, tdata1Pre.DMODE.asBool && tdata1Pre.TYPE.isLegal, true.B)) && debugMode else debugMode).asBool
1189    tdata1RegVec(idx) match {
1190      case m: HasTriggerBundle =>
1191        m.canWriteDmode := canWriteDmode
1192        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1193      case _ =>
1194    }
1195  }
1196
1197  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1198    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
1199    mod1.w.wdata  := wdata
1200    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
1201    mod2.w.wdata  := wdata
1202  }}
1203
1204  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1205
1206  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
1207  io.status.memTrigger      := debugMod.io.out.memTrigger
1208  /**
1209   * debug_end
1210   */
1211
1212  // trace
1213  val privForTrace = Mux(debugMode,
1214    Priv.D,
1215    Mux1H(
1216      Seq(privState.isModeM, privState.isModeHS, privState.isModeVS, privState.isModeHU, privState.isModeVU),
1217      Seq(Priv.M,            Priv.HS,            Priv.VS,            Priv.HU,            Priv.VU)
1218    )
1219  )
1220  val xret = legalDret || legalMNret || legalMret || legalSret
1221  val currentPriv = privForTrace
1222  val lastPriv = RegEnable(privForTrace, Priv.M, (xret || io.fromRob.trap.valid))
1223
1224  io.status.traceCSR.lastPriv       := lastPriv
1225  io.status.traceCSR.currentPriv    := privForTrace
1226  io.status.traceCSR.cause := Mux1H(
1227    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1228    Seq(mcause.rdata,      scause.rdata,       vscause.rdata)
1229  )
1230  io.status.traceCSR.tval  := Mux1H(
1231    Seq(privState.isModeM, privState.isModeHS, privState.isModeVS),
1232    Seq(mtval.rdata,       stval.rdata,        vstval.rdata)
1233  )
1234
1235  /**
1236   * perf_begin
1237   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1238   */
1239  val csrevents = mhpmevents.slice(24, 29).map(_.rdata)
1240
1241  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1242  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1243    hcEvents(i) := io.perf.perfEventsHc(i)
1244  }
1245
1246  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1247  val allPerfEvents = io.perf.perfEventsFrontend ++
1248    io.perf.perfEventsBackend ++
1249    io.perf.perfEventsLsu ++
1250    hpmHc.getPerf
1251
1252  val countingEn        = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1253  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1254  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1255
1256  for(i <- 0 until perfCntNum) {
1257    mhpmcounters(i) match {
1258      case m: HasPerfCounterBundle =>
1259        m.countingEn        := countingEn(i)
1260        m.perf              := allPerfEvents(i)
1261        ofFromPerfCntVec(i) := m.toMhpmeventOF
1262      case _ =>
1263    }
1264
1265    mhpmevents(i) match {
1266      case m: HasOfFromPerfCntBundle =>
1267        m.ofFromPerfCnt := ofFromPerfCntVec(i)
1268      case _ =>
1269    }
1270
1271    val mhpmevent = Wire(new MhpmeventBundle)
1272    mhpmevent := mhpmevents(i).rdata
1273    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevent.OF.asBool
1274
1275    countingEn(i) := (privState.isModeM && !mhpmevent.MINH) ||
1276      (privState.isModeHS && !mhpmevent.SINH)  ||
1277      (privState.isModeHU && !mhpmevent.UINH)  ||
1278      (privState.isModeVS && !mhpmevent.VSINH) ||
1279      (privState.isModeVU && !mhpmevent.VUINH)
1280  }
1281
1282  val lcofiReq = lcofiReqVec.asUInt.orR
1283  mip match {
1284    case m: HasLocalInterruptReqBundle =>
1285      m.lcofiReq := lcofiReq
1286    case _ =>
1287  }
1288  /**
1289   * perf_end
1290   */
1291
1292  /**
1293   * [[io.status.custom]] connection
1294   */
1295  io.status.custom.pf_ctrl.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1296  io.status.custom.pf_ctrl.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1297  io.status.custom.pf_ctrl.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1298  io.status.custom.pf_ctrl.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1299  io.status.custom.pf_ctrl.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1300  io.status.custom.pf_ctrl.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1301  io.status.custom.pf_ctrl.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1302  io.status.custom.pf_ctrl.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1303  io.status.custom.pf_ctrl.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1304  io.status.custom.pf_ctrl.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1305  io.status.custom.pf_ctrl.l2_pf_recv_enable       := spfctl.regOut.L2_PF_RECV_ENABLE.asBool
1306  io.status.custom.pf_ctrl.l2_pf_pbop_enable       := spfctl.regOut.L2_PF_PBOP_ENABLE.asBool
1307  io.status.custom.pf_ctrl.l2_pf_vbop_enable       := spfctl.regOut.L2_PF_VBOP_ENABLE.asBool
1308  io.status.custom.pf_ctrl.l2_pf_tp_enable         := spfctl.regOut.L2_PF_TP_ENABLE.asBool
1309
1310  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1311  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1312  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1313  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1314  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1315
1316  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1317  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1318  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1319  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1320  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1321  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1322  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1323
1324  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1325  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1326  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1327  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1328  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1329  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
1330  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
1331
1332  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1333  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool && (!io.status.singleStepFlag) && !debugMode
1334
1335  io.status.custom.power_down_enable := mcorepwr.regOut.POWER_DOWN_ENABLE.asBool
1336
1337  io.status.custom.flush_l2_enable := mflushpwr.regOut.FLUSH_L2_ENABLE.asBool
1338
1339  io.status.instrAddrTransType.bare := privState.isModeM ||
1340    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1341    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1342  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1343    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1344  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1345    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1346  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1347  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1348  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1349
1350  private val csrAccess = wenLegalReg || RegNext(ren)
1351
1352  private val imsicAddrValid =
1353    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1354    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1355    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1356
1357  private val imsicAddr = Mux1H(Seq(
1358    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1359    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1360    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1361  ))
1362
1363  private val imsicAddrPrivState = Mux1H(Seq(
1364    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1365    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1366    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1367  ))
1368
1369  private val imsicWdataValid =
1370    mireg.w.wen  && miselect.inIMSICRange ||
1371    sireg.w.wen  && siselect.inIMSICRange ||
1372    vsireg.w.wen && vsiselect.inIMSICRange
1373
1374  toAIA.addr.valid     := imsicAddrValid
1375  toAIA.addr.bits.addr := imsicAddr
1376  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1377  toAIA.addr.bits.v    := imsicAddrPrivState.V
1378
1379  toAIA.wdata.valid := imsicWdataValid
1380  toAIA.wdata.bits.op := RegNext(io.in.bits.op)
1381  toAIA.wdata.bits.data := RegNext(io.in.bits.src)
1382  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1383  toAIA.mClaim  := mtopei.w.wen
1384  toAIA.sClaim  := stopei.w.wen
1385  toAIA.vsClaim := vstopei.w.wen
1386
1387  // tlb
1388  io.tlb.satpASIDChanged  := GatedValidRegNext(satp.w.wen  && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1389  io.tlb.vsatpASIDChanged := GatedValidRegNext(vsatp.w.wen && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1390  io.tlb.hgatpVMIDChanged := GatedValidRegNext(hgatp.w.wen && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1391  io.tlb.satp := satp.rdata
1392  io.tlb.vsatp := vsatp.rdata
1393  io.tlb.hgatp := hgatp.rdata
1394  if (HasBitmapCheck) {
1395    io.tlb.mbmc := mbmc.get.rdata
1396  } else {
1397    io.tlb.mbmc := DontCare
1398  }
1399  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1400  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1401  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1402  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1403  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1404
1405  io.tlb.imode := PRVM.asUInt
1406  // when NMIE is zero, force to behave as MPRV is zero
1407  io.tlb.dmode := Mux(
1408    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1409    mstatus.regOut.MPP.asUInt,
1410    PRVM.asUInt
1411  )
1412  io.tlb.dvirt := Mux(
1413    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1414    mstatus.regOut.MPV.asUInt,
1415    V.asUInt
1416  )
1417  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
1418  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1419  io.tlb.pmm.mseccfg := RegNext(mseccfg.regOut.PMM.asUInt)
1420  io.tlb.pmm.menvcfg := RegNext(menvcfg.regOut.PMM.asUInt)
1421  io.tlb.pmm.henvcfg := RegNext(henvcfg.regOut.PMM.asUInt)
1422  io.tlb.pmm.hstatus := RegNext(hstatus.regOut.HUPMM.asUInt)
1423  io.tlb.pmm.senvcfg := RegNext(senvcfg.regOut.PMM.asUInt)
1424
1425  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1426  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1427  io.toDecode.illegalInst.sfencePart := isModeHU
1428  io.toDecode.virtualInst.sfencePart := isModeVU
1429  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1430  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1431  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1432  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
1433  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1434  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1435  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1436  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1437  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1438  io.toDecode.illegalInst.wrs_nto    := !isModeM && mstatus.regOut.TW
1439  io.toDecode.virtualInst.wrs_nto    := privState.V && !mstatus.regOut.TW && hstatus.regOut.VTW
1440  io.toDecode.illegalInst.frm        := frmIsReserved
1441  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1442  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1443  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1444    isModeVS && !henvcfg.regOut.CBZE ||
1445    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1446  )
1447  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1448  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1449    isModeVS && !henvcfg.regOut.CBCFE ||
1450    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1451  )
1452  io.toDecode.illegalInst.cboI       :=
1453    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1454    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1455  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1456    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1457    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1458  )
1459  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1460    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1461    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1462    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1463  )
1464
1465  io.distributedWenLegal := wenLegalReg && !noCSRIllegalReg
1466  io.status.criticalErrorState := criticalErrorState && !dcsr.regOut.CETRIG.asBool
1467
1468  val criticalErrors = Seq(
1469    ("csr_dbltrp_inMN", !mnstatus.regOut.NMIE && hasTrap && !entryDebugMode),
1470  )
1471  criticalErrorStateInCSR := criticalErrors.map(criticalError => criticalError._2).reduce(_ || _).asBool
1472  generateCriticalErrors()
1473
1474  // Always instantiate basic difftest modules.
1475  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1476    // Delay trap passed to difftest until VecExcpMod is not busy
1477    val pendingTrap = RegInit(false.B)
1478    when (hasTrap) {
1479      pendingTrap := true.B
1480    }.elsewhen (!io.fromVecExcpMod.busy) {
1481      pendingTrap := false.B
1482    }
1483
1484    val hartId = io.fromTop.hartId
1485    val trapValid = pendingTrap && !io.fromVecExcpMod.busy
1486    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1487    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1488    val hasNMI = nmi && hasTrap
1489    val interruptNO = Mux(interrupt, trapNO, 0.U)
1490    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1491    val isSv39: Bool =
1492      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
1493      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
1494    val isSv48: Bool =
1495      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
1496      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
1497    val isBare = !isSv39 && !isSv48
1498    val sv39PC = SignExt(trapPC.take(39), XLEN)
1499    val sv48PC = SignExt(trapPC.take(48), XLEN)
1500    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1501    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1502    val exceptionPC = Mux1H(Seq(
1503      isSv39 -> sv39PC,
1504      isSv48 -> sv48PC,
1505      isBare -> barePC,
1506    ))
1507
1508    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1509    diffArchEvent.coreid := hartId
1510    diffArchEvent.valid := trapValid
1511    diffArchEvent.interrupt := RegEnable(interruptNO, hasTrap)
1512    diffArchEvent.exception := RegEnable(exceptionNO, hasTrap)
1513    diffArchEvent.exceptionPC := RegEnable(exceptionPC, hasTrap)
1514    diffArchEvent.hasNMI := RegEnable(hasNMI, hasTrap)
1515    diffArchEvent.virtualInterruptIsHvictlInject := RegNext(virtualInterruptIsHvictlInject && hasTrap)
1516    diffArchEvent.irToHS := RegEnable(irToHS, hasTrap)
1517    diffArchEvent.irToVS := RegEnable(irToVS, hasTrap)
1518    if (env.EnableDifftest) {
1519      diffArchEvent.exceptionInst := RegEnable(io.fromRob.trap.bits.instr, hasTrap)
1520    }
1521
1522    val diffCriticalErrorEvent = DifftestModule(new DiffCriticalErrorEvent, delay = 4, dontCare = true)
1523    diffCriticalErrorEvent.valid := io.status.criticalErrorState && trapValid
1524    diffCriticalErrorEvent.coreid := hartId
1525    diffCriticalErrorEvent.criticalError := io.status.criticalErrorState
1526
1527    val diffCSRState = DifftestModule(new DiffCSRState)
1528    diffCSRState.coreid         := hartId
1529    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1530    diffCSRState.mstatus        := mstatus.rdata.asUInt
1531    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1532    diffCSRState.mepc           := mepc.rdata.asUInt
1533    diffCSRState.sepc           := sepc.rdata.asUInt
1534    diffCSRState.mtval          := mtval.rdata.asUInt
1535    diffCSRState.stval          := stval.rdata.asUInt
1536    diffCSRState.mtvec          := mtvec.rdata.asUInt
1537    diffCSRState.stvec          := stvec.rdata.asUInt
1538    diffCSRState.mcause         := mcause.rdata.asUInt
1539    diffCSRState.scause         := scause.rdata.asUInt
1540    diffCSRState.satp           := satp.rdata.asUInt
1541    diffCSRState.mip            := mip.rdata.asUInt
1542    diffCSRState.mie            := mie.rdata.asUInt
1543    diffCSRState.mscratch       := mscratch.rdata.asUInt
1544    diffCSRState.sscratch       := sscratch.rdata.asUInt
1545    diffCSRState.mideleg        := mideleg.rdata.asUInt
1546    diffCSRState.medeleg        := medeleg.rdata.asUInt
1547
1548    val diffDebugMode = DifftestModule(new DiffDebugMode)
1549    diffDebugMode.coreid    := hartId
1550    diffDebugMode.debugMode := debugMode
1551    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1552    diffDebugMode.dpc       := dpc.rdata.asUInt
1553    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1554    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1555
1556    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1557    diffTriggerCSRState.coreid    := hartId
1558    diffTriggerCSRState.tselect   := tselect.rdata
1559    diffTriggerCSRState.tdata1    := tdata1.rdata
1560    diffTriggerCSRState.tinfo     := tinfo.rdata
1561
1562    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1563    diffVecCSRState.coreid := hartId
1564    diffVecCSRState.vstart := vstart.rdata.asUInt
1565    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1566    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1567    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1568    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1569    diffVecCSRState.vtype := vtype.rdata.asUInt
1570    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1571
1572    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1573    diffFpCSRState.coreid := hartId
1574    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1575
1576    val diffHCSRState = DifftestModule(new DiffHCSRState)
1577    diffHCSRState.coreid      := hartId
1578    diffHCSRState.virtMode    := privState.V.asBool
1579    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1580    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1581    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1582    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1583    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1584    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1585    diffHCSRState.htval       := htval.rdata.asUInt
1586    diffHCSRState.htinst      := htinst.rdata.asUInt
1587    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1588    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1589    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1590    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1591    diffHCSRState.vscause     := vscause.rdata.asUInt
1592    diffHCSRState.vstval      := vstval.rdata.asUInt
1593    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1594    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1595
1596    val platformIRPMeipChange = !platformIRP.MEIP &&  RegNext(platformIRP.MEIP) || platformIRP.MEIP && !RegNext(platformIRP.MEIP)
1597    val platformIRPMtipChange = !platformIRP.MTIP &&  RegNext(platformIRP.MTIP) || platformIRP.MTIP && !RegNext(platformIRP.MTIP)
1598    val platformIRPMsipChange = !platformIRP.MSIP &&  RegNext(platformIRP.MSIP) || platformIRP.MSIP && !RegNext(platformIRP.MSIP)
1599    val platformIRPSeipChange = !platformIRP.SEIP &&  RegNext(platformIRP.SEIP) || platformIRP.SEIP && !RegNext(platformIRP.SEIP)
1600    val platformIRPStipChange = !sstcIRGen.o.STIP &&  RegNext(sstcIRGen.o.STIP) || sstcIRGen.o.STIP && !RegNext(sstcIRGen.o.STIP)
1601    val platformIRPVseipChange = !platformIRP.VSEIP &&  RegNext(platformIRP.VSEIP) ||
1602                                  platformIRP.VSEIP && !RegNext(platformIRP.VSEIP) ||
1603                                 !hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) &&  RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) ||
1604                                  hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && !RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt))
1605    val platformIRPVstipChange = !sstcIRGen.o.VSTIP && RegNext(sstcIRGen.o.VSTIP) || sstcIRGen.o.VSTIP && !RegNext(sstcIRGen.o.VSTIP)
1606    val fromAIAMeipChange = !fromAIA.meip && RegNext(fromAIA.meip) || fromAIA.meip && !RegNext(fromAIA.meip)
1607    val fromAIASeipChange = !fromAIA.seip && RegNext(fromAIA.seip) || fromAIA.seip && !RegNext(fromAIA.seip)
1608    val lcofiReqChange = !lcofiReq && RegNext(lcofiReq) || lcofiReq && !RegNext(lcofiReq)
1609
1610    val diffNonRegInterruptPendingEvent = DifftestModule(new DiffNonRegInterruptPendingEvent)
1611    diffNonRegInterruptPendingEvent.coreid           := hartId
1612    diffNonRegInterruptPendingEvent.valid            := (platformIRPMeipChange || platformIRPMtipChange || platformIRPMsipChange ||
1613                                                        platformIRPSeipChange || platformIRPStipChange ||
1614                                                        platformIRPVseipChange || platformIRPVstipChange ||
1615                                                        fromAIAMeipChange || fromAIASeipChange ||
1616                                                        lcofiReqChange || RegNext(reset.asBool)) & !reset.asBool
1617    diffNonRegInterruptPendingEvent.platformIRPMeip  := platformIRP.MEIP
1618    diffNonRegInterruptPendingEvent.platformIRPMtip  := platformIRP.MTIP
1619    diffNonRegInterruptPendingEvent.platformIRPMsip  := platformIRP.MSIP
1620    diffNonRegInterruptPendingEvent.platformIRPSeip  := platformIRP.SEIP
1621    diffNonRegInterruptPendingEvent.platformIRPStip  := sstcIRGen.o.STIP
1622    diffNonRegInterruptPendingEvent.platformIRPVseip := platformIRP.VSEIP || hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)
1623    diffNonRegInterruptPendingEvent.platformIRPVstip := sstcIRGen.o.VSTIP
1624    diffNonRegInterruptPendingEvent.fromAIAMeip := fromAIA.meip
1625    diffNonRegInterruptPendingEvent.fromAIASeip := fromAIA.seip
1626    diffNonRegInterruptPendingEvent.localCounterOverflowInterruptReq  := mip.regOut.LCOFIP.asBool
1627
1628    val diffMhpmeventOverflowEvent = DifftestModule(new DiffMhpmeventOverflowEvent)
1629    diffMhpmeventOverflowEvent.coreid := hartId
1630    diffMhpmeventOverflowEvent.valid  := Cat(mhpmevents.zipWithIndex.map{ case (event, i) =>
1631      !ofFromPerfCntVec(i) && RegNext(ofFromPerfCntVec(i)) || ofFromPerfCntVec(i) && !RegNext(ofFromPerfCntVec(i))
1632    }).orR
1633    diffMhpmeventOverflowEvent.mhpmeventOverflow := VecInit(mhpmevents.map(_.regOut.asInstanceOf[MhpmeventBundle].OF.asBool)).asUInt
1634
1635    val mtopeiChange = RegNext(fromAIA.mtopei.asUInt) =/= fromAIA.mtopei.asUInt
1636    val stopeiChange = RegNext(fromAIA.stopei.asUInt) =/= fromAIA.stopei.asUInt
1637    val vstopeiChange = RegNext(hstatus.regOut.VGEIN.asUInt) =/= hstatus.regOut.VGEIN.asUInt
1638    val hgeipChange = RegNext(fromAIA.vseip) =/= fromAIA.vseip
1639
1640    val diffSyncAIAEvent = DifftestModule(new DiffSyncAIAEvent)
1641    diffSyncAIAEvent.coreid := hartId
1642    diffSyncAIAEvent.valid := mtopeiChange || stopeiChange || vstopeiChange || hgeipChange
1643    diffSyncAIAEvent.mtopei := mtopei.rdata
1644    diffSyncAIAEvent.stopei := stopei.rdata
1645    diffSyncAIAEvent.vstopei := vstopei.rdata
1646    diffSyncAIAEvent.hgeip := hgeip.rdata
1647
1648    val diffCustomMflushpwr = DifftestModule(new DiffSyncCustomMflushpwrEvent)
1649    diffCustomMflushpwr.coreid := hartId
1650    diffCustomMflushpwr.valid := RegNext(io.fromTop.l2FlushDone) =/= io.fromTop.l2FlushDone
1651    diffCustomMflushpwr.l2FlushDone := io.fromTop.l2FlushDone
1652  }
1653}
1654
1655trait IpIeAliasConnect {
1656  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1657
1658  mip.fromMvip  := mvip.toMip
1659  mip.fromSip   := sip.toMip
1660  mip.fromVSip  := vsip.toMip
1661  mvip.fromMip  := mip.toMvip
1662  mvip.fromSip  := sip.toMvip
1663  mvip.fromVSip := vsip.toMvip
1664  hvip.fromMip  := mip.toHvip
1665  hvip.fromHip  := hip.toHvip
1666  hvip.fromVSip := vsip.toHvip
1667
1668  mie.fromHie  := hie.toMie
1669  mie.fromSie  := sie.toMie
1670  mie.fromVSie := vsie.toMie
1671  sie.fromVSie := vsie.toSie
1672}
1673
1674object NewCSRMain extends App {
1675  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1676    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1677
1678  val defaultConfig = config.alterPartial({
1679    // Get XSCoreParams and pass it to the "small module"
1680    case XSCoreParamsKey => config(XSTileKey).head
1681  })
1682
1683  Generator.execute(
1684    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1685    new NewCSR()(defaultConfig),
1686    firtoolOpts
1687  )
1688
1689  println("done")
1690}
1691