xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision 5860cb7027869d595fd8baf1ca3b2fb2b937e2a4)
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      case _ =>
599    }
600    mod match {
601      case m: HasIpIeBundle =>
602        m.mideleg := mideleg.regOut
603        m.mip := mip.rdata
604        m.mie := mie.regOut
605        m.mvip := mvip.regOut
606        m.mvien := mvien.regOut
607        m.hideleg := hideleg.regOut
608        m.hip := hip.regOut
609        m.hie := hie.regOut
610        m.hvien := hvien.regOut
611        m.hvip := hvip.regOut
612        m.sip := sip.regOut
613        m.sie := sie.regOut
614        m.vsip := vsip.regOut
615        m.vsie := vsie.regOut
616        m.hgeip := hgeip.regOut
617        m.hgeie := hgeie.regOut
618        m.hstatusVGEIN := hstatus.regOut.VGEIN
619      case _ =>
620    }
621    mod match {
622      case m: HasMhpmeventOfBundle =>
623        m.ofVec := VecInit(mhpmevents.map(event => event.rdata.head(1).asBool)).asUInt //todo:fix
624        m.privState := privState
625        m.mcounteren := mcounteren.rdata
626        m.hcounteren := hcounteren.rdata
627      case _ =>
628    }
629    mod match {
630      case m: HasStateen0Bundle =>
631        m.fromMstateen0 := mstateen0.regOut
632        m.fromHstateen0 := hstateen0.regOut
633        m.privState     := privState
634      case _ =>
635    }
636  }
637
638  csrMods.foreach { mod =>
639    println(s"${mod.modName}: ")
640    println(mod.dumpFields)
641  }
642
643  trapEntryMEvent.valid  := hasTrap && entryPrivState.isModeM && !entryDebugMode  && !debugMode && !nmi
644  trapEntryMNEvent.valid := hasTrap && nmi && !debugMode
645  trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS && !entryDebugMode && !debugMode
646  trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS && !entryDebugMode && !debugMode
647
648  Seq(trapEntryMEvent, trapEntryMNEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod =>
649    eMod.in match {
650      case in: TrapEntryEventInput =>
651        in.causeNO := trapHandleMod.io.out.causeNO
652        in.trapPc := trapPC
653        in.trapPcGPA := trapPCGPA // only used by trapEntryMEvent & trapEntryHSEvent
654        in.trapInst := io.trapInst
655        in.fetchMalTval := io.fetchMalTval
656        in.isCrossPageIPF := trapIsCrossPageIPF
657        in.isHls := trapIsHls
658        in.isFetchMalAddr := trapIsFetchMalAddr
659
660        in.iMode.PRVM := PRVM
661        in.iMode.V := V
662        // when NMIE is zero, force to behave as MPRV is zero
663        in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool && mnstatus.regOut.NMIE.asBool, mstatus.regOut.MPP, PRVM)
664        in.dMode.V := V.asUInt.asBool || mstatus.regOut.MPRV && mnstatus.regOut.NMIE.asBool && (mstatus.regOut.MPP =/= PrivMode.M) && mstatus.regOut.MPV
665
666        in.privState := privState
667        in.mstatus := mstatus.regOut
668        in.hstatus := hstatus.regOut
669        in.sstatus := mstatus.sstatus
670        in.vsstatus := vsstatus.regOut
671        in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec
672        in.tcontrol := tcontrol.regOut
673
674        in.satp  := satp.regOut
675        in.vsatp := vsatp.regOut
676        in.hgatp := hgatp.regOut
677
678        in.memExceptionVAddr := io.fromMem.excpVA
679        in.memExceptionGPAddr := io.fromMem.excpGPA
680
681        in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject
682        in.hvictlIID := hvictl.regOut.IID.asUInt
683    }
684  }
685
686  mnretEvent.valid := legalMNret
687  mnretEvent.in match {
688    case in =>
689      in.mstatus := mstatus.regOut
690      in.mnepc   := mnepc.regOut
691      in.mnstatus:= mnstatus.regOut
692      in.satp := satp.regOut
693      in.vsatp := vsatp.regOut
694      in.hgatp := hgatp.regOut
695  }
696
697  mretEvent.valid := legalMret
698  mretEvent.in match {
699    case in =>
700      in.mstatus := mstatus.regOut
701      in.mepc := mepc.regOut
702      in.tcontrol := tcontrol.regOut
703      in.satp := satp.regOut
704      in.vsatp := vsatp.regOut
705      in.hgatp := hgatp.regOut
706  }
707
708  sretEvent.valid := legalSret
709  sretEvent.in match {
710    case in =>
711      in.privState := privState
712      in.sstatus := mstatus.sstatus
713      in.hstatus := hstatus.regOut
714      in.vsstatus := vsstatus.regOut
715      in.sepc := sepc.regOut
716      in.vsepc := vsepc.regOut
717      in.satp := satp.regOut
718      in.vsatp := vsatp.regOut
719      in.hgatp := hgatp.regOut
720  }
721
722  dretEvent.valid := legalDret
723  dretEvent.in match {
724    case in =>
725      in.dcsr := dcsr.regOut
726      in.dpc  := dpc.regOut
727      in.mstatus := mstatus.regOut
728      in.satp := satp.regOut
729      in.vsatp := vsatp.regOut
730      in.hgatp := hgatp.regOut
731  }
732
733  PRVM := MuxCase(
734    PRVM,
735    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
736      x => x.out match {
737        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
738      }
739    }
740  )
741
742  V := MuxCase(
743    V,
744    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
745      x => x.out match {
746        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
747      }
748    }
749  )
750
751  debugMode := MuxCase(
752    debugMode,
753    Seq(
754      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits,
755      trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits
756    )
757  )
758
759  debugIntrEnable := MuxCase(
760    debugIntrEnable,
761    Seq(
762      dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits,
763      trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits
764    )
765  )
766
767  // perf
768  val addrInPerfCnt = (wen || ren) && (
769    (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
770    (addr === mcountinhibit.addr.U) ||
771    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) ||
772    (addr === CSRs.mip.U) || (addr === CSRs.sip.U) || (addr === CSRs.vsip.U) ||
773    (addr === CSRs.hip.U) || (addr === CSRs.mvip.U) || (addr === CSRs.hvip.U) ||
774    Cat(aiaSkipCSRs.map(_.addr.U === addr)).orR ||
775    (addr === CSRs.menvcfg.U) ||
776    (addr === CSRs.henvcfg.U) ||
777    (addr === CSRs.stimecmp.U)
778  )
779
780  // flush
781  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed
782
783  val floatStatusOnOff = mstatus.w.wen && (
784    mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
785    mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
786  ) || mstatus.wAliasSstatus.wen && (
787    mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
788    mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
789  ) || vsstatus.w.wen && (
790    vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off ||
791    vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off
792  )
793
794  val vectorStatusOnOff = mstatus.w.wen && (
795    mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
796    mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
797  ) || mstatus.wAliasSstatus.wen && (
798    mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
799    mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
800  ) || vsstatus.w.wen && (
801    vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off ||
802    vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off
803  )
804
805  val triggerFrontendChange = Wire(Bool())
806
807  val vstartChange = vstart.w.wen && (
808    vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U ||
809    vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U
810  )
811
812  // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved
813  val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR
814  val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR
815  val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR
816  val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) ||
817    fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved)
818
819  val flushPipe = resetSatp ||
820    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
821    vstartChange || frmChange
822
823  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
824    if (vsMapS.contains(id)) {
825      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
826    } else if (sMapVS.contains(id)) {
827      (!isModeVS && addr === id.U) -> rdata
828    } else {
829      (raddr === id.U) -> rdata
830    }
831  })
832
833  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
834    if (vsMapS.contains(id)) {
835      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
836    } else if (sMapVS.contains(id)) {
837      (!isModeVS && addr === id.U) -> regOut
838    } else {
839      (raddr === id.U) -> regOut
840    }
841  })
842
843  private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
844    trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
845
846  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
847
848  private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3)
849
850  /** the state machine of newCSR module */
851  private val state = RegInit(s_idle)
852  /** the next state of newCSR */
853  private val stateNext = WireInit(state)
854  state := stateNext
855
856  /**
857   * Asynchronous read operation of CSR. Check whether a read is asynchronous when read-enable is high.
858   * AIA registers are designed to be read asynchronously, so newCSR will wait for response.
859   **/
860  private val asyncRead = ren && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && (
861    mireg.addr.U === addr && miselect.inIMSICRange ||
862    sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) ||
863    vsireg.addr.U === addr && vsiselect.inIMSICRange
864  )
865
866  /** State machine of newCSR */
867  switch(state) {
868    is(s_idle) {
869      when(valid && asyncRead) {
870        stateNext := s_waitIMSIC
871      }.elsewhen(valid && !io.out.ready) {
872        stateNext := s_finish
873      }
874    }
875    is(s_waitIMSIC) {
876      when(fromAIA.rdata.valid) {
877        when(io.out.ready) {
878          stateNext := s_idle
879        }.otherwise {
880          stateNext := s_finish
881        }
882      }
883    }
884    is(s_finish) {
885      when(io.out.ready) {
886        stateNext := s_idle
887      }
888    }
889  }
890
891  /** Data that have been read before,and should be stored because output not fired */
892  val rdataReg = RegInit(UInt(64.W), 0.U)
893
894  when(valid && !asyncRead) {
895    rdataReg := rdata
896  }
897
898  // Todo: check IMSIC EX_II and EX_VI
899  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
900  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
901  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
902
903  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
904  io.in.ready := (state === s_idle)
905
906  /**
907   * Valid signal of newCSR output.
908   * When in IDLE state, when input_valid is high, we set it.
909   * When in waitIMSIC state, and the next state is IDLE, we set it.
910   **/
911  io.out.valid := (state === s_idle) && valid && !(asyncRead && fromAIA.rdata.valid) ||
912                  (state === s_waitIMSIC) && fromAIA.rdata.valid ||
913                  (state === s_finish)
914  io.out.bits.EX_II := permitMod.io.out.EX_II || imsic_EX_II || noCSRIllegal
915  io.out.bits.EX_VI := permitMod.io.out.EX_VI || imsic_EX_VI
916
917  io.out.bits.flushPipe := flushPipe
918
919  /** Prepare read data for output */
920  io.out.bits.rData := MuxCase(0.U, Seq(
921    ((state === s_idle) && valid) -> rdata,
922    (state === s_waitIMSIC && fromAIA.rdata.valid) -> fromAIA.rdata.bits.data,
923    (state === s_finish) -> rdataReg,
924  ))
925  io.out.bits.regOut := regOut
926  io.out.bits.targetPc := DataHoldBypass(
927    Mux(trapEntryDEvent.out.targetPc.valid,
928      trapEntryDEvent.out.targetPc.bits,
929      Mux1H(Seq(
930        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
931        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
932        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
933        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
934        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
935        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
936        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
937        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
938      )
939    ),
940  needTargetUpdate)
941  io.out.bits.targetPcUpdate := needTargetUpdate
942  io.out.bits.isPerfCnt := addrInPerfCnt
943
944  io.status.privState := privState
945  io.status.fpState.frm := fcsr.frm
946  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
947  io.status.vecState.vstart := vstart.rdata.asUInt
948  io.status.vecState.vxsat := vcsr.vxsat
949  io.status.vecState.vxrm := vcsr.vxrm
950  io.status.vecState.vcsr := vcsr.rdata.asUInt
951  io.status.vecState.vl := vl.rdata.asUInt
952  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
953  io.status.vecState.vlenb := vlenb.rdata.asUInt
954  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
955  io.status.interrupt := intrMod.io.out.interruptVec.valid
956  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
957  io.status.debugMode := debugMode
958  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
959
960  /**
961   * debug_begin
962   */
963  val tdata1Selected = Wire(new Tdata1Bundle)
964  tdata1Selected := tdata1.rdata
965  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
966  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
967  val tdata1Update  = tdata1.w.wen && triggerCanWrite
968  val tdata2Update  = tdata2.w.wen && triggerCanWrite
969  val tdata1Vec = tdata1RegVec.map{ mod => {
970    val tdata1Wire = Wire(new Tdata1Bundle)
971    tdata1Wire := mod.rdata
972    tdata1Wire
973  }}
974
975  val debugMod = Module(new Debug)
976  debugMod.io.in.trapInfo.valid            := hasTrap
977  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
978  debugMod.io.in.trapInfo.bits.intrVec     := intrVec
979  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
980  debugMod.io.in.trapInfo.bits.trigger     := trigger
981  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
982  debugMod.io.in.privState                 := privState
983  debugMod.io.in.debugMode                 := debugMode
984  debugMod.io.in.dcsr                      := dcsr.regOut
985  debugMod.io.in.tcontrol                  := tcontrol.regOut
986  debugMod.io.in.tselect                   := tselect.regOut
987  debugMod.io.in.tdata1Vec                 := tdata1Vec
988  debugMod.io.in.tdata1Selected            := tdata1.rdata
989  debugMod.io.in.tdata2Selected            := tdata2.rdata
990  debugMod.io.in.tdata1Update              := tdata1Update
991  debugMod.io.in.tdata2Update              := tdata2Update
992  debugMod.io.in.tdata1Wdata               := wdata
993
994  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
995
996  trapEntryDEvent.valid                       := entryDebugMode
997  trapEntryDEvent.in.hasDebugIntr             := debugMod.io.out.hasDebugIntr
998  trapEntryDEvent.in.debugMode                := debugMode
999  trapEntryDEvent.in.hasTrap                  := hasTrap
1000  trapEntryDEvent.in.hasSingleStep            := debugMod.io.out.hasSingleStep
1001  trapEntryDEvent.in.triggerEnterDebugMode    := debugMod.io.out.triggerEnterDebugMode
1002  trapEntryDEvent.in.hasDebugEbreakException  := debugMod.io.out.hasDebugEbreakException
1003  trapEntryDEvent.in.breakPoint               := debugMod.io.out.breakPoint
1004
1005  trapHandleMod.io.in.trapInfo.bits.singleStep  := debugMod.io.out.hasSingleStep
1006
1007  intrMod.io.in.debugMode := debugMode
1008  intrMod.io.in.debugIntr := debugIntr
1009  intrMod.io.in.dcsr      := dcsr.regOut
1010
1011  tdata1RegVec.foreach { mod =>
1012    mod match {
1013      case m: HasdebugModeBundle =>
1014        m.debugMode := debugMode
1015        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1016      case _ =>
1017    }
1018  }
1019  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1020    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
1021    mod1.w.wdata  := wdata
1022    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
1023    mod2.w.wdata  := wdata
1024  }}
1025
1026  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1027
1028  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
1029  io.status.memTrigger      := debugMod.io.out.memTrigger
1030  /**
1031   * debug_end
1032   */
1033
1034  /**
1035   * perf_begin
1036   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1037   */
1038  // tmp: mhpmevents is wrapper of perfEvents, read/write/update mhpmevents -> read/write/update perfEvents
1039  val csrevents = perfEvents.slice(24, 29)
1040
1041  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1042  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1043    hcEvents(i) := io.perf.perfEventsHc(i)
1044  }
1045
1046  val allHcPerfEvents = hcEvents.map(x => (s"Hc", x.value))
1047  if (printEventCoding) {
1048    for (((name, inc), i) <- allHcPerfEvents.zipWithIndex) {
1049      println("HuanCun perfEvents Set", name, inc, i)
1050    }
1051  }
1052
1053  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1054
1055  val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU)
1056  val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1057  for (i <-0 until perfCntNum) {
1058    countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR
1059  }
1060  val allPerfEvents = io.perf.perfEventsFrontend ++
1061    io.perf.perfEventsBackend ++
1062    io.perf.perfEventsLsu ++
1063    hpmHc.getPerf
1064
1065  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1066  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1067  for(i <- 0 until perfCntNum) {
1068    mhpmcounters(i) match {
1069      case m: HasPerfCounterBundle =>
1070        m.countingEn        := countingEn(i)
1071        m.perf              := allPerfEvents(i)
1072        ofFromPerfCntVec(i) := m.toMhpmeventOF
1073      case _ =>
1074    }
1075    perfEvents(i)  := Mux(mhpmevents(i).w.wen, wdata, (perfEvents(i).head(1).asBool || ofFromPerfCntVec(i)) ## perfEvents(i).tail(1))
1076    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1)
1077  }
1078
1079  val lcofiReq = lcofiReqVec.asUInt.orR
1080  mip match {
1081    case m: HasLocalInterruptReqBundle =>
1082      m.lcofiReq := lcofiReq
1083    case _ =>
1084  }
1085  /**
1086   * perf_end
1087   */
1088
1089  /**
1090   * [[io.status.custom]] connection
1091   */
1092  io.status.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1093  io.status.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1094  io.status.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1095  io.status.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1096  io.status.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1097  io.status.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1098  io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1099  io.status.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1100  io.status.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1101  io.status.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1102
1103  io.status.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
1104
1105  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1106  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1107  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1108  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1109  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1110
1111  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1112  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1113  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1114  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1115  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1116  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1117  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1118
1119  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1120  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1121  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1122  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1123  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1124  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
1125  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
1126
1127  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1128  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool
1129
1130  io.status.instrAddrTransType.bare := privState.isModeM ||
1131    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1132    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1133  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1134    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1135  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1136    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1137  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1138  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1139  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1140
1141  private val csrAccess = wen || ren
1142
1143  private val imsicAddrValid =
1144    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1145    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1146    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1147
1148  private val imsicAddr = Mux1H(Seq(
1149    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1150    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1151    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1152  ))
1153
1154  private val imsicAddrPrivState = Mux1H(Seq(
1155    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1156    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1157    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1158  ))
1159
1160  private val imsicWdataValid =
1161    mireg.w.wen  && miselect.inIMSICRange ||
1162    sireg.w.wen  && siselect.inIMSICRange ||
1163    vsireg.w.wen && vsiselect.inIMSICRange
1164
1165  toAIA.addr.valid     := imsicAddrValid
1166  toAIA.addr.bits.addr := imsicAddr
1167  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1168  toAIA.addr.bits.v    := imsicAddrPrivState.V
1169
1170  toAIA.wdata.valid := imsicWdataValid
1171  toAIA.wdata.bits.op := io.in.bits.op
1172  toAIA.wdata.bits.data := io.in.bits.src
1173  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1174  toAIA.mClaim  := mtopei.w.wen
1175  toAIA.sClaim  := stopei.w.wen
1176  toAIA.vsClaim := vstopei.w.wen
1177
1178  // tlb
1179  io.tlb.satpASIDChanged  := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1180  io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1181  io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1182  io.tlb.satp := satp.rdata
1183  io.tlb.vsatp := vsatp.rdata
1184  io.tlb.hgatp := hgatp.rdata
1185  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1186  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1187  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1188  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1189  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1190
1191  io.tlb.imode := PRVM.asUInt
1192  // when NMIE is zero, force to behave as MPRV is zero
1193  io.tlb.dmode := Mux(
1194    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1195    mstatus.regOut.MPP.asUInt,
1196    PRVM.asUInt
1197  )
1198  io.tlb.dvirt := Mux(
1199    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1200    mstatus.regOut.MPV.asUInt,
1201    V.asUInt
1202  )
1203  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
1204  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1205
1206  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1207  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1208  io.toDecode.illegalInst.sfencePart := isModeHU
1209  io.toDecode.virtualInst.sfencePart := isModeVU
1210  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1211  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1212  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1213  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
1214  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1215  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1216  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1217  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1218  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1219  io.toDecode.illegalInst.frm        := frmIsReserved
1220  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1221  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1222  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1223    isModeVS && !henvcfg.regOut.CBZE ||
1224    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1225  )
1226  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1227  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1228    isModeVS && !henvcfg.regOut.CBCFE ||
1229    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1230  )
1231  io.toDecode.illegalInst.cboI       :=
1232    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1233    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1234  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1235    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1236    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1237  )
1238  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1239    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1240    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1241    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1242  )
1243
1244  // Always instantiate basic difftest modules.
1245  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1246    val hartId = io.fromTop.hartId
1247    val trapValid = io.fromRob.trap.valid
1248    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1249    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1250    val hasNMI = nmi && hasTrap
1251    val interruptNO = Mux(interrupt, trapNO, 0.U)
1252    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1253    val isSv39: Bool =
1254      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
1255      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
1256    val isSv48: Bool =
1257      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
1258      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
1259    val isBare = !isSv39 && !isSv48
1260    val sv39PC = SignExt(trapPC.take(39), XLEN)
1261    val sv48PC = SignExt(trapPC.take(48), XLEN)
1262    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1263    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1264    val exceptionPC = Mux1H(Seq(
1265      isSv39 -> sv39PC,
1266      isSv48 -> sv48PC,
1267      isBare -> barePC,
1268    ))
1269
1270    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1271    diffArchEvent.coreid := hartId
1272    diffArchEvent.valid := trapValid
1273    diffArchEvent.interrupt := interruptNO
1274    diffArchEvent.exception := exceptionNO
1275    diffArchEvent.exceptionPC := exceptionPC
1276    diffArchEvent.hasNMI := hasNMI
1277    diffArchEvent.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject && hasTrap
1278    if (env.EnableDifftest) {
1279      diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr
1280    }
1281
1282    val diffCSRState = DifftestModule(new DiffCSRState)
1283    diffCSRState.coreid         := hartId
1284    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1285    diffCSRState.mstatus        := mstatus.rdata.asUInt
1286    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1287    diffCSRState.mepc           := mepc.rdata.asUInt
1288    diffCSRState.sepc           := sepc.rdata.asUInt
1289    diffCSRState.mtval          := mtval.rdata.asUInt
1290    diffCSRState.stval          := stval.rdata.asUInt
1291    diffCSRState.mtvec          := mtvec.rdata.asUInt
1292    diffCSRState.stvec          := stvec.rdata.asUInt
1293    diffCSRState.mcause         := mcause.rdata.asUInt
1294    diffCSRState.scause         := scause.rdata.asUInt
1295    diffCSRState.satp           := satp.rdata.asUInt
1296    diffCSRState.mip            := mip.regOut.asUInt
1297    diffCSRState.mie            := mie.rdata.asUInt
1298    diffCSRState.mscratch       := mscratch.rdata.asUInt
1299    diffCSRState.sscratch       := sscratch.rdata.asUInt
1300    diffCSRState.mideleg        := mideleg.rdata.asUInt
1301    diffCSRState.medeleg        := medeleg.rdata.asUInt
1302
1303    val diffDebugMode = DifftestModule(new DiffDebugMode)
1304    diffDebugMode.coreid    := hartId
1305    diffDebugMode.debugMode := debugMode
1306    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1307    diffDebugMode.dpc       := dpc.rdata.asUInt
1308    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1309    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1310
1311    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1312    diffTriggerCSRState.coreid    := hartId
1313    diffTriggerCSRState.tselect   := tselect.rdata
1314    diffTriggerCSRState.tdata1    := tdata1.rdata
1315    diffTriggerCSRState.tinfo     := tinfo.rdata
1316    diffTriggerCSRState.tcontrol  := tcontrol.rdata
1317
1318    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1319    diffVecCSRState.coreid := hartId
1320    diffVecCSRState.vstart := vstart.rdata.asUInt
1321    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1322    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1323    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1324    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1325    diffVecCSRState.vtype := vtype.rdata.asUInt
1326    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1327
1328    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1329    diffFpCSRState.coreid := hartId
1330    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1331
1332    val diffHCSRState = DifftestModule(new DiffHCSRState)
1333    diffHCSRState.coreid      := hartId
1334    diffHCSRState.virtMode    := privState.V.asBool
1335    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1336    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1337    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1338    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1339    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1340    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1341    diffHCSRState.htval       := htval.rdata.asUInt
1342    diffHCSRState.htinst      := htinst.rdata.asUInt
1343    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1344    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1345    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1346    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1347    diffHCSRState.vscause     := vscause.rdata.asUInt
1348    diffHCSRState.vstval      := vstval.rdata.asUInt
1349    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1350    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1351
1352  }
1353}
1354
1355trait IpIeAliasConnect {
1356  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1357
1358  mip.fromMvip  := mvip.toMip
1359  mip.fromSip   := sip.toMip
1360  mip.fromVSip  := vsip.toMip
1361  mvip.fromMip  := mip.toMvip
1362  mvip.fromSip  := sip.toMvip
1363  mvip.fromVSip := vsip.toMvip
1364  hvip.fromMip  := mip.toHvip
1365  hvip.fromHip  := hip.toHvip
1366  hvip.fromVSip := vsip.toHvip
1367
1368  mie.fromHie  := hie.toMie
1369  mie.fromSie  := sie.toMie
1370  mie.fromVSie := vsie.toMie
1371  sie.fromVSie := vsie.toSie
1372}
1373
1374object NewCSRMain extends App {
1375  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1376    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1377
1378  val defaultConfig = config.alterPartial({
1379    // Get XSCoreParams and pass it to the "small module"
1380    case XSCoreParamsKey => config(XSTileKey).head
1381  })
1382
1383  Generator.execute(
1384    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1385    new NewCSR()(defaultConfig),
1386    firtoolOpts
1387  )
1388
1389  println("done")
1390}