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