xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision ceba215ad376611ba6c994765c6e33e6b5749316)
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) || (addr === CSRs.sip.U) || (addr === CSRs.vsip.U) ||
692    (addr === CSRs.hip.U) || (addr === CSRs.mvip.U) || (addr === CSRs.hvip.U) ||
693    Cat(aiaSkipCSRs.map(_.addr.U === addr)).orR ||
694    (addr === CSRs.stimecmp.U) ||
695    (addr === CSRs.mcounteren.U) ||
696    (addr === CSRs.scounteren.U) ||
697    (addr === CSRs.menvcfg.U)
698  )
699
700  // flush
701  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed
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
727  val vstartChange = vstart.w.wen && (
728    vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U ||
729    vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U
730  )
731
732  val flushPipe = resetSatp ||
733    triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff ||
734    vstartChange
735
736  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) =>
737    if (vsMapS.contains(id)) {
738      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata
739    } else if (sMapVS.contains(id)) {
740      (!isModeVS && addr === id.U) -> rdata
741    } else {
742      (raddr === id.U) -> rdata
743    }
744  })
745
746  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
747    if (vsMapS.contains(id)) {
748      ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut
749    } else if (sMapVS.contains(id)) {
750      (!isModeVS && addr === id.U) -> regOut
751    } else {
752      (raddr === id.U) -> regOut
753    }
754  })
755
756  private val needTargetUpdate = mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
757    trapEntryMEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
758
759  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
760
761  private val s_idle :: s_waitIMSIC :: Nil = Enum(2)
762
763  private val state = RegInit(s_idle)
764  private val stateNext = WireInit(state)
765  state := stateNext
766
767  private val asyncRead = ren && (
768    mireg.addr.U === addr && miselect.inIMSICRange ||
769      sireg.addr.U === addr && siselect.inIMSICRange ||
770      vsireg.addr.U === addr && vsiselect.inIMSICRange
771    )
772
773  switch(state) {
774    is(s_idle) {
775      when(asyncRead) {
776        stateNext := s_waitIMSIC
777      }
778    }
779    is(s_waitIMSIC) {
780      when(fromAIA.rdata.valid) {
781        stateNext := s_idle
782      }
783    }
784  }
785
786  // Todo: check IMSIC EX_II and EX_VI
787  private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal
788  private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool
789  private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool
790
791  io.out.valid :=
792    io.in.valid && stateNext === s_idle ||
793    state === s_waitIMSIC && stateNext === s_idle
794  io.out.bits.EX_II := permitMod.io.out.EX_II || imsic_EX_II || noCSRIllegal
795  io.out.bits.EX_VI := permitMod.io.out.EX_VI || imsic_EX_VI
796  io.out.bits.flushPipe := flushPipe
797
798  io.out.bits.rData := MuxCase(0.U, Seq(
799    (state === s_waitIMSIC && stateNext === s_idle) -> fromAIA.rdata.bits.data,
800    ren -> rdata,
801  ))
802  io.out.bits.regOut := regOut
803  io.out.bits.targetPc := DataHoldBypass(
804    Mux(trapEntryDEvent.out.targetPc.valid,
805      trapEntryDEvent.out.targetPc.bits,
806      Mux1H(Seq(
807        mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits,
808        sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits,
809        dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits,
810        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
811        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
812        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
813      )
814    ),
815  needTargetUpdate)
816  io.out.bits.isPerfCnt := addrInPerfCnt
817
818  io.status.privState := privState
819  io.status.fpState.frm := fcsr.frm
820  io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off
821  io.status.vecState.vstart := vstart.rdata.asUInt
822  io.status.vecState.vxsat := vcsr.vxsat
823  io.status.vecState.vxrm := vcsr.vxrm
824  io.status.vecState.vcsr := vcsr.rdata.asUInt
825  io.status.vecState.vl := vl.rdata.asUInt
826  io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
827  io.status.vecState.vlenb := vlenb.rdata.asUInt
828  io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off
829  io.status.interrupt := intrMod.io.out.interruptVec.valid
830  io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
831  io.status.debugMode := debugMode
832  io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP
833
834  /**
835   * debug_begin
836   */
837
838  val tdata1Update  = tdata1.w.wen
839  val tdata2Update  = tdata2.w.wen
840  val tdata1Vec = tdata1RegVec.map{ mod => {
841    val tdata1Wire = Wire(new Tdata1Bundle)
842    tdata1Wire := mod.rdata
843    tdata1Wire
844  }}
845
846  val debugMod = Module(new Debug)
847  debugMod.io.in.trapInfo.valid            := hasTrap
848  debugMod.io.in.trapInfo.bits.trapVec     := trapVec.asUInt
849  debugMod.io.in.trapInfo.bits.intrVec     := intrVec
850  debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
851  debugMod.io.in.trapInfo.bits.triggerCf   := triggerCf
852  debugMod.io.in.trapInfo.bits.singleStep  := singleStep
853  debugMod.io.in.privState                 := privState
854  debugMod.io.in.debugMode                 := debugMode
855  debugMod.io.in.dcsr                      := dcsr.regOut
856  debugMod.io.in.tcontrol                  := tcontrol.regOut
857  debugMod.io.in.tselect                   := tselect.regOut
858  debugMod.io.in.tdata1Vec                 := tdata1Vec
859  debugMod.io.in.tdata1Selected            := tdata1.rdata
860  debugMod.io.in.tdata2Selected            := tdata2.rdata
861  debugMod.io.in.tdata1Update              := tdata1Update
862  debugMod.io.in.tdata2Update              := tdata2Update
863  debugMod.io.in.tdata1Wdata               := wdata
864
865  trapEntryDEvent.valid                       := debugMod.io.out.hasDebugTrap && !debugMode
866  trapEntryDEvent.in.hasDebugIntr             := debugMod.io.out.hasDebugIntr
867  trapEntryDEvent.in.debugMode                := debugMode
868  trapEntryDEvent.in.hasTrap                  := hasTrap
869  trapEntryDEvent.in.hasSingleStep            := debugMod.io.out.hasSingleStep
870  trapEntryDEvent.in.hasTriggerFire           := debugMod.io.out.hasTriggerFire
871  trapEntryDEvent.in.hasDebugEbreakException  := debugMod.io.out.hasDebugEbreakException
872  trapEntryDEvent.in.breakPoint               := debugMod.io.out.breakPoint
873
874  trapHandleMod.io.in.trapInfo.bits.singleStep  := debugMod.io.out.hasSingleStep
875  trapHandleMod.io.in.trapInfo.bits.triggerFire := debugMod.io.out.triggerCanFire
876
877  intrMod.io.in.debugMode := debugMode
878  intrMod.io.in.debugIntr := debugIntr
879  intrMod.io.in.dcsr      := dcsr.regOut
880
881  tdata1RegVec.foreach { mod =>
882    mod match {
883      case m: HasdebugModeBundle =>
884        m.debugMode := debugMode
885        m.chainable := debugMod.io.out.newTriggerChainIsLegal
886      case _ =>
887    }
888  }
889  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
890    mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
891    mod1.w.wdata  := wdata
892    mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
893    mod2.w.wdata  := wdata
894  }}
895
896  triggerFrontendChange := debugMod.io.out.triggerFrontendChange
897
898  io.status.frontendTrigger := debugMod.io.out.frontendTrigger
899  io.status.memTrigger      := debugMod.io.out.memTrigger
900  /**
901   * debug_end
902   */
903
904  /**
905   * perf_begin
906   * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5)
907   */
908  // tmp: mhpmevents is wrapper of perfEvents, read/write/update mhpmevents -> read/write/update perfEvents
909  for (i <-0 until perfCntNum) {
910    when(mhpmevents(i).w.wen) {
911      perfEvents(i) := wdata
912    }
913  }
914  val csrevents = perfEvents.slice(24, 29)
915
916  val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
917  for (i <- 0 until numPCntHc * coreParams.L2NBanks) {
918    hcEvents(i) := io.perf.perfEventsHc(i)
919  }
920
921  val allHcPerfEvents = hcEvents.map(x => (s"Hc", x.value))
922  if (printEventCoding) {
923    for (((name, inc), i) <- allHcPerfEvents.zipWithIndex) {
924      println("HuanCun perfEvents Set", name, inc, i)
925    }
926  }
927
928  val hpmHc = HPerfMonitor(csrevents, hcEvents)
929
930  val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU)
931  val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool())))
932  for (i <-0 until perfCntNum) {
933    countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR
934  }
935  val allPerfEvents = io.perf.perfEventsFrontend ++
936    io.perf.perfEventsBackend ++
937    io.perf.perfEventsLsu ++
938    hpmHc.getPerf
939
940  val ofFromPerfCntVec  = Wire(Vec(perfCntNum, Bool()))
941  val lcofiReqVec       = Wire(Vec(perfCntNum, Bool()))
942  for(i <- 0 until perfCntNum) {
943    mhpmcounters(i) match {
944      case m: HasPerfCounterBundle =>
945        m.countingEn        := countingEn(i)
946        m.perf              := allPerfEvents(i)
947        ofFromPerfCntVec(i) := m.toMhpmeventOF
948      case _ =>
949    }
950    perfEvents(i)   := (perfEvents(i).head(1).asBool || ofFromPerfCntVec(i)) ## perfEvents(i).tail(1)
951    lcofiReqVec(i)  := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1)
952  }
953
954  val lcofiReq = lcofiReqVec.asUInt.orR
955  mip match {
956    case m: HasLocalInterruptReqBundle =>
957      m.lcofiReq := lcofiReq
958    case _ =>
959  }
960  /**
961   * perf_end
962   */
963
964  /**
965   * [[io.status.custom]] connection
966   */
967  io.status.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
968  io.status.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
969  io.status.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
970  io.status.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
971  io.status.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
972  io.status.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
973  io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
974  io.status.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
975  io.status.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
976  io.status.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
977
978  io.status.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
979
980  io.status.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
981  io.status.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
982  io.status.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
983  io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
984  io.status.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
985
986  io.status.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
987  io.status.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
988  io.status.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
989  io.status.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
990  io.status.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
991  io.status.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
992  io.status.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
993
994  io.status.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
995  io.status.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
996  io.status.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
997  io.status.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
998  io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
999
1000  io.status.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
1001  io.status.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool
1002
1003  private val csrAccess = wen || ren
1004
1005  private val imsicAddrValid =
1006    csrAccess &&  addr === CSRs.mireg.U &&  miselect.inIMSICRange ||
1007    csrAccess &&  addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange ||
1008    csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange
1009
1010  private val imsicAddr = Mux1H(Seq(
1011    (csrAccess &&  addr === CSRs.mireg.U) -> miselect.rdata,
1012    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata,
1013    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata,
1014  ))
1015
1016  private val imsicAddrPrivState = Mux1H(Seq(
1017    (csrAccess &&  addr === CSRs.mireg.U) -> PrivState.ModeM,
1018    (csrAccess &&  addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS,
1019    (csrAccess && (addr === CSRs.sireg.U &&  isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS,
1020  ))
1021
1022  private val imsicWdataValid =
1023    mireg.w.wen  && miselect.inIMSICRange ||
1024    sireg.w.wen  && siselect.inIMSICRange ||
1025    vsireg.w.wen && vsiselect.inIMSICRange
1026
1027  toAIA.addr.valid     := imsicAddrValid
1028  toAIA.addr.bits.addr := imsicAddr
1029  toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM
1030  toAIA.addr.bits.v    := imsicAddrPrivState.V
1031
1032  toAIA.wdata.valid := imsicWdataValid
1033  toAIA.wdata.bits.op := io.in.bits.op
1034  toAIA.wdata.bits.data := io.in.bits.src
1035  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
1036  toAIA.mClaim  := mtopei.w.wen
1037  toAIA.sClaim  := stopei.w.wen
1038  toAIA.vsClaim := vstopei.w.wen
1039
1040  // tlb
1041  io.tlb.satpASIDChanged  := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/=  satp.w.wdataFields.ASID)
1042  io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID)
1043  io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID)
1044  io.tlb.satp := satp.rdata
1045  io.tlb.vsatp := vsatp.rdata
1046  io.tlb.hgatp := hgatp.rdata
1047  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
1048  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
1049  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
1050  io.tlb.vsum := vsstatus.regOut.SUM.asBool
1051  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
1052
1053  io.tlb.imode := PRVM.asUInt
1054  io.tlb.dmode := Mux(
1055    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV,
1056    mstatus.regOut.MPP.asUInt,
1057    PRVM.asUInt
1058  )
1059  io.tlb.dvirt := Mux(
1060    (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mstatus.regOut.MPP =/= PrivMode.M,
1061    mstatus.regOut.MPV.asUInt,
1062    V.asUInt
1063  )
1064
1065  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
1066  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
1067  io.toDecode.illegalInst.sfencePart := isModeHU
1068  io.toDecode.virtualInst.sfencePart := isModeVU
1069  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
1070  io.toDecode.illegalInst.hfenceVVMA := isModeHU
1071  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
1072  io.toDecode.illegalInst.hlsv       := isModeHU && hstatus.regOut.HU
1073  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
1074  io.toDecode.illegalInst.fsIsOff    := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off
1075  io.toDecode.illegalInst.vsIsOff    := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off
1076  io.toDecode.illegalInst.wfi        := isModeHU || !isModeM && mstatus.regOut.TW
1077  io.toDecode.virtualInst.wfi        := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW
1078
1079  // Always instantiate basic difftest modules.
1080  if (env.AlwaysBasicDiff || env.EnableDifftest) {
1081    val hartId = io.fromTop.hartId
1082    val trapValid = io.fromRob.trap.valid
1083    val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt
1084    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
1085    val interruptNO = Mux(interrupt, trapNO, 0.U)
1086    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
1087    val ivmHS = isModeHS &&  satp.regOut.MODE =/= SatpMode.Bare
1088    val ivmVS = isModeVS && vsatp.regOut.MODE =/= SatpMode.Bare
1089    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
1090    val exceptionPC = Mux(ivmHS || ivmVS, SignExt(trapPC, XLEN), ZeroExt(trapPC, XLEN))
1091
1092    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
1093    diffArchEvent.coreid := hartId
1094    diffArchEvent.valid := trapValid
1095    diffArchEvent.interrupt := interruptNO
1096    diffArchEvent.exception := exceptionNO
1097    diffArchEvent.exceptionPC := exceptionPC
1098    if (env.EnableDifftest) {
1099      diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr
1100    }
1101
1102    val diffCSRState = DifftestModule(new DiffCSRState)
1103    diffCSRState.coreid         := hartId
1104    diffCSRState.privilegeMode  := privState.PRVM.asUInt
1105    diffCSRState.mstatus        := mstatus.rdata.asUInt
1106    diffCSRState.sstatus        := mstatus.sstatus.asUInt
1107    diffCSRState.mepc           := mepc.rdata.asUInt
1108    diffCSRState.sepc           := sepc.rdata.asUInt
1109    diffCSRState.mtval          := mtval.rdata.asUInt
1110    diffCSRState.stval          := stval.rdata.asUInt
1111    diffCSRState.mtvec          := mtvec.rdata.asUInt
1112    diffCSRState.stvec          := stvec.rdata.asUInt
1113    diffCSRState.mcause         := mcause.rdata.asUInt
1114    diffCSRState.scause         := scause.rdata.asUInt
1115    diffCSRState.satp           := satp.rdata.asUInt
1116    diffCSRState.mip            := mip.regOut.asUInt
1117    diffCSRState.mie            := mie.rdata.asUInt
1118    diffCSRState.mscratch       := mscratch.rdata.asUInt
1119    diffCSRState.sscratch       := sscratch.rdata.asUInt
1120    diffCSRState.mideleg        := mideleg.rdata.asUInt
1121    diffCSRState.medeleg        := medeleg.rdata.asUInt
1122
1123    val diffDebugMode = DifftestModule(new DiffDebugMode)
1124    diffDebugMode.coreid    := hartId
1125    diffDebugMode.debugMode := debugMode
1126    diffDebugMode.dcsr      := dcsr.rdata.asUInt
1127    diffDebugMode.dpc       := dpc.rdata.asUInt
1128    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
1129    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
1130
1131    val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState)
1132    diffTriggerCSRState.coreid    := hartId
1133    diffTriggerCSRState.tselect   := tselect.rdata
1134    diffTriggerCSRState.tdata1    := tdata1.rdata
1135    diffTriggerCSRState.tinfo     := tinfo.rdata
1136    diffTriggerCSRState.tcontrol  := tcontrol.rdata
1137
1138    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
1139    diffVecCSRState.coreid := hartId
1140    diffVecCSRState.vstart := vstart.rdata.asUInt
1141    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
1142    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
1143    diffVecCSRState.vcsr := vcsr.rdata.asUInt
1144    diffVecCSRState.vl := RegNext(io.fromRob.commit.vl)
1145    diffVecCSRState.vtype := vtype.rdata.asUInt
1146    diffVecCSRState.vlenb := vlenb.rdata.asUInt
1147
1148    val diffFpCSRState = DifftestModule(new DiffFpCSRState)
1149    diffFpCSRState.coreid := hartId
1150    diffFpCSRState.fcsr := fcsr.rdata.asUInt
1151
1152    val diffHCSRState = DifftestModule(new DiffHCSRState)
1153    diffHCSRState.coreid      := hartId
1154    diffHCSRState.virtMode    := privState.V.asBool
1155    diffHCSRState.mtval2      := mtval2.rdata.asUInt
1156    diffHCSRState.mtinst      := mtinst.rdata.asUInt
1157    diffHCSRState.hstatus     := hstatus.rdata.asUInt
1158    diffHCSRState.hideleg     := hideleg.rdata.asUInt
1159    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
1160    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
1161    diffHCSRState.htval       := htval.rdata.asUInt
1162    diffHCSRState.htinst      := htinst.rdata.asUInt
1163    diffHCSRState.hgatp       := hgatp.rdata.asUInt
1164    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
1165    diffHCSRState.vstvec      := vstvec.rdata.asUInt
1166    diffHCSRState.vsepc       := vsepc.rdata.asUInt
1167    diffHCSRState.vscause     := vscause.rdata.asUInt
1168    diffHCSRState.vstval      := vstval.rdata.asUInt
1169    diffHCSRState.vsatp       := vsatp.rdata.asUInt
1170    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
1171
1172  }
1173}
1174
1175trait IpIeAliasConnect {
1176  self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel =>
1177
1178  mip.fromMvip  := mvip.toMip
1179  mip.fromSip   := sip.toMip
1180  mip.fromVSip  := vsip.toMip
1181  mvip.fromMip  := mip.toMvip
1182  mvip.fromSip  := sip.toMvip
1183  mvip.fromVSip := vsip.toMvip
1184  hvip.fromMip  := mip.toHvip
1185  hvip.fromHip  := hip.toHvip
1186  hvip.fromVSip := vsip.toHvip
1187
1188  mie.fromHie  := hie.toMie
1189  mie.fromSie  := sie.toMie
1190  mie.fromVSie := vsie.toMie
1191  sie.fromVSie := vsie.toSie
1192}
1193
1194object NewCSRMain extends App {
1195  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
1196    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
1197
1198  val defaultConfig = config.alterPartial({
1199    // Get XSCoreParams and pass it to the "small module"
1200    case XSCoreParamsKey => config(XSTileKey).head
1201  })
1202
1203  Generator.execute(
1204    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
1205    new NewCSR()(defaultConfig),
1206    firtoolOpts
1207  )
1208
1209  println("done")
1210}