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