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