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