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