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