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