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