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