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