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