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