xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision 46e9ee74b05bff567ec23c58a1dde7151176258f)
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.rdataFields
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
897  // Todo: check IMSIC EX_II and EX_VI
898  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
899  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
900  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
901
902  /** Set io.in.ready when state machine is ready to receive a new request synchronously */
903  io.in.ready := (state === s_idle)
904
905  /**
906   * Valid signal of newCSR output.
907   * When in IDLE state, when input_valid is high, we set it.
908   * When in waitIMSIC state, and the next state is IDLE, we set it.
909   **/
910
911  /** Data that have been read before,and should be stored because output not fired */
912  io.out.valid := state === s_idle && valid && !asyncRead ||
913                  state === s_waitIMSIC && fromAIA.rdata.valid ||
914                  state === s_finish
915  io.out.bits.EX_II := DataHoldBypass(permitMod.io.out.EX_II || noCSRIllegal, false.B, io.in.fire) ||
916                       DataHoldBypass(imsic_EX_II, false.B, fromAIA.rdata.valid)
917  io.out.bits.EX_VI := DataHoldBypass(permitMod.io.out.EX_VI, false.B, io.in.fire) ||
918                       DataHoldBypass(imsic_EX_VI, false.B, fromAIA.rdata.valid)
919  io.out.bits.flushPipe := DataHoldBypass(flushPipe, false.B, io.in.fire)
920
921  /** Prepare read data for output */
922  io.out.bits.rData := DataHoldBypass(
923    Mux1H(Seq(
924      io.in.fire -> rdata,
925      fromAIA.rdata.valid -> fromAIA.rdata.bits.data
926    )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid)
927  io.out.bits.regOut := regOut
928  io.out.bits.targetPc := DataHoldBypass(
929    Mux(trapEntryDEvent.out.targetPc.valid,
930      trapEntryDEvent.out.targetPc.bits,
931      Mux1H(Seq(
932        mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits,
933        mretEvent.out.targetPc.valid  -> mretEvent.out.targetPc.bits,
934        sretEvent.out.targetPc.valid  -> sretEvent.out.targetPc.bits,
935        dretEvent.out.targetPc.valid  -> dretEvent.out.targetPc.bits,
936        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
937        trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits,
938        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
939        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
940      )
941    ),
942  needTargetUpdate)
943  io.out.bits.targetPcUpdate := DataHoldBypass(needTargetUpdate, false.B, io.in.fire)
944  io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire)
945
946  io.status.privState := privState
947  io.status.fpState.frm := fcsr.frm
948  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
949  io.status.vecState.vstart := vstart.rdata.asUInt
950  io.status.vecState.vxsat := vcsr.vxsat
951  io.status.vecState.vxrm := vcsr.vxrm
952  io.status.vecState.vcsr := vcsr.rdata.asUInt
953  io.status.vecState.vl := vl.rdata.asUInt
954  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
955  io.status.vecState.vlenb := vlenb.rdata.asUInt
956  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
957  io.status.interrupt := intrMod.io.out.interruptVec.valid
958  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
959  io.status.debugMode := debugMode
960  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
961
962  /**
963   * debug_begin
964   */
965  val tdata1Selected = Wire(new Tdata1Bundle)
966  tdata1Selected := tdata1.rdata
967  val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool
968  val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger
969  val tdata1Update  = tdata1.w.wen && triggerCanWrite
970  val tdata2Update  = tdata2.w.wen && triggerCanWrite
971  val tdata1Vec = tdata1RegVec.map{ mod => {
972    val tdata1Wire = Wire(new Tdata1Bundle)
973    tdata1Wire := mod.rdata
974    tdata1Wire
975  }}
976
977  val debugMod = Module(new Debug)
978  debugMod.io.in.trapInfo.valid            := hasTrap
979  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
980  debugMod.io.in.trapInfo.bits.intrVec     := intrVec
981  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
982  debugMod.io.in.trapInfo.bits.trigger     := trigger
983  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
984  debugMod.io.in.privState                 := privState
985  debugMod.io.in.debugMode                 := debugMode
986  debugMod.io.in.dcsr                      := dcsr.regOut
987  debugMod.io.in.tcontrol                  := tcontrol.regOut
988  debugMod.io.in.tselect                   := tselect.regOut
989  debugMod.io.in.tdata1Vec                 := tdata1Vec
990  debugMod.io.in.tdata1Selected            := tdata1.rdata
991  debugMod.io.in.tdata2Selected            := tdata2.rdata
992  debugMod.io.in.tdata1Update              := tdata1Update
993  debugMod.io.in.tdata2Update              := tdata2Update
994  debugMod.io.in.tdata1Wdata               := wdata
995
996  entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
997
998  trapEntryDEvent.valid                       := entryDebugMode
999  trapEntryDEvent.in.hasDebugIntr             := debugMod.io.out.hasDebugIntr
1000  trapEntryDEvent.in.debugMode                := debugMode
1001  trapEntryDEvent.in.hasTrap                  := hasTrap
1002  trapEntryDEvent.in.hasSingleStep            := debugMod.io.out.hasSingleStep
1003  trapEntryDEvent.in.triggerEnterDebugMode    := debugMod.io.out.triggerEnterDebugMode
1004  trapEntryDEvent.in.hasDebugEbreakException  := debugMod.io.out.hasDebugEbreakException
1005  trapEntryDEvent.in.breakPoint               := debugMod.io.out.breakPoint
1006
1007  trapHandleMod.io.in.trapInfo.bits.singleStep  := debugMod.io.out.hasSingleStep
1008
1009  intrMod.io.in.debugMode := debugMode
1010  intrMod.io.in.debugIntr := debugIntr
1011  intrMod.io.in.dcsr      := dcsr.regOut
1012
1013  tdata1RegVec.foreach { mod =>
1014    mod match {
1015      case m: HasdebugModeBundle =>
1016        m.debugMode := debugMode
1017        m.chainable := debugMod.io.out.newTriggerChainIsLegal
1018      case _ =>
1019    }
1020  }
1021  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
1022    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
1023    mod1.w.wdata  := wdata
1024    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
1025    mod2.w.wdata  := wdata
1026  }}
1027
1028  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
1029
1030  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
1031  io.status.memTrigger      := debugMod.io.out.memTrigger
1032  /**
1033   * debug_end
1034   */
1035
1036  /**
1037   * perf_begin
1038   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
1039   */
1040  // tmp: mhpmevents is wrapper of perfEvents, read/write/update mhpmevents -> read/write/update perfEvents
1041  val csrevents = perfEvents.slice(24, 29)
1042
1043  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
1044  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
1045    hcEvents(i) := io.perf.perfEventsHc(i)
1046  }
1047
1048  val hpmHc = HPerfMonitor(csrevents, hcEvents)
1049
1050  val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU)
1051  val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1052  for (i <-0 until perfCntNum) {
1053    countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR
1054  }
1055  val allPerfEvents = io.perf.perfEventsFrontend ++
1056    io.perf.perfEventsBackend ++
1057    io.perf.perfEventsLsu ++
1058    hpmHc.getPerf
1059
1060  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1061  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1062  for(i <- 0 until perfCntNum) {
1063    mhpmcounters(i) match {
1064      case m: HasPerfCounterBundle =>
1065        m.countingEn        := countingEn(i)
1066        m.perf              := allPerfEvents(i)
1067        ofFromPerfCntVec(i) := m.toMhpmeventOF
1068      case _ =>
1069    }
1070    perfEvents(i)  := Mux(mhpmevents(i).w.wen, wdata, (perfEvents(i).head(1).asBool || ofFromPerfCntVec(i)) ## perfEvents(i).tail(1))
1071    lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1)
1072  }
1073
1074  val lcofiReq = lcofiReqVec.asUInt.orR
1075  mip match {
1076    case m: HasLocalInterruptReqBundle =>
1077      m.lcofiReq := lcofiReq
1078    case _ =>
1079  }
1080  /**
1081   * perf_end
1082   */
1083
1084  /**
1085   * [[io.status.custom]] connection
1086   */
1087  io.status.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1088  io.status.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1089  io.status.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1090  io.status.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1091  io.status.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1092  io.status.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1093  io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1094  io.status.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1095  io.status.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1096  io.status.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1097
1098  io.status.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
1099
1100  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1101  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1102  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1103  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1104  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1105
1106  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1107  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1108  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1109  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1110  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1111  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1112  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1113
1114  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1115  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1116  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1117  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1118  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1119  io.status.custom.hd_misalign_st_enable            := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool
1120  io.status.custom.hd_misalign_ld_enable            := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool
1121
1122  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1123  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool
1124
1125  io.status.instrAddrTransType.bare := privState.isModeM ||
1126    (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) ||
1127    (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare)
1128  io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 ||
1129    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39
1130  io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 ||
1131    privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48
1132  io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4
1133  io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4
1134  assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted")
1135
1136  private val csrAccess = wen || ren
1137
1138  private val imsicAddrValid =
1139    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1140    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1141    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1142
1143  private val imsicAddr = Mux1H(Seq(
1144    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1145    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1146    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1147  ))
1148
1149  private val imsicAddrPrivState = Mux1H(Seq(
1150    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1151    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1152    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1153  ))
1154
1155  private val imsicWdataValid =
1156    mireg.w.wen  && miselect.inIMSICRange ||
1157    sireg.w.wen  && siselect.inIMSICRange ||
1158    vsireg.w.wen && vsiselect.inIMSICRange
1159
1160  toAIA.addr.valid     := imsicAddrValid
1161  toAIA.addr.bits.addr := imsicAddr
1162  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1163  toAIA.addr.bits.v    := imsicAddrPrivState.V
1164
1165  toAIA.wdata.valid := imsicWdataValid
1166  toAIA.wdata.bits.op := io.in.bits.op
1167  toAIA.wdata.bits.data := io.in.bits.src
1168  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1169  toAIA.mClaim  := mtopei.w.wen
1170  toAIA.sClaim  := stopei.w.wen
1171  toAIA.vsClaim := vstopei.w.wen
1172
1173  // tlb
1174  io.tlb.satpASIDChanged  := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1175  io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1176  io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1177  io.tlb.satp := satp.rdata
1178  io.tlb.vsatp := vsatp.rdata
1179  io.tlb.hgatp := hgatp.rdata
1180  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1181  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1182  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1183  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1184  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1185
1186  io.tlb.imode := PRVM.asUInt
1187  // when NMIE is zero, force to behave as MPRV is zero
1188  io.tlb.dmode := Mux(
1189    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE,
1190    mstatus.regOut.MPP.asUInt,
1191    PRVM.asUInt
1192  )
1193  io.tlb.dvirt := Mux(
1194    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M,
1195    mstatus.regOut.MPV.asUInt,
1196    V.asUInt
1197  )
1198  io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool)
1199  io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool)
1200
1201  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1202  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1203  io.toDecode.illegalInst.sfencePart := isModeHU
1204  io.toDecode.virtualInst.sfencePart := isModeVU
1205  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1206  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1207  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1208  io.toDecode.illegalInst.hlsv       := isModeHU && !hstatus.regOut.HU
1209  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1210  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1211  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1212  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1213  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1214  io.toDecode.illegalInst.frm        := frmIsReserved
1215  // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State
1216  io.toDecode.illegalInst.cboZ       := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE
1217  io.toDecode.virtualInst.cboZ       := menvcfg.regOut.CBZE && (
1218    isModeVS && !henvcfg.regOut.CBZE ||
1219    isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE)
1220  )
1221  io.toDecode.illegalInst.cboCF      := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE
1222  io.toDecode.virtualInst.cboCF      := menvcfg.regOut.CBCFE && (
1223    isModeVS && !henvcfg.regOut.CBCFE ||
1224    isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE)
1225  )
1226  io.toDecode.illegalInst.cboI       :=
1227    !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off ||
1228    isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off
1229  io.toDecode.virtualInst.cboI       := menvcfg.regOut.CBIE =/= EnvCBIE.Off && (
1230    isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off ||
1231    isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off)
1232  )
1233  io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && (
1234    menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM ||
1235    senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) ||
1236    henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU)
1237  )
1238
1239  // Always instantiate basic difftest modules.
1240  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1241    val hartId = io.fromTop.hartId
1242    val trapValid = io.fromRob.trap.valid
1243    val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt)
1244    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1245    val hasNMI = nmi && hasTrap
1246    val interruptNO = Mux(interrupt, trapNO, 0.U)
1247    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1248    val isSv39: Bool =
1249      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv39 ||
1250      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39
1251    val isSv48: Bool =
1252      (isModeHS || isModeHU) &&  satp.regOut.MODE === SatpMode.Sv48 ||
1253      (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48
1254    val isBare = !isSv39 && !isSv48
1255    val sv39PC = SignExt(trapPC.take(39), XLEN)
1256    val sv48PC = SignExt(trapPC.take(48), XLEN)
1257    val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN)
1258    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1259    val exceptionPC = Mux1H(Seq(
1260      isSv39 -> sv39PC,
1261      isSv48 -> sv48PC,
1262      isBare -> barePC,
1263    ))
1264
1265    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1266    diffArchEvent.coreid := hartId
1267    diffArchEvent.valid := trapValid
1268    diffArchEvent.interrupt := interruptNO
1269    diffArchEvent.exception := exceptionNO
1270    diffArchEvent.exceptionPC := exceptionPC
1271    diffArchEvent.hasNMI := hasNMI
1272    diffArchEvent.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject && hasTrap
1273    if (env.EnableDifftest) {
1274      diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr
1275    }
1276
1277    val diffCSRState = DifftestModule(new DiffCSRState)
1278    diffCSRState.coreid         := hartId
1279    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1280    diffCSRState.mstatus        := mstatus.rdata.asUInt
1281    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1282    diffCSRState.mepc           := mepc.rdata.asUInt
1283    diffCSRState.sepc           := sepc.rdata.asUInt
1284    diffCSRState.mtval          := mtval.rdata.asUInt
1285    diffCSRState.stval          := stval.rdata.asUInt
1286    diffCSRState.mtvec          := mtvec.rdata.asUInt
1287    diffCSRState.stvec          := stvec.rdata.asUInt
1288    diffCSRState.mcause         := mcause.rdata.asUInt
1289    diffCSRState.scause         := scause.rdata.asUInt
1290    diffCSRState.satp           := satp.rdata.asUInt
1291    diffCSRState.mip            := mip.regOut.asUInt
1292    diffCSRState.mie            := mie.rdata.asUInt
1293    diffCSRState.mscratch       := mscratch.rdata.asUInt
1294    diffCSRState.sscratch       := sscratch.rdata.asUInt
1295    diffCSRState.mideleg        := mideleg.rdata.asUInt
1296    diffCSRState.medeleg        := medeleg.rdata.asUInt
1297
1298    val diffDebugMode = DifftestModule(new DiffDebugMode)
1299    diffDebugMode.coreid    := hartId
1300    diffDebugMode.debugMode := debugMode
1301    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1302    diffDebugMode.dpc       := dpc.rdata.asUInt
1303    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1304    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1305
1306    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1307    diffTriggerCSRState.coreid    := hartId
1308    diffTriggerCSRState.tselect   := tselect.rdata
1309    diffTriggerCSRState.tdata1    := tdata1.rdata
1310    diffTriggerCSRState.tinfo     := tinfo.rdata
1311    diffTriggerCSRState.tcontrol  := tcontrol.rdata
1312
1313    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1314    diffVecCSRState.coreid := hartId
1315    diffVecCSRState.vstart := vstart.rdata.asUInt
1316    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1317    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1318    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1319    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1320    diffVecCSRState.vtype := vtype.rdata.asUInt
1321    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1322
1323    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1324    diffFpCSRState.coreid := hartId
1325    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1326
1327    val diffHCSRState = DifftestModule(new DiffHCSRState)
1328    diffHCSRState.coreid      := hartId
1329    diffHCSRState.virtMode    := privState.V.asBool
1330    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1331    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1332    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1333    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1334    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1335    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1336    diffHCSRState.htval       := htval.rdata.asUInt
1337    diffHCSRState.htinst      := htinst.rdata.asUInt
1338    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1339    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1340    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1341    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1342    diffHCSRState.vscause     := vscause.rdata.asUInt
1343    diffHCSRState.vstval      := vstval.rdata.asUInt
1344    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1345    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1346
1347  }
1348}
1349
1350trait IpIeAliasConnect {
1351  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1352
1353  mip.fromMvip  := mvip.toMip
1354  mip.fromSip   := sip.toMip
1355  mip.fromVSip  := vsip.toMip
1356  mvip.fromMip  := mip.toMvip
1357  mvip.fromSip  := sip.toMvip
1358  mvip.fromVSip := vsip.toMvip
1359  hvip.fromMip  := mip.toHvip
1360  hvip.fromHip  := hip.toHvip
1361  hvip.fromVSip := vsip.toHvip
1362
1363  mie.fromHie  := hie.toMie
1364  mie.fromSie  := sie.toMie
1365  mie.fromVSie := vsie.toMie
1366  sie.fromVSie := vsie.toSie
1367}
1368
1369object NewCSRMain extends App {
1370  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1371    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1372
1373  val defaultConfig = config.alterPartial({
1374    // Get XSCoreParams and pass it to the "small module"
1375    case XSCoreParamsKey => config(XSTileKey).head
1376  })
1377
1378  Generator.execute(
1379    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1380    new NewCSR()(defaultConfig),
1381    firtoolOpts
1382  )
1383
1384  println("done")
1385}