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