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