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