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