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