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