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