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