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