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