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