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