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