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