xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision cc1eb70ddc8a82e88a4bb868a34725c834b703c5)
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.mstateen0 := mstateen0.rdata
365  permitMod.io.in.status.hstateen0 := hstateen0.rdata
366  permitMod.io.in.status.sstateen0 := sstateen0.rdata
367
368  permitMod.io.in.status.menvcfg := menvcfg.rdata
369  permitMod.io.in.status.henvcfg := henvcfg.rdata
370
371  permitMod.io.in.status.mstatusFSOff  :=  mstatus.regOut.FS === ContextStatus.Off
372  permitMod.io.in.status.mstatusVSOff  :=  mstatus.regOut.VS === ContextStatus.Off
373  permitMod.io.in.status.vsstatusFSOff := vsstatus.regOut.FS === ContextStatus.Off
374  permitMod.io.in.status.vsstatusVSOff := vsstatus.regOut.VS === ContextStatus.Off
375
376  sstcIRGen.i.stime.valid := time.updated
377  sstcIRGen.i.stime.bits  := time.stime
378  sstcIRGen.i.vstime.valid := time.updated
379  sstcIRGen.i.vstime.bits  := time.vstime
380  sstcIRGen.i.stimecmp := stimecmp.rdata
381  sstcIRGen.i.vstimecmp := vstimecmp.rdata
382  sstcIRGen.i.menvcfgSTCE := menvcfg.regOut.STCE.asBool
383  sstcIRGen.i.henvcfgSTCE := henvcfg.regOut.STCE.asBool
384
385  miregiprios.foreach { mod =>
386    mod.w.wen := (addr === mireg.addr.U) && (miselect.regOut.ALL.asUInt === mod.addr.U)
387    mod.w.wdata := wdata
388  }
389
390  siregiprios.foreach { mod =>
391    mod.w.wen := (addr === sireg.addr.U) && (siselect.regOut.ALL.asUInt === mod.addr.U)
392    mod.w.wdata := wdata
393  }
394
395  mhartid.hartid := this.io.fromTop.hartId
396
397  cfgs.zipWithIndex.foreach { case (mod, i) =>
398    mod.w.wen := wen && (addr === (0x3A0 + i / 8 * 2).U)
399    mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8))
400  }
401
402  pmpaddr.zipWithIndex.foreach{ case(mod, i) =>
403    mod.w.wen := wen && (addr === (0x3B0 + i).U)
404    mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i)
405  }
406
407  csrMods.foreach { mod =>
408    mod match {
409      case m: HypervisorBundle =>
410        m.hstatus := hstatus.regOut
411      case _ =>
412    }
413    mod match {
414      case m: VirtualSupervisorBundle =>
415        m.v := V.asUInt.asBool
416        m.hgatp := hgatp.regOut
417      case _ =>
418    }
419    mod match {
420      case m: HasMachineDelegBundle =>
421        m.mideleg := mideleg.regOut
422        m.medeleg := medeleg.regOut
423      case _ =>
424    }
425    mod match {
426      case m: HasMachineCounterControlBundle =>
427        m.mcountinhibit := mcountinhibit.regOut
428      case _ =>
429    }
430    mod match {
431      case m: HasExternalInterruptBundle =>
432        m.platformIRP := this.platformIRP
433        m.platformIRP.STIP  := sstcIRGen.o.STIP
434        m.platformIRP.VSTIP := sstcIRGen.o.VSTIP
435      case _ =>
436    }
437    mod match {
438      case m: HasRobCommitBundle =>
439        // Todo: move RegNext from ROB to CSR
440        m.robCommit.instNum := io.fromRob.commit.instNum
441        m.robCommit.fflags  := RegNextWithEnable(io.fromRob.commit.fflags)
442        m.robCommit.fsDirty := GatedValidRegNext(io.fromRob.commit.fsDirty)
443        m.robCommit.vsDirty := GatedValidRegNext(io.fromRob.commit.vsDirty)
444        m.robCommit.vxsat   := RegNextWithEnable(io.fromRob.commit.vxsat)
445        m.robCommit.vtype   := RegNextWithEnable(io.fromRob.commit.vtype)
446        m.robCommit.vl      := RegNext          (io.fromRob.commit.vl)
447        m.robCommit.vstart  := RegNextWithEnable(io.fromRob.commit.vstart)
448        m.writeFCSR         := writeFpLegal
449        m.writeVCSR         := writeVecLegal
450        m.isVirtMode        := V.asUInt.asBool
451      case _ =>
452    }
453    mod match {
454      case m: TrapEntryDEventSinkBundle =>
455        m.trapToD := trapEntryDEvent.out
456      case _ =>
457    }
458    mod match {
459      case m: TrapEntryMEventSinkBundle =>
460        m.trapToM := trapEntryMEvent.out
461      case _ =>
462    }
463    mod match {
464      case m: TrapEntryHSEventSinkBundle =>
465        m.trapToHS := trapEntryHSEvent.out
466      case _ =>
467    }
468    mod match {
469      case m: TrapEntryVSEventSinkBundle =>
470        m.trapToVS := trapEntryVSEvent.out
471      case _ =>
472    }
473    mod match {
474      case m: MretEventSinkBundle =>
475        m.retFromM := mretEvent.out
476      case _ =>
477    }
478    mod match {
479      case m: SretEventSinkBundle =>
480        m.retFromS := sretEvent.out
481      case _ =>
482    }
483    mod match {
484      case m: DretEventSinkBundle =>
485        m.retFromD := dretEvent.out
486      case _ =>
487    }
488    mod match {
489      case m: HasAIABundle =>
490        m.aiaToCSR.rdata.valid := fromAIA.rdata.valid
491        m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data
492        m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal
493        m.aiaToCSR.mtopei.valid := fromAIA.mtopei.valid
494        m.aiaToCSR.stopei.valid := fromAIA.stopei.valid
495        m.aiaToCSR.vstopei.valid := fromAIA.vstopei.valid
496        m.aiaToCSR.mtopei.bits := fromAIA.mtopei.bits
497        m.aiaToCSR.stopei.bits := fromAIA.stopei.bits
498        m.aiaToCSR.vstopei.bits := fromAIA.vstopei.bits
499      case _ =>
500    }
501    mod match {
502      case m: HasInterruptFilterSink =>
503        m.topIR.mtopi  := intrMod.io.out.mtopi
504        m.topIR.stopi  := intrMod.io.out.stopi
505        m.topIR.vstopi := intrMod.io.out.vstopi
506      case _ =>
507    }
508    mod match {
509      case m: HasPMPAddrSink =>
510        m.addrRData := pmpEntryMod.io.out.pmpAddrRData
511      case _ =>
512    }
513    mod match {
514      case m: HasMHPMSink =>
515        // cycle from mcycle
516        m.mHPM.cycle := mcycle.rdata
517        // time from clint
518        m.mHPM.time  := io.fromTop.clintTime
519        // instret from minstret
520        m.mHPM.instret := minstret.rdata
521        // VS-Mode or VU-Mode
522        m.v := privState.isVirtual
523        m.htimedelta := htimedelta.rdata
524        m.mHPM.hpmcounters.zip(mhpmcounters).map{
525          case(counter, mcounter) => counter := mcounter.rdata
526        }
527      case _ =>
528    }
529    mod match {
530      case m: HasMachineEnvBundle =>
531        m.menvcfg := menvcfg.regOut
532      case _ =>
533    }
534    mod match {
535      case m: HasHypervisorEnvBundle =>
536        m.menvcfg := menvcfg.regOut
537        m.privState := privState
538        m.accessStimecmp := (ren || wen) && (addr === CSRs.stimecmp.U || addr === CSRs.vstimecmp.U)
539      case _ =>
540    }
541    mod match {
542      case m: HasIpIeBundle =>
543        m.mideleg := mideleg.regOut
544        m.mip := mip.regOut
545        m.mie := mie.regOut
546        m.mvip := mvip.regOut
547        m.mvien := mvien.regOut
548        m.hideleg := hideleg.regOut
549        m.hip := hip.regOut
550        m.hie := hie.regOut
551        m.hvien := hvien.regOut
552        m.hvip := hvip.regOut
553        m.sip := sip.regOut
554        m.sie := sie.regOut
555        m.vsip := vsip.regOut
556        m.vsie := vsie.regOut
557        m.hgeip := hgeip.regOut
558        m.hgeie := hgeie.regOut
559        m.hstatusVGEIN := hstatus.regOut.VGEIN
560      case _ =>
561    }
562    mod match {
563      case m: HasMhpmeventOfBundle =>
564        m.ofVec := VecInit(mhpmevents.map(event => event.rdata.head(1).asBool)).asUInt //todo:fix
565        m.privState := privState
566        m.mcounteren := mcounteren.rdata
567        m.hcounteren := hcounteren.rdata
568      case _ =>
569    }
570    mod match {
571      case m: HasStateen0Bundle =>
572        m.fromMstateen0 := mstateen0.regOut
573        m.fromHstateen0 := hstateen0.regOut
574        m.privState     := privState
575      case _ =>
576    }
577  }
578
579  csrMods.foreach { mod =>
580    println(s"${mod.modName}: ")
581    println(mod.dumpFields)
582  }
583
584  trapEntryMEvent .valid := hasTrap && entryPrivState.isModeM
585  trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS
586  trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS
587
588  Seq(trapEntryMEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod =>
589    eMod.in match {
590      case in: TrapEntryEventInput =>
591        in.causeNO := trapHandleMod.io.out.causeNO
592        in.trapPc := trapPC
593        in.isCrossPageIPF := trapIsCrossPageIPF
594        in.isHls := trapIsHls
595
596        in.iMode.PRVM := PRVM
597        in.iMode.V := V
598        in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool, mstatus.regOut.MPP, PRVM)
599        in.dMode.V := V.asUInt.asBool || mstatus.regOut.MPRV && (mstatus.regOut.MPP =/= PrivMode.M) && mstatus.regOut.MPV
600
601        in.privState := privState
602        in.mstatus := mstatus.regOut
603        in.hstatus := hstatus.regOut
604        in.sstatus := mstatus.sstatus
605        in.vsstatus := vsstatus.regOut
606        in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec
607        in.tcontrol := tcontrol.regOut
608
609        in.satp  := satp.regOut
610        in.vsatp := vsatp.regOut
611        in.hgatp := hgatp.regOut
612
613        in.memExceptionVAddr := io.fromMem.excpVA
614        in.memExceptionGPAddr := io.fromMem.excpGPA
615    }
616  }
617
618  mretEvent.valid := legalMret
619  mretEvent.in match {
620    case in =>
621      in.mstatus := mstatus.regOut
622      in.mepc := mepc.regOut
623      in.tcontrol := tcontrol.regOut
624  }
625
626  sretEvent.valid := legalSret
627  sretEvent.in match {
628    case in =>
629      in.privState := privState
630      in.sstatus := mstatus.sstatus
631      in.hstatus := hstatus.regOut
632      in.vsstatus := vsstatus.regOut
633      in.sepc := sepc.regOut
634      in.vsepc := vsepc.regOut
635  }
636
637  dretEvent.valid := legalDret
638  dretEvent.in match {
639    case in =>
640      in.dcsr := dcsr.regOut
641      in.dpc  := dpc.regOut
642      in.mstatus := mstatus.regOut
643  }
644
645  PRVM := MuxCase(
646    PRVM,
647    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
648      x => x.out match {
649        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
650      }
651    }
652  )
653
654  V := MuxCase(
655    V,
656    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
657      x => x.out match {
658        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
659      }
660    }
661  )
662
663  debugMode := MuxCase(
664    debugMode,
665    Seq(
666      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits,
667      trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits
668    )
669  )
670
671  debugIntrEnable := MuxCase(
672    debugIntrEnable,
673    Seq(
674      dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits,
675      trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits
676    )
677  )
678
679  // perf
680  val addrInPerfCnt = (wen || ren) && (
681    (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
682    (addr >= mcountinhibit.addr.U) && (addr <= mhpmevents.last.addr.U) ||
683    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) ||
684    (addr === CSRs.mip.U) ||
685    Cat(aiaSkipCSRs.map(_.addr.U === addr)).orR ||
686    (addr === CSRs.stimecmp.U) ||
687    (addr === CSRs.mcounteren.U) ||
688    (addr === CSRs.scounteren.U) ||
689    (addr === CSRs.menvcfg.U)
690  )
691
692  // flush
693  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed
694
695  val wFcsrChangeRM = addr === fcsr.addr.U && wenLegal && wdata(7, 5) =/= fcsr.frm
696  val wFrmChangeRM  = addr === CSRs.frm.U  && wenLegal && wdata(2, 0) =/= fcsr.frm
697  val frmChange = wFcsrChangeRM || wFrmChangeRM
698
699  val wVcsrChangeRM = addr === CSRs.vcsr.U && wenLegal && wdata(2, 1) =/= vcsr.vxrm
700  val wVxrmChangeRM = addr === CSRs.vxrm.U && wenLegal && wdata(1, 0) =/= vcsr.vxrm
701  val vxrmChange = wVcsrChangeRM || wVxrmChangeRM
702
703  val floatStatusOnOff = mstatus.w.wen && (
704    mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
705    mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
706  ) || mstatus.wAliasSstatus.wen && (
707    mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
708    mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off
709  ) || vsstatus.w.wen && (
710    vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off ||
711    vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off
712  )
713
714  val vectorStatusOnOff = mstatus.w.wen && (
715    mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
716    mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
717  ) || mstatus.wAliasSstatus.wen && (
718    mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off ||
719    mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off
720  ) || vsstatus.w.wen && (
721    vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off ||
722    vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off
723  )
724
725  val triggerFrontendChange = Wire(Bool())
726  val flushPipe = resetSatp || frmChange || vxrmChange || triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff
727
728  // fence
729  val tvm = mstatus.regOut.TVM.asBool
730  val vtvm = hstatus.regOut.VTVM.asBool
731
732  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
733    if (vsMapS.contains(id)) {
734      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
735    } else if (sMapVS.contains(id)) {
736      (!isModeVS && addr === id.U) -> rdata
737    } else {
738      (raddr === id.U) -> rdata
739    }
740  })
741
742  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
743    if (vsMapS.contains(id)) {
744      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
745    } else if (sMapVS.contains(id)) {
746      (!isModeVS && addr === id.U) -> regOut
747    } else {
748      (raddr === id.U) -> regOut
749    }
750  })
751
752  private val needTargetUpdate = mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
753    trapEntryMEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
754
755  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
756
757  private val s_idle :: s_waitIMSIC :: Nil = Enum(2)
758
759  private val state = RegInit(s_idle)
760  private val stateNext = WireInit(state)
761  state := stateNext
762
763  private val asyncRead = ren && (
764    mireg.addr.U === addr && miselect.inIMSICRange ||
765      sireg.addr.U === addr && siselect.inIMSICRange ||
766      vsireg.addr.U === addr && vsiselect.inIMSICRange
767    )
768
769  switch(state) {
770    is(s_idle) {
771      when(asyncRead) {
772        stateNext := s_waitIMSIC
773      }
774    }
775    is(s_waitIMSIC) {
776      when(fromAIA.rdata.valid) {
777        stateNext := s_idle
778      }
779    }
780  }
781
782  // Todo: check IMSIC EX_II and EX_VI
783  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
784  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
785  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
786
787  io.out.valid :=
788    io.in.valid && stateNext === s_idle ||
789    state === s_waitIMSIC && stateNext === s_idle
790  io.out.bits.EX_II := permitMod.io.out.EX_II || imsic_EX_II || noCSRIllegal
791  io.out.bits.EX_VI := permitMod.io.out.EX_VI || imsic_EX_VI
792  io.out.bits.flushPipe := flushPipe
793
794  io.out.bits.rData := Mux(ren, rdata, 0.U)
795  io.out.bits.regOut := regOut
796  io.out.bits.targetPc := DataHoldBypass(
797    Mux(trapEntryDEvent.out.targetPc.valid,
798      trapEntryDEvent.out.targetPc.bits,
799      Mux1H(Seq(
800        mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits,
801        sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits,
802        dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits,
803        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
804        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
805        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
806      )
807    ),
808  needTargetUpdate)
809  io.out.bits.isPerfCnt := addrInPerfCnt
810
811  io.status.privState := privState
812  io.status.fpState.frm := fcsr.frm
813  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
814  io.status.vecState.vstart := vstart.rdata.asUInt
815  io.status.vecState.vxsat := vcsr.vxsat
816  io.status.vecState.vxrm := vcsr.vxrm
817  io.status.vecState.vcsr := vcsr.rdata.asUInt
818  io.status.vecState.vl := vl.rdata.asUInt
819  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
820  io.status.vecState.vlenb := vlenb.rdata.asUInt
821  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
822  io.status.interrupt := intrMod.io.out.interruptVec.valid
823  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
824  io.status.debugMode := debugMode
825  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
826  io.status.tvm := tvm
827  io.status.vtvm := vtvm
828
829  /**
830   * debug_begin
831   *
832   * ways to entry Dmode:
833   *    1. debug intr(from external debug module)
834   *    2. ebreak inst in nonDmode
835   *    3. trigger fire in nonDmode
836   *    4. single step(debug module set dcsr.step before hart resume)
837   */
838  // debug_intr
839  val hasIntr = hasTrap && trapIsInterrupt
840  val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG)
841
842  // debug_exception_ebreak
843  val hasExp = hasTrap && !trapIsInterrupt
844  val breakPoint = trapVec(ExceptionNO.breakPoint).asBool
845  val hasBreakPoint = hasExp && breakPoint
846  val ebreakEnterDebugMode =
847    (privState.isModeM && dcsr.regOut.EBREAKM.asBool) ||
848      (privState.isModeHS && dcsr.regOut.EBREAKS.asBool) ||
849      (privState.isModeHU && dcsr.regOut.EBREAKU.asBool) ||
850      (privState.isModeVS && dcsr.regOut.EBREAKVS.asBool) ||
851      (privState.isModeVU && dcsr.regOut.EBREAKVU.asBool)
852  val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode
853
854  // debug_exception_trigger
855  val triggerFrontendHitVec = triggerCf.frontendHit
856  val triggerMemHitVec = triggerCf.backendHit
857  val triggerHitVec = triggerFrontendHitVec.asUInt | triggerMemHitVec.asUInt // Todo: update mcontrol.hit
858  val triggerFrontendCanFireVec = triggerCf.frontendCanFire.asUInt
859  val triggerMemCanFireVec = triggerCf.backendCanFire.asUInt
860  val triggerCanFireVec = triggerFrontendCanFireVec | triggerMemCanFireVec
861  val tdata1WireVec = tdata1RegVec.map{ mod => {
862      val tdata1Wire = Wire(new Tdata1Bundle)
863      tdata1Wire := mod.rdata
864      tdata1Wire
865  }}
866  val tdata2WireVec = tdata2RegVec.map{ mod => {
867      val tdata2Wire = Wire(new Tdata2Bundle)
868      tdata2Wire := mod.rdata
869      tdata2Wire
870  }}
871  val mcontrolWireVec = tdata1WireVec.map{ mod => {
872    val mcontrolWire = Wire(new Mcontrol)
873    mcontrolWire := mod.DATA.asUInt
874    mcontrolWire
875  }}
876
877  // More than one triggers can hit at the same time, but only fire one
878  // We select the first hit trigger to fire
879  val triggerFireOH = PriorityEncoderOH(triggerCanFireVec)
880  val triggerFireAction = PriorityMux(triggerFireOH, tdata1WireVec.map(_.getTriggerAction)).asUInt
881  val hasTriggerFire = hasExp && triggerCf.canFire
882  val hasDebugTriggerException = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt)
883  val triggerCanFire = hasTriggerFire && (triggerFireAction === TrigAction.BreakpointExp.asUInt) &&
884                          Mux(privState.isModeM && !debugMode, tcontrol.regOut.MTE.asBool, true.B) // todo: Should trigger be fire in dmode?
885
886  // debug_exception_single
887  val hasSingleStep = hasExp && io.fromRob.trap.bits.singleStep
888
889  val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep
890  val hasDebugTrap = hasDebugException || hasDebugIntr
891
892  trapEntryDEvent.valid                       := hasDebugTrap && !debugMode
893  trapEntryDEvent.in.hasDebugIntr             := hasDebugIntr
894  trapEntryDEvent.in.debugMode                := debugMode
895  trapEntryDEvent.in.hasTrap                  := hasTrap
896  trapEntryDEvent.in.hasSingleStep            := hasSingleStep
897  trapEntryDEvent.in.hasTriggerFire           := hasTriggerFire
898  trapEntryDEvent.in.hasDebugEbreakException  := hasDebugEbreakException
899  trapEntryDEvent.in.breakPoint               := breakPoint
900
901  trapHandleMod.io.in.trapInfo.bits.singleStep  := hasSingleStep
902  trapHandleMod.io.in.trapInfo.bits.triggerFire := triggerCanFire
903
904  intrMod.io.in.debugMode := debugMode
905  intrMod.io.in.debugIntr := debugIntr
906  intrMod.io.in.dcsr      := dcsr.rdata.asUInt
907
908  val tselect1H = UIntToOH(tselect.rdata.asUInt, TriggerNum).asBools
909  val chainVec = mcontrolWireVec.map(_.CHAIN.asBool)
910  val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b}
911  val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength)
912
913  val tdata1Update  = tdata1.w.wen
914  val tdata2Update  = tdata2.w.wen
915  val triggerUpdate = tdata1Update || tdata2Update
916
917  tdata1RegVec.foreach { mod =>
918    mod match {
919      case m: HasdebugModeBundle =>
920        m.debugMode := debugMode
921        m.chainable := newTriggerChainIsLegal
922      case _ =>
923    }
924  }
925  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
926      mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
927      mod1.w.wdata  := wdata
928      mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
929      mod2.w.wdata  := wdata
930    }
931  }
932
933  val tdata1Wdata = Wire(new Tdata1Bundle)
934  tdata1Wdata := wdata
935  val mcontrolWdata = Wire(new Mcontrol)
936  mcontrolWdata := tdata1Wdata.DATA.asUInt
937  val tdata1TypeWdata = tdata1Wdata.TYPE
938
939  val tdata1Selected = Wire(new Tdata1Bundle)
940  tdata1Selected := tdata1.rdata.asUInt
941  val mcontrolSelected = Wire(new Mcontrol)
942  mcontrolSelected := tdata1Selected.DATA.asUInt
943  val tdata2Selected = Wire(new Tdata2Bundle)
944  tdata2Selected := tdata2.rdata.asUInt
945
946  val frontendTriggerUpdate =
947    tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isFetchTrigger ||
948      mcontrolSelected.isFetchTrigger && triggerUpdate
949
950  val memTriggerUpdate =
951    tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isMemAccTrigger ||
952      mcontrolSelected.isMemAccTrigger && triggerUpdate
953
954  val triggerEnableVec = tdata1WireVec.zip(mcontrolWireVec).map { case(tdata1, mcontrol) =>
955    tdata1.TYPE.isLegal && (
956      mcontrol.M && privState.isModeM  ||
957        mcontrol.S && privState.isModeHS ||
958        mcontrol.U && privState.isModeHU)
959  }
960
961  val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map {
962    case (tEnable, mod) => tEnable && mod.isFetchTrigger
963  }
964  val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map {
965    case (tEnable, mod) => tEnable && mod.isMemAccTrigger
966  }
967
968  triggerFrontendChange := frontendTriggerUpdate
969
970  io.status.frontendTrigger.tUpdate.valid       := RegNext(RegNext(frontendTriggerUpdate))
971  io.status.frontendTrigger.tUpdate.bits.addr   := tselect.rdata.asUInt
972  io.status.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected)
973  io.status.frontendTrigger.tEnableVec          := fetchTriggerEnableVec
974  io.status.memTrigger.tUpdate.valid            := RegNext(RegNext(memTriggerUpdate))
975  io.status.memTrigger.tUpdate.bits.addr        := tselect.rdata.asUInt
976  io.status.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected)
977  io.status.memTrigger.tEnableVec               := memAccTriggerEnableVec
978  /**
979   * debug_end
980   */
981
982  /**
983   * perf_begin
984   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huncun 5)
985   */
986  // tmp: mhpmevents is wrapper of perfEvents, read/write/update mhpmevents -> read/write/update perfEvents
987  for (i <-0 until perfCntNum) {
988    when(mhpmevents(i).w.wen) {
989      perfEvents(i) := wdata
990    }
991  }
992  val csrevents = perfEvents.slice(24, 29)
993
994  val hpmEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
995  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
996    hpmEvents(i) := io.perf.perfEventsHc(i)
997  }
998
999  val hpmHc = HPerfMonitor(csrevents, hpmEvents)
1000
1001  val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU)
1002  val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
1003  for (i <-0 until perfCntNum) {
1004    countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR
1005  }
1006  val allPerfEvents = io.perf.perfEventsFrontend ++
1007    io.perf.perfEventsCtrl ++
1008    io.perf.perfEventsLsu ++
1009    hpmHc.getPerf
1010
1011  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
1012  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
1013  for(i <- 0 until perfCntNum) {
1014    mhpmcounters(i) match {
1015      case m: HasPerfCounterBundle =>
1016        m.countingEn        := countingEn(i)
1017        m.perf              := allPerfEvents(i)
1018        ofFromPerfCntVec(i) := m.toMhpmeventOF
1019      case _ =>
1020    }
1021    perfEvents(i)   := ofFromPerfCntVec(i) ## perfEvents(i).tail(1)
1022    lcofiReqVec(i)  := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1)
1023  }
1024
1025  val lcofiReq = lcofiReqVec.asUInt.orR
1026  mip match {
1027    case m: HasLocalInterruptReqBundle =>
1028      m.lcofiReq := lcofiReq
1029    case _ =>
1030  }
1031  /**
1032   * perf_end
1033   */
1034
1035  /**
1036   * [[io.status.custom]] connection
1037   */
1038  io.status.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
1039  io.status.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
1040  io.status.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
1041  io.status.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
1042  io.status.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
1043  io.status.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
1044  io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
1045  io.status.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
1046  io.status.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
1047  io.status.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
1048
1049  io.status.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
1050
1051  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
1052  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
1053  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
1054  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
1055  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
1056
1057  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
1058  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
1059  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
1060  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
1061  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
1062  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
1063  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
1064
1065  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
1066  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
1067  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
1068  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
1069  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
1070
1071  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1072  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool
1073
1074  private val csrAccess = wen || ren
1075
1076  private val imsicAddrValid =
1077    csrAccess && addr ===  mireg.addr.U &&  miselect.inIMSICRange ||
1078    csrAccess && addr ===  sireg.addr.U &&  siselect.inIMSICRange ||
1079    csrAccess && addr === vsireg.addr.U && vsiselect.inIMSICRange
1080
1081  private val imsicAddr = Mux1H(Seq(
1082    (csrAccess && addr ===  mireg.addr.U) -> miselect.regOut.asUInt,
1083    (csrAccess && addr ===  sireg.addr.U) -> siselect.regOut.asUInt,
1084    (csrAccess && addr === vsireg.addr.U) -> vsiselect.regOut.asUInt,
1085  ))
1086
1087  private val imsicAddrPrivState = Mux1H(Seq(
1088    ( mireg.w.wen) -> PrivState.ModeM,
1089    ( sireg.w.wen) -> PrivState.ModeHS,
1090    (vsireg.w.wen) -> PrivState.ModeVS,
1091  ))
1092
1093  private val imsicWdataValid =
1094    wen && addr === mireg.addr.U && miselect.inIMSICRange ||
1095    wen && addr === sireg.addr.U && siselect.inIMSICRange ||
1096    wen && addr === vsireg.addr.U && vsiselect.inIMSICRange
1097
1098  toAIA.addr.valid     := imsicAddrValid
1099  toAIA.addr.bits.addr := imsicAddr
1100  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1101  toAIA.addr.bits.v    := imsicAddrPrivState.V
1102
1103  toAIA.wdata.valid := imsicWdataValid
1104  toAIA.wdata.bits.op := io.in.bits.op
1105  toAIA.wdata.bits.data := io.in.bits.src
1106  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1107  toAIA.mClaim  := mtopei.w.wen
1108  toAIA.sClaim  := stopei.w.wen
1109  toAIA.vsClaim := vstopei.w.wen
1110
1111  // tlb
1112  io.tlb.satpASIDChanged  := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1113  io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1114  io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1115  io.tlb.satp := satp.rdata
1116  io.tlb.vsatp := vsatp.rdata
1117  io.tlb.hgatp := hgatp.rdata
1118  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1119  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1120  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1121  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1122  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1123
1124  io.tlb.imode := PRVM.asUInt
1125  io.tlb.dmode := Mux(
1126    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV,
1127    mstatus.regOut.MPP.asUInt,
1128    PRVM.asUInt
1129  )
1130  io.tlb.dvirt := Mux(
1131    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mstatus.regOut.MPP =/= PrivMode.M,
1132    mstatus.regOut.MPV.asUInt,
1133    V.asUInt
1134  )
1135
1136  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1137  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1138  io.toDecode.illegalInst.sfencePart := isModeHU
1139  io.toDecode.virtualInst.sfencePart := isModeVU
1140  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1141  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1142  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1143  io.toDecode.illegalInst.hlsv       := isModeHU && hstatus.regOut.HU
1144  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1145  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1146  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1147  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1148  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1149
1150  // Always instantiate basic difftest modules.
1151  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1152    val hartId = io.fromTop.hartId
1153    val trapValid = io.fromRob.trap.valid
1154    val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt
1155    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1156    val interruptNO = Mux(interrupt, trapNO, 0.U)
1157    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1158    val ivmHS = isModeHS &&  satp.regOut.MODE =/= SatpMode.Bare
1159    val ivmVS = isModeVS && vsatp.regOut.MODE =/= SatpMode.Bare
1160    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1161    val exceptionPC = Mux(ivmHS || ivmVS, SignExt(trapPC, XLEN), ZeroExt(trapPC, XLEN))
1162
1163    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1164    diffArchEvent.coreid := hartId
1165    diffArchEvent.valid := trapValid
1166    diffArchEvent.interrupt := interruptNO
1167    diffArchEvent.exception := exceptionNO
1168    diffArchEvent.exceptionPC := exceptionPC
1169    if (env.EnableDifftest) {
1170      diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr
1171    }
1172
1173    val diffCSRState = DifftestModule(new DiffCSRState)
1174    diffCSRState.coreid         := hartId
1175    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1176    diffCSRState.mstatus        := mstatus.rdata.asUInt
1177    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1178    diffCSRState.mepc           := mepc.rdata.asUInt
1179    diffCSRState.sepc           := sepc.rdata.asUInt
1180    diffCSRState.mtval          := mtval.rdata.asUInt
1181    diffCSRState.stval          := stval.rdata.asUInt
1182    diffCSRState.mtvec          := mtvec.rdata.asUInt
1183    diffCSRState.stvec          := stvec.rdata.asUInt
1184    diffCSRState.mcause         := mcause.rdata.asUInt
1185    diffCSRState.scause         := scause.rdata.asUInt
1186    diffCSRState.satp           := satp.rdata.asUInt
1187    diffCSRState.mip            := mip.regOut.asUInt
1188    diffCSRState.mie            := mie.rdata.asUInt
1189    diffCSRState.mscratch       := mscratch.rdata.asUInt
1190    diffCSRState.sscratch       := sscratch.rdata.asUInt
1191    diffCSRState.mideleg        := mideleg.rdata.asUInt
1192    diffCSRState.medeleg        := medeleg.rdata.asUInt
1193
1194    val diffDebugMode = DifftestModule(new DiffDebugMode)
1195    diffDebugMode.coreid    := hartId
1196    diffDebugMode.debugMode := debugMode
1197    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1198    diffDebugMode.dpc       := dpc.rdata.asUInt
1199    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1200    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1201
1202    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1203    diffVecCSRState.coreid := hartId
1204    diffVecCSRState.vstart := vstart.rdata.asUInt
1205    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1206    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1207    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1208    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1209    diffVecCSRState.vtype := vtype.rdata.asUInt
1210    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1211
1212    val diffHCSRState = DifftestModule(new DiffHCSRState)
1213    diffHCSRState.coreid      := hartId
1214    diffHCSRState.virtMode    := privState.V.asBool
1215    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1216    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1217    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1218    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1219    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1220    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1221    diffHCSRState.htval       := htval.rdata.asUInt
1222    diffHCSRState.htinst      := htinst.rdata.asUInt
1223    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1224    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1225    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1226    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1227    diffHCSRState.vscause     := vscause.rdata.asUInt
1228    diffHCSRState.vstval      := vstval.rdata.asUInt
1229    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1230    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1231
1232  }
1233}
1234
1235trait IpIeAliasConnect {
1236  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1237
1238  mip.fromMvip  := mvip.toMip
1239  mip.fromSip   := sip.toMip
1240  mip.fromVSip  := vsip.toMip
1241  mvip.fromMip  := mip.toMvip
1242  mvip.fromSip  := sip.toMvip
1243  mvip.fromVSip := vsip.toMvip
1244  hvip.fromMip  := mip.toHvip
1245  hvip.fromHip  := hip.toHvip
1246  hvip.fromVSip := vsip.toHvip
1247
1248  mie.fromHie  := hie.toMie
1249  mie.fromSie  := sie.toMie
1250  mie.fromVSie := vsie.toMie
1251  sie.fromVSie := vsie.toSie
1252}
1253
1254object NewCSRMain extends App {
1255  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1256    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1257
1258  val defaultConfig = config.alterPartial({
1259    // Get XSCoreParams and pass it to the "small module"
1260    case XSCoreParamsKey => config(XSTileKey).head
1261  })
1262
1263  Generator.execute(
1264    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1265    new NewCSR()(defaultConfig),
1266    firtoolOpts
1267  )
1268
1269  println("done")
1270}