xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision c0beb497532ef1deb7aabb86deefe9ae4e4be55e)
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 = 41 // only Sv39 and Sv39x4
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 = 36
52
53  final val AddrWidthInPage = 12
54
55  final val PMPAddrWidth = 36
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 triggerCf = new TriggerCf
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 triggerCf = io.fromRob.trap.bits.triggerCf
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 = Wire(Bool())
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
594  trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS && !entryDebugMode
595  trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS && !entryDebugMode
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  val flushPipe = resetSatp ||
736    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
737    vstartChange
738
739  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
740    if (vsMapS.contains(id)) {
741      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
742    } else if (sMapVS.contains(id)) {
743      (!isModeVS && addr === id.U) -> rdata
744    } else {
745      (raddr === id.U) -> rdata
746    }
747  })
748
749  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
750    if (vsMapS.contains(id)) {
751      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
752    } else if (sMapVS.contains(id)) {
753      (!isModeVS && addr === id.U) -> regOut
754    } else {
755      (raddr === id.U) -> regOut
756    }
757  })
758
759  private val needTargetUpdate = mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
760    trapEntryMEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
761
762  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
763
764  private val s_idle :: s_waitIMSIC :: Nil = Enum(2)
765
766  private val state = RegInit(s_idle)
767  private val stateNext = WireInit(state)
768  state := stateNext
769
770  private val asyncRead = ren && (
771    mireg.addr.U === addr && miselect.inIMSICRange ||
772      sireg.addr.U === addr && siselect.inIMSICRange ||
773      vsireg.addr.U === addr && vsiselect.inIMSICRange
774    )
775
776  switch(state) {
777    is(s_idle) {
778      when(asyncRead) {
779        stateNext := s_waitIMSIC
780      }
781    }
782    is(s_waitIMSIC) {
783      when(fromAIA.rdata.valid) {
784        stateNext := s_idle
785      }
786    }
787  }
788
789  // Todo: check IMSIC EX_II and EX_VI
790  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
791  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
792  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
793
794  io.out.valid :=
795    io.in.valid && stateNext === s_idle ||
796    state === s_waitIMSIC && stateNext === s_idle
797  io.out.bits.EX_II := permitMod.io.out.EX_II || imsic_EX_II || noCSRIllegal
798  io.out.bits.EX_VI := permitMod.io.out.EX_VI || imsic_EX_VI
799  io.out.bits.flushPipe := flushPipe
800
801  io.out.bits.rData := MuxCase(0.U, Seq(
802    (state === s_waitIMSIC && stateNext === s_idle) -> fromAIA.rdata.bits.data,
803    ren -> rdata,
804  ))
805  io.out.bits.regOut := regOut
806  io.out.bits.targetPc := DataHoldBypass(
807    Mux(trapEntryDEvent.out.targetPc.valid,
808      trapEntryDEvent.out.targetPc.bits,
809      Mux1H(Seq(
810        mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits,
811        sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits,
812        dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits,
813        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
814        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
815        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
816      )
817    ),
818  needTargetUpdate)
819  io.out.bits.isPerfCnt := addrInPerfCnt
820
821  io.status.privState := privState
822  io.status.fpState.frm := fcsr.frm
823  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
824  io.status.vecState.vstart := vstart.rdata.asUInt
825  io.status.vecState.vxsat := vcsr.vxsat
826  io.status.vecState.vxrm := vcsr.vxrm
827  io.status.vecState.vcsr := vcsr.rdata.asUInt
828  io.status.vecState.vl := vl.rdata.asUInt
829  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
830  io.status.vecState.vlenb := vlenb.rdata.asUInt
831  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
832  io.status.interrupt := intrMod.io.out.interruptVec.valid
833  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
834  io.status.debugMode := debugMode
835  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
836
837  /**
838   * debug_begin
839   */
840
841  val tdata1Update  = tdata1.w.wen
842  val tdata2Update  = tdata2.w.wen
843  val tdata1Vec = tdata1RegVec.map{ mod => {
844    val tdata1Wire = Wire(new Tdata1Bundle)
845    tdata1Wire := mod.rdata
846    tdata1Wire
847  }}
848
849  val debugMod = Module(new Debug)
850  debugMod.io.in.trapInfo.valid            := hasTrap
851  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
852  debugMod.io.in.trapInfo.bits.intrVec     := intrVec
853  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
854  debugMod.io.in.trapInfo.bits.triggerCf   := triggerCf
855  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
856  debugMod.io.in.privState                 := privState
857  debugMod.io.in.debugMode                 := debugMode
858  debugMod.io.in.dcsr                      := dcsr.regOut
859  debugMod.io.in.tcontrol                  := tcontrol.regOut
860  debugMod.io.in.tselect                   := tselect.regOut
861  debugMod.io.in.tdata1Vec                 := tdata1Vec
862  debugMod.io.in.tdata1Selected            := tdata1.rdata
863  debugMod.io.in.tdata2Selected            := tdata2.rdata
864  debugMod.io.in.tdata1Update              := tdata1Update
865  debugMod.io.in.tdata2Update              := tdata2Update
866  debugMod.io.in.tdata1Wdata               := wdata
867
868  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
869
870  trapEntryDEvent.valid                       := entryDebugMode
871  trapEntryDEvent.in.hasDebugIntr             := debugMod.io.out.hasDebugIntr
872  trapEntryDEvent.in.debugMode                := debugMode
873  trapEntryDEvent.in.hasTrap                  := hasTrap
874  trapEntryDEvent.in.hasSingleStep            := debugMod.io.out.hasSingleStep
875  trapEntryDEvent.in.hasTriggerFire           := debugMod.io.out.hasTriggerFire
876  trapEntryDEvent.in.hasDebugEbreakException  := debugMod.io.out.hasDebugEbreakException
877  trapEntryDEvent.in.breakPoint               := debugMod.io.out.breakPoint
878
879  trapHandleMod.io.in.trapInfo.bits.singleStep  := debugMod.io.out.hasSingleStep
880  trapHandleMod.io.in.trapInfo.bits.triggerFire := debugMod.io.out.triggerCanFire
881
882  intrMod.io.in.debugMode := debugMode
883  intrMod.io.in.debugIntr := debugIntr
884  intrMod.io.in.dcsr      := dcsr.regOut
885
886  tdata1RegVec.foreach { mod =>
887    mod match {
888      case m: HasdebugModeBundle =>
889        m.debugMode := debugMode
890        m.chainable := debugMod.io.out.newTriggerChainIsLegal
891      case _ =>
892    }
893  }
894  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
895    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
896    mod1.w.wdata  := wdata
897    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
898    mod2.w.wdata  := wdata
899  }}
900
901  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
902
903  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
904  io.status.memTrigger      := debugMod.io.out.memTrigger
905  /**
906   * debug_end
907   */
908
909  /**
910   * perf_begin
911   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
912   */
913  // tmp: mhpmevents is wrapper of perfEvents, read/write/update mhpmevents -> read/write/update perfEvents
914  for (i <-0 until perfCntNum) {
915    when(mhpmevents(i).w.wen) {
916      perfEvents(i) := wdata
917    }
918  }
919  val csrevents = perfEvents.slice(24, 29)
920
921  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
922  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
923    hcEvents(i) := io.perf.perfEventsHc(i)
924  }
925
926  val allHcPerfEvents = hcEvents.map(x => (s"Hc", x.value))
927  if (printEventCoding) {
928    for (((name, inc), i) <- allHcPerfEvents.zipWithIndex) {
929      println("HuanCun perfEvents Set", name, inc, i)
930    }
931  }
932
933  val hpmHc = HPerfMonitor(csrevents, hcEvents)
934
935  val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU)
936  val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
937  for (i <-0 until perfCntNum) {
938    countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR
939  }
940  val allPerfEvents = io.perf.perfEventsFrontend ++
941    io.perf.perfEventsBackend ++
942    io.perf.perfEventsLsu ++
943    hpmHc.getPerf
944
945  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
946  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
947  for(i <- 0 until perfCntNum) {
948    mhpmcounters(i) match {
949      case m: HasPerfCounterBundle =>
950        m.countingEn        := countingEn(i)
951        m.perf              := allPerfEvents(i)
952        ofFromPerfCntVec(i) := m.toMhpmeventOF
953      case _ =>
954    }
955    perfEvents(i)   := (perfEvents(i).head(1).asBool || ofFromPerfCntVec(i)) ## perfEvents(i).tail(1)
956    lcofiReqVec(i)  := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1)
957  }
958
959  val lcofiReq = lcofiReqVec.asUInt.orR
960  mip match {
961    case m: HasLocalInterruptReqBundle =>
962      m.lcofiReq := lcofiReq
963    case _ =>
964  }
965  /**
966   * perf_end
967   */
968
969  /**
970   * [[io.status.custom]] connection
971   */
972  io.status.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
973  io.status.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
974  io.status.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
975  io.status.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
976  io.status.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
977  io.status.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
978  io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
979  io.status.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
980  io.status.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
981  io.status.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
982
983  io.status.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
984
985  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
986  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
987  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
988  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
989  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
990
991  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
992  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
993  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
994  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
995  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
996  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
997  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
998
999  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1000  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1001  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1002  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1003  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1004
1005  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1006  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool
1007
1008  private val csrAccess = wen || ren
1009
1010  private val imsicAddrValid =
1011    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1012    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1013    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1014
1015  private val imsicAddr = Mux1H(Seq(
1016    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1017    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1018    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1019  ))
1020
1021  private val imsicAddrPrivState = Mux1H(Seq(
1022    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1023    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1024    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1025  ))
1026
1027  private val imsicWdataValid =
1028    mireg.w.wen  && miselect.inIMSICRange ||
1029    sireg.w.wen  && siselect.inIMSICRange ||
1030    vsireg.w.wen && vsiselect.inIMSICRange
1031
1032  toAIA.addr.valid     := imsicAddrValid
1033  toAIA.addr.bits.addr := imsicAddr
1034  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1035  toAIA.addr.bits.v    := imsicAddrPrivState.V
1036
1037  toAIA.wdata.valid := imsicWdataValid
1038  toAIA.wdata.bits.op := io.in.bits.op
1039  toAIA.wdata.bits.data := io.in.bits.src
1040  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1041  toAIA.mClaim  := mtopei.w.wen
1042  toAIA.sClaim  := stopei.w.wen
1043  toAIA.vsClaim := vstopei.w.wen
1044
1045  // tlb
1046  io.tlb.satpASIDChanged  := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1047  io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1048  io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1049  io.tlb.satp := satp.rdata
1050  io.tlb.vsatp := vsatp.rdata
1051  io.tlb.hgatp := hgatp.rdata
1052  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1053  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1054  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1055  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1056  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1057
1058  io.tlb.imode := PRVM.asUInt
1059  io.tlb.dmode := Mux(
1060    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV,
1061    mstatus.regOut.MPP.asUInt,
1062    PRVM.asUInt
1063  )
1064  io.tlb.dvirt := Mux(
1065    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mstatus.regOut.MPP =/= PrivMode.M,
1066    mstatus.regOut.MPV.asUInt,
1067    V.asUInt
1068  )
1069
1070  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1071  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1072  io.toDecode.illegalInst.sfencePart := isModeHU
1073  io.toDecode.virtualInst.sfencePart := isModeVU
1074  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1075  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1076  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1077  io.toDecode.illegalInst.hlsv       := isModeHU && hstatus.regOut.HU
1078  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1079  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1080  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1081  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1082  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1083
1084  // Always instantiate basic difftest modules.
1085  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1086    val hartId = io.fromTop.hartId
1087    val trapValid = io.fromRob.trap.valid
1088    val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt
1089    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1090    val interruptNO = Mux(interrupt, trapNO, 0.U)
1091    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1092    val ivmHS = isModeHS &&  satp.regOut.MODE =/= SatpMode.Bare
1093    val ivmVS = isModeVS && vsatp.regOut.MODE =/= SatpMode.Bare
1094    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1095    val exceptionPC = Mux(ivmHS || ivmVS, SignExt(trapPC, XLEN), ZeroExt(trapPC, XLEN))
1096
1097    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1098    diffArchEvent.coreid := hartId
1099    diffArchEvent.valid := trapValid
1100    diffArchEvent.interrupt := interruptNO
1101    diffArchEvent.exception := exceptionNO
1102    diffArchEvent.exceptionPC := exceptionPC
1103    if (env.EnableDifftest) {
1104      diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr
1105    }
1106
1107    val diffCSRState = DifftestModule(new DiffCSRState)
1108    diffCSRState.coreid         := hartId
1109    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1110    diffCSRState.mstatus        := mstatus.rdata.asUInt
1111    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1112    diffCSRState.mepc           := mepc.rdata.asUInt
1113    diffCSRState.sepc           := sepc.rdata.asUInt
1114    diffCSRState.mtval          := mtval.rdata.asUInt
1115    diffCSRState.stval          := stval.rdata.asUInt
1116    diffCSRState.mtvec          := mtvec.rdata.asUInt
1117    diffCSRState.stvec          := stvec.rdata.asUInt
1118    diffCSRState.mcause         := mcause.rdata.asUInt
1119    diffCSRState.scause         := scause.rdata.asUInt
1120    diffCSRState.satp           := satp.rdata.asUInt
1121    diffCSRState.mip            := mip.regOut.asUInt
1122    diffCSRState.mie            := mie.rdata.asUInt
1123    diffCSRState.mscratch       := mscratch.rdata.asUInt
1124    diffCSRState.sscratch       := sscratch.rdata.asUInt
1125    diffCSRState.mideleg        := mideleg.rdata.asUInt
1126    diffCSRState.medeleg        := medeleg.rdata.asUInt
1127
1128    val diffDebugMode = DifftestModule(new DiffDebugMode)
1129    diffDebugMode.coreid    := hartId
1130    diffDebugMode.debugMode := debugMode
1131    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1132    diffDebugMode.dpc       := dpc.rdata.asUInt
1133    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1134    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1135
1136    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1137    diffTriggerCSRState.coreid    := hartId
1138    diffTriggerCSRState.tselect   := tselect.rdata
1139    diffTriggerCSRState.tdata1    := tdata1.rdata
1140    diffTriggerCSRState.tinfo     := tinfo.rdata
1141    diffTriggerCSRState.tcontrol  := tcontrol.rdata
1142
1143    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1144    diffVecCSRState.coreid := hartId
1145    diffVecCSRState.vstart := vstart.rdata.asUInt
1146    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1147    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1148    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1149    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1150    diffVecCSRState.vtype := vtype.rdata.asUInt
1151    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1152
1153    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1154    diffFpCSRState.coreid := hartId
1155    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1156
1157    val diffHCSRState = DifftestModule(new DiffHCSRState)
1158    diffHCSRState.coreid      := hartId
1159    diffHCSRState.virtMode    := privState.V.asBool
1160    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1161    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1162    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1163    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1164    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1165    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1166    diffHCSRState.htval       := htval.rdata.asUInt
1167    diffHCSRState.htinst      := htinst.rdata.asUInt
1168    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1169    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1170    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1171    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1172    diffHCSRState.vscause     := vscause.rdata.asUInt
1173    diffHCSRState.vstval      := vstval.rdata.asUInt
1174    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1175    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1176
1177  }
1178}
1179
1180trait IpIeAliasConnect {
1181  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1182
1183  mip.fromMvip  := mvip.toMip
1184  mip.fromSip   := sip.toMip
1185  mip.fromVSip  := vsip.toMip
1186  mvip.fromMip  := mip.toMvip
1187  mvip.fromSip  := sip.toMvip
1188  mvip.fromVSip := vsip.toMvip
1189  hvip.fromMip  := mip.toHvip
1190  hvip.fromHip  := hip.toHvip
1191  hvip.fromVSip := vsip.toHvip
1192
1193  mie.fromHie  := hie.toMie
1194  mie.fromSie  := sie.toMie
1195  mie.fromVSie := vsie.toMie
1196  sie.fromVSie := vsie.toSie
1197}
1198
1199object NewCSRMain extends App {
1200  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1201    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1202
1203  val defaultConfig = config.alterPartial({
1204    // Get XSCoreParams and pass it to the "small module"
1205    case XSCoreParamsKey => config(XSTileKey).head
1206  })
1207
1208  Generator.execute(
1209    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1210    new NewCSR()(defaultConfig),
1211    firtoolOpts
1212  )
1213
1214  println("done")
1215}