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