xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision 40ac5bb1842d44eb247ef164881a9d06c158a05a)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import freechips.rocketchip.rocket.CSRs
6import difftest._
7import org.chipsalliance.cde.config.Parameters
8import top.{ArgParser, Generator}
9import utility.{SignExt, ZeroExt}
10import utils.OptionWrapper
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, TrapEntryEventInput, TrapEntryHSEventSinkBundle, TrapEntryMEventSinkBundle, TrapEntryVSEventSinkBundle}
15import xiangshan.backend.fu.fpu.Bundles.Frm
16import xiangshan.backend.fu.vector.Bundles.{Vl, Vstart, Vxrm, Vxsat}
17import xiangshan.{HasXSParameter, XSCoreParamsKey, XSTileKey}
18
19object CSRConfig {
20  final val GEILEN = 63
21
22  final val ASIDLEN = 16 // the length of ASID of XS implementation
23
24  final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec
25
26  final val HIIDWidth = 12 // support Hvictl[27:16](IID)
27
28  final val VMIDLEN = 14 // the length of VMID of XS implementation
29
30  final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec
31
32  // the width of VGEIN
33  final val VGEINWidth = 6
34
35  final val VaddrMaxWidth = 41 // only Sv39 and Sv39x4
36
37  final val XLEN = 64 // Todo: use XSParams
38
39  final val VLEN = 128
40
41  // Since we need macro to compute the width of CSR field, the input of macro should be the value that can be computed
42  // at compile time. The log2Up function cannot be used as meta-programming function, so we use litral value here
43  // log2Up(128 + 1), hold 0~128
44  final val VlWidth = 8
45}
46
47class NewCSR(implicit val p: Parameters) extends Module
48  with HasXSParameter
49  with MachineLevel
50  with SupervisorLevel
51  with HypervisorLevel
52  with VirtualSupervisorLevel
53  with Unprivileged
54  with CSRAIA
55  with HasExternalInterruptBundle
56  with SupervisorMachineAliasConnect
57  with CSREvents
58  with DebugLevel
59  with CSRCustom
60{
61
62  import CSRConfig._
63
64  val io = IO(new Bundle {
65    val fromTop = Input(new Bundle {
66      val hartId = UInt(hartIdLen.W)
67    })
68    val in = Input(new Bundle {
69      val wen = Bool()
70      val ren = Bool()
71      val addr = UInt(12.W)
72      val wdata = UInt(64.W)
73    })
74    val fromMem = Input(new Bundle {
75      val excpVA  = UInt(VaddrMaxWidth.W)
76      val excpGPA = UInt(VaddrMaxWidth.W) // Todo: use guest physical address width
77    })
78    val fromRob = Input(new Bundle {
79      val trap = ValidIO(new Bundle {
80        val pc = UInt(VaddrMaxWidth.W)
81        val instr = UInt(32.W)
82        val trapVec = UInt(64.W)
83        val singleStep = Bool()
84        val crossPageIPFFix = Bool()
85        val isInterrupt = Bool()
86      })
87      val commit = Input(new RobCommitCSR)
88    })
89    val mret = Input(Bool())
90    val sret = Input(Bool())
91    val dret = Input(Bool())
92    val wfi  = Input(Bool())
93
94    val out = Output(new Bundle {
95      val EX_II = Bool()
96      val EX_VI = Bool()
97      val flushPipe = Bool()
98      val rData = UInt(64.W)
99      val targetPc = UInt(VaddrMaxWidth.W)
100      val regOut = UInt(64.W)
101      val privState = new PrivState
102      val interrupt = Bool()
103      val wfiEvent = Bool()
104      val tvm = Bool()
105      val vtvm = Bool()
106      // fp
107      val fpState = new Bundle {
108        val off = Bool()
109        val frm = Frm()
110      }
111      // vec
112      val vecState = new Bundle {
113        val vstart = Vstart()
114        val vxsat = Vxsat()
115        val vxrm = Vxrm()
116        val vcsr = UInt(XLEN.W)
117        val vl = Vl()
118        val vtype = UInt(XLEN.W)
119        val vlenb = UInt(XLEN.W)
120        val off = Bool()
121      }
122      // perf
123      val isPerfCnt = Bool()
124      // debug
125      val debugMode = Bool()
126      val singleStepFlag = Bool()
127      // custom
128      val custom = new CSRCustomState
129    })
130    // tlb
131    val tlb = Output(new Bundle {
132      val satpASIDChanged = Bool()
133      val satp = new SatpBundle
134      val mxr = Bool()
135      val sum = Bool()
136      val imode = UInt(2.W)
137      val dmode = UInt(2.W)
138    })
139    // customCtrl
140    val customCtrl = Output(new Bundle {
141      val sbpctl = UInt(XLEN.W)
142      val spfctl = UInt(XLEN.W)
143      val slvpredctl = UInt(XLEN.W)
144      val smblockctl = UInt(XLEN.W)
145      val srnctl = UInt(XLEN.W)
146      val sdsid = UInt(XLEN.W)
147      val sfetchctl  = Bool()
148    })
149  })
150
151  val toAIA   = IO(Output(new CSRToAIABundle))
152  val fromAIA = IO(Flipped(Output(new AIAToCSRBundle)))
153
154  dontTouch(toAIA)
155  dontTouch(fromAIA)
156
157  val wen   = io.in.wen
158  val addr  = io.in.addr
159  val wdata = io.in.wdata
160
161  val ren   = io.in.ren
162  val raddr = io.in.addr
163
164  val hasTrap = io.fromRob.trap.valid
165  val trapVec = io.fromRob.trap.bits.trapVec
166  val trapPC = io.fromRob.trap.bits.pc
167  val trapIsInterrupt = io.fromRob.trap.bits.isInterrupt
168  val trapIsCrossPageIPF = io.fromRob.trap.bits.crossPageIPFFix
169
170  // CSR Privilege State
171  val PRVM = RegInit(PrivMode(0), PrivMode.M)
172  val V = RegInit(VirtMode(0), VirtMode.Off)
173  val debugMode = RegInit(false.B)
174  private val privState = Wire(new PrivState)
175  privState.PRVM := PRVM
176  privState.V := V
177
178  val permitMod = Module(new CSRPermitModule)
179
180  private val wenLegal = permitMod.io.out.hasLegalWen
181
182  val legalSret = permitMod.io.out.hasLegalSret
183  val legalMret = permitMod.io.out.hasLegalMret
184  val isDret = io.dret // Todo: check permission
185  val isWfi  = io.wfi  // Todo: check permission
186
187  var csrRwMap =
188    machineLevelCSRMap ++
189    supervisorLevelCSRMap ++
190    hypervisorCSRMap ++
191    virtualSupervisorCSRMap ++
192    unprivilegedCSRMap ++
193    debugCSRMap ++
194    aiaCSRMap ++
195    customCSRMap
196
197  val csrMods =
198    machineLevelCSRMods ++
199    supervisorLevelCSRMods ++
200    hypervisorCSRMods ++
201    virtualSupervisorCSRMods ++
202    unprivilegedCSRMods ++
203    debugCSRMods ++
204    aiaCSRMods ++
205    customCSRMods
206
207  var csrOutMap =
208    machineLevelCSROutMap ++
209    supervisorLevelCSROutMap ++
210    hypervisorCSROutMap ++
211    virtualSupervisorCSROutMap ++
212    unprivilegedCSROutMap ++
213    debugCSROutMap ++
214    aiaCSROutMap ++
215    customCSROutMap
216
217  val trapHandleMod = Module(new TrapHandleModule)
218
219  trapHandleMod.io.in.trapInfo.valid := hasTrap
220  trapHandleMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt
221  trapHandleMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
222  trapHandleMod.io.in.privState.PRVM := PRVM
223  trapHandleMod.io.in.privState.V := V
224  trapHandleMod.io.in.mideleg := mideleg.regOut
225  trapHandleMod.io.in.medeleg := medeleg.regOut
226  trapHandleMod.io.in.hideleg := hideleg.regOut
227  trapHandleMod.io.in.hedeleg := hedeleg.regOut
228  trapHandleMod.io.in.mtvec := mtvec.regOut
229  trapHandleMod.io.in.stvec := stvec.regOut
230  trapHandleMod.io.in.vstvec := vstvec.regOut
231
232  val entryPrivState = trapHandleMod.io.out.entryPrivState
233
234    // interrupt
235  val intrMod = Module(new InterruptFilter)
236  intrMod.io.in.privState.PRVM := PRVM
237  intrMod.io.in.privState.V := V
238  intrMod.io.in.mstatusMIE := mstatus.rdata.MIE.asBool
239  intrMod.io.in.sstatusSIE := mstatus.rdata.SIE.asBool
240  intrMod.io.in.vsstatusSIE := vsstatus.rdata.SIE.asBool
241  intrMod.io.in.mip := mip.rdata.asUInt
242  intrMod.io.in.mie := mie.rdata.asUInt
243  intrMod.io.in.mideleg := mideleg.rdata.asUInt
244  intrMod.io.in.sip := sip.rdata.asUInt
245  intrMod.io.in.sie := sie.rdata.asUInt
246  intrMod.io.in.hip := hip.rdata.asUInt
247  intrMod.io.in.hie := hie.rdata.asUInt
248  intrMod.io.in.hideleg := hideleg.rdata.asUInt
249  intrMod.io.in.vsip := vsip.rdata.asUInt
250  intrMod.io.in.vsie := vsie.rdata.asUInt
251  intrMod.io.in.hvictl := hvictl.rdata.asUInt
252  intrMod.io.in.hstatus := hstatus.rdata.asUInt
253  intrMod.io.in.mtopei := mtopei.rdata.asUInt
254  intrMod.io.in.stopei := stopei.rdata.asUInt
255  intrMod.io.in.vstopei := vstopei.rdata.asUInt
256  intrMod.io.in.hviprio1 := hviprio1.rdata.asUInt
257  intrMod.io.in.hviprio2 := hviprio2.rdata.asUInt
258  intrMod.io.in.miprios := Cat(miregiprios.map(_.rdata.asInstanceOf[CSRBundle].asUInt).reverse)
259  intrMod.io.in.hsiprios := Cat(siregiprios.map(_.rdata.asInstanceOf[CSRBundle].asUInt).reverse)
260  // val disableInterrupt = debugMode || (dcsr.rdata.STEP.asBool && !dcsr.rdata.STEPIE.asBool)
261  // val intrVec = Cat(debugIntr && !debugMode, mie.rdata.asUInt(11, 0) & mip.rdata.asUInt & intrVecEnable.asUInt) // Todo: asUInt(11,0) is ok?
262
263  for ((id, (wBundle, _)) <- csrRwMap) {
264    wBundle.wen := wenLegal && addr === id.U
265    wBundle.wdata := wdata
266  }
267
268  // Todo: support set dirty only when fcsr has changed
269  private val writeFpState = wenLegal && Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _)
270  private val writeVecState = wenLegal && Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _)
271
272  permitMod.io.in.csrAccess.ren := ren
273  permitMod.io.in.csrAccess.wen := wen
274  permitMod.io.in.csrAccess.addr := addr
275
276  permitMod.io.in.privState.V := V
277  permitMod.io.in.privState.PRVM := PRVM
278
279  permitMod.io.in.mret := io.mret
280  permitMod.io.in.sret := io.sret
281
282  permitMod.io.in.status.tsr := mstatus.rdata.TSR.asBool
283  permitMod.io.in.status.vtsr := hstatus.rdata.VTSR.asBool
284
285  miregiprios.foreach { mod =>
286    mod.w.wen := (addr === mireg.addr.U) && (miselect.regOut.ALL.asUInt === mod.addr.U)
287    mod.w.wdata := wdata
288  }
289
290  siregiprios.foreach { mod =>
291    mod.w.wen := (addr === sireg.addr.U) && (siselect.regOut.ALL.asUInt === mod.addr.U)
292    mod.w.wdata := wdata
293  }
294
295  mhartid.hartid := this.io.fromTop.hartId
296
297  csrMods.foreach { mod =>
298    mod match {
299      case m: HypervisorBundle =>
300        m.hstatus := hstatus.regOut
301        m.hvip := hvip.regOut
302        m.hideleg := hideleg.regOut
303        m.hedeleg := hedeleg.regOut
304        m.hgeip := hgeip.regOut
305        m.hgeie := hgeie.regOut
306        m.hip := hip.regOut
307        m.hie := hie.regOut
308      case _ =>
309    }
310    mod match {
311      case m: HasMachineInterruptBundle =>
312        m.mvien := mvien.regOut
313        m.mvip := mvip.regOut
314        m.mip := mip.regOut
315        m.mie := mie.regOut
316      case _ =>
317    }
318    mod match {
319      case m: HasMachineDelegBundle =>
320        m.mideleg := mideleg.regOut
321        m.medeleg := medeleg.regOut
322      case _ =>
323    }
324    mod match {
325      case m: HasMachineCounterControlBundle =>
326        m.mcountinhibit := mcountinhibit.regOut
327      case _ =>
328    }
329    mod match {
330      case m: HasExternalInterruptBundle =>
331        m.platformIRP := this.platformIRP
332      case _ =>
333    }
334    mod match {
335      case m: HasRobCommitBundle =>
336        m.robCommit := io.fromRob.commit
337        m.robCommit.fsDirty := io.fromRob.commit.fsDirty || writeFpState
338        m.robCommit.vsDirty := io.fromRob.commit.vsDirty || writeVecState
339      case _ =>
340    }
341    mod match {
342      case m: TrapEntryMEventSinkBundle =>
343        m.trapToM := trapEntryMEvent.out
344      case _ =>
345    }
346    mod match {
347      case m: TrapEntryHSEventSinkBundle =>
348        m.trapToHS := trapEntryHSEvent.out
349      case _ =>
350    }
351    mod match {
352      case m: TrapEntryVSEventSinkBundle =>
353        m.trapToVS := trapEntryVSEvent.out
354      case _ =>
355    }
356    mod match {
357      case m: MretEventSinkBundle =>
358        m.retFromM := mretEvent.out
359      case _ =>
360    }
361    mod match {
362      case m: SretEventSinkBundle =>
363        m.retFromS := sretEvent.out
364      case _ =>
365    }
366    mod match {
367      case m: DretEventSinkBundle =>
368        m.retFromD := dretEvent.out
369      case _ =>
370    }
371    mod match {
372      case m: HasAIABundle =>
373        m.aiaToCSR.rdata.valid := fromAIA.rdata.valid
374        m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data
375        m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal
376        m.aiaToCSR.mtopei.valid := fromAIA.mtopei.valid
377        m.aiaToCSR.stopei.valid := fromAIA.stopei.valid
378        m.aiaToCSR.vstopei.valid := fromAIA.vstopei.valid
379        m.aiaToCSR.mtopei.bits := fromAIA.mtopei.bits
380        m.aiaToCSR.stopei.bits := fromAIA.stopei.bits
381        m.aiaToCSR.vstopei.bits := fromAIA.vstopei.bits
382      case _ =>
383    }
384    mod match {
385      case m: HasInterruptFilterSink =>
386        m.topIR.mtopi  := intrMod.io.out.mtopi
387        m.topIR.stopi  := intrMod.io.out.stopi
388        m.topIR.vstopi := intrMod.io.out.vstopi
389      case _ =>
390    }
391    mod match {
392      case m: HasISelectBundle =>
393        m.privState.PRVM := PRVM
394        m.privState.V := V
395        m.miselect := miselect.regOut
396        m.siselect := siselect.regOut
397        m.mireg := mireg.regOut.asUInt
398        m.sireg := sireg.regOut.asUInt
399      case _ =>
400    }
401  }
402
403  csrMods.foreach { mod =>
404    println(s"${mod.modName}: ")
405    println(mod.dumpFields)
406  }
407
408  trapEntryMEvent .valid := hasTrap && entryPrivState.isModeM
409  trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS
410  trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS
411
412  Seq(trapEntryMEvent, trapEntryHSEvent, trapEntryVSEvent).foreach { eMod =>
413    eMod.in match {
414      case in: TrapEntryEventInput =>
415        in.causeNO := trapHandleMod.io.out.causeNO
416        in.trapPc := trapPC
417        in.isCrossPageIPF := trapIsCrossPageIPF
418
419        in.iMode.PRVM := PRVM
420        in.iMode.V := V
421        in.dMode.PRVM := Mux(mstatus.rdata.MPRV.asBool, mstatus.rdata.MPP, PRVM)
422        in.dMode.V := Mux(mstatus.rdata.MPRV.asBool, mstatus.rdata.MPV, V)
423
424        in.privState.PRVM := PRVM
425        in.privState.V := V
426        in.mstatus := mstatus.regOut
427        in.hstatus := hstatus.regOut
428        in.sstatus := mstatus.sstatus
429        in.vsstatus := vsstatus.regOut
430        in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec
431
432        in.satp := satp.rdata
433        in.vsatp := vsatp.rdata
434
435        in.memExceptionVAddr := io.fromMem.excpVA
436        in.memExceptionGPAddr := io.fromMem.excpGPA
437    }
438  }
439
440  mretEvent.valid := legalMret
441  mretEvent.in match {
442    case in =>
443      in.mstatus := mstatus.regOut
444      in.mepc := mepc.regOut
445  }
446
447  sretEvent.valid := legalSret
448  sretEvent.in match {
449    case in =>
450      in.privState.PRVM := PRVM
451      in.privState.V := V
452      in.sstatus := mstatus.sstatus
453      in.hstatus := hstatus.regOut
454      in.vsstatus := vsstatus.regOut
455      in.sepc := sepc.regOut
456      in.vsepc := vsepc.regOut
457  }
458
459  dretEvent.valid := isDret
460  dretEvent.in match {
461    case in =>
462      in.dcsr := dcsr.regOut
463      in.dpc  := dpc.regOut
464      in.mstatus := mstatus.regOut
465  }
466
467  PRVM := MuxCase(
468    PRVM,
469    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
470      x => x.out match {
471        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
472      }
473    }
474  )
475
476  V := MuxCase(
477    V,
478    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
479      x => x.out match {
480        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
481      }
482    }
483  )
484
485  debugMode := MuxCase(
486    debugMode,
487    Seq(
488      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits
489    )
490  )
491
492
493  // perf
494  val addrInPerfCnt = (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
495    (addr >= mcountinhibit.addr.U) && (addr <= mhpmevents.last.addr.U) ||
496    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) ||
497    (addr === CSRs.mip.U) ||
498    (addr === CSRs.hip.U)
499  // Todo: may be vsip and sip
500
501  // flush
502  val resetSatp = addr === satp.addr.U && wenLegal // write to satp will cause the pipeline be flushed
503
504  val wFcsrChangeRM = addr === fcsr.addr.U && wenLegal && wdata(7, 5) =/= fcsr.frm
505  val wFrmChangeRM  = addr === CSRs.frm.U  && wenLegal && wdata(2, 0) =/= fcsr.frm
506  val frmChange = wFcsrChangeRM || wFrmChangeRM
507
508  val wVcsrChangeRM = addr === CSRs.vcsr.U && wenLegal && wdata(2, 1) =/= vcsr.vxrm
509  val wVxrmChangeRM = addr === CSRs.vxrm.U && wenLegal && wdata(1, 0) =/= vcsr.vxrm
510  val vxrmChange = wVcsrChangeRM || wVxrmChangeRM
511
512  val flushPipe = resetSatp || frmChange || vxrmChange
513
514  // debug
515  val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable
516  debugIntrEnable := dretEvent.out.debugIntrEnable
517  val debugIntr = platformIRP.debugIP && debugIntrEnable
518
519  // fence
520  val tvm = mstatus.rdata.TVM.asBool
521  val vtvm = hstatus.rdata.VTVM.asBool
522
523  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rBundle)) =>
524    (raddr === id.U) -> rBundle.asUInt
525  })
526
527  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
528    (raddr === id.U) -> regOut
529  })
530
531  private val hasEvent = mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
532    trapEntryMEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid
533
534  io.out.EX_II     := permitMod.io.out.EX_II
535  io.out.EX_VI     := permitMod.io.out.EX_VI
536  io.out.flushPipe := flushPipe
537
538  io.out.rData := Mux(ren, rdata, 0.U)
539  io.out.regOut := regOut
540  io.out.targetPc := RegEnable(Mux1H(Seq(
541    mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits,
542    sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits,
543    dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits,
544    trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
545    trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
546    trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits,
547  )), hasEvent)
548
549  io.out.privState.PRVM := PRVM
550  io.out.privState.V    := V
551
552  io.out.fpState.frm := fcsr.frm
553  io.out.fpState.off := mstatus.rdata.FS === ContextStatus.Off
554  io.out.vecState.vstart := vstart.rdata.asUInt
555  io.out.vecState.vxsat := vcsr.vxsat
556  io.out.vecState.vxrm := vcsr.vxrm
557  io.out.vecState.vcsr := vcsr.rdata.asUInt
558  io.out.vecState.vl := vl.rdata.asUInt
559  io.out.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
560  io.out.vecState.vlenb := vlenb.rdata.asUInt
561  io.out.vecState.off := mstatus.rdata.VS === ContextStatus.Off
562  io.out.isPerfCnt := addrInPerfCnt
563  io.out.interrupt := intrMod.io.out.interruptVec.valid
564  io.out.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
565  io.out.debugMode := debugMode
566  io.out.singleStepFlag := !debugMode && dcsr.rdata.STEP
567  io.out.tvm := tvm
568  io.out.vtvm := vtvm
569
570  /**
571   * [[io.out.custom]] connection
572   */
573  io.out.custom.l1I_pf_enable           := spfctl.rdata.L1I_PF_ENABLE.asBool
574  io.out.custom.l2_pf_enable            := spfctl.rdata.L2_PF_ENABLE.asBool
575  io.out.custom.l1D_pf_enable           := spfctl.rdata.L1D_PF_ENABLE.asBool
576  io.out.custom.l1D_pf_train_on_hit     := spfctl.rdata.L1D_PF_TRAIN_ON_HIT.asBool
577  io.out.custom.l1D_pf_enable_agt       := spfctl.rdata.L1D_PF_ENABLE_AGT.asBool
578  io.out.custom.l1D_pf_enable_pht       := spfctl.rdata.L1D_PF_ENABLE_PHT.asBool
579  io.out.custom.l1D_pf_active_threshold := spfctl.rdata.L1D_PF_ACTIVE_THRESHOLD.asUInt
580  io.out.custom.l1D_pf_active_stride    := spfctl.rdata.L1D_PF_ACTIVE_STRIDE.asUInt
581  io.out.custom.l1D_pf_enable_stride    := spfctl.rdata.L1D_PF_ENABLE_STRIDE.asBool
582  io.out.custom.l2_pf_store_only        := spfctl.rdata.L2_PF_STORE_ONLY.asBool
583
584  io.out.custom.icache_parity_enable    := sfetchctl.rdata.ICACHE_PARITY_ENABLE.asBool
585
586  io.out.custom.dsid                    := sdsid.rdata.asUInt
587
588  io.out.custom.lvpred_disable          := slvpredctl.rdata.LVPRED_DISABLE.asBool
589  io.out.custom.no_spec_load            := slvpredctl.rdata.NO_SPEC_LOAD.asBool
590  io.out.custom.storeset_wait_store     := slvpredctl.rdata.STORESET_WAIT_STORE.asBool
591  io.out.custom.storeset_no_fast_wakeup := slvpredctl.rdata.STORESET_NO_FAST_WAKEUP.asBool
592  io.out.custom.lvpred_timeout          := slvpredctl.rdata.LVPRED_TIMEOUT.asUInt
593
594  io.out.custom.bp_ctrl.ubtb_enable     := sbpctl.rdata.UBTB_ENABLE .asBool
595  io.out.custom.bp_ctrl.btb_enable      := sbpctl.rdata.BTB_ENABLE  .asBool
596  io.out.custom.bp_ctrl.bim_enable      := sbpctl.rdata.BIM_ENABLE  .asBool
597  io.out.custom.bp_ctrl.tage_enable     := sbpctl.rdata.TAGE_ENABLE .asBool
598  io.out.custom.bp_ctrl.sc_enable       := sbpctl.rdata.SC_ENABLE   .asBool
599  io.out.custom.bp_ctrl.ras_enable      := sbpctl.rdata.RAS_ENABLE  .asBool
600  io.out.custom.bp_ctrl.loop_enable     := sbpctl.rdata.LOOP_ENABLE .asBool
601
602  io.out.custom.sbuffer_threshold                := smblockctl.rdata.SBUFFER_THRESHOLD.asUInt
603  io.out.custom.ldld_vio_check_enable            := smblockctl.rdata.LDLD_VIO_CHECK_ENABLE.asBool
604  io.out.custom.soft_prefetch_enable             := smblockctl.rdata.SOFT_PREFETCH_ENABLE.asBool
605  io.out.custom.cache_error_enable               := smblockctl.rdata.CACHE_ERROR_ENABLE.asBool
606  io.out.custom.uncache_write_outstanding_enable := smblockctl.rdata.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
607
608  io.out.custom.fusion_enable           := srnctl.rdata.FUSION_ENABLE.asBool
609  io.out.custom.wfi_enable              := srnctl.rdata.WFI_ENABLE.asBool
610  io.out.custom.svinval_enable          := srnctl.rdata.SVINVAL_ENABLE.asBool
611
612  // Todo: record the last address to avoid xireg is different with xiselect
613  toAIA.addr.valid := wenLegal && Seq(miselect, siselect, vsiselect).map(
614    _.addr.U === addr
615  ).reduce(_ || _)
616  toAIA.addr.bits.addr := addr
617  toAIA.addr.bits.prvm := PRVM
618  toAIA.addr.bits.v := V
619  toAIA.vgein := hstatus.rdata.VGEIN.asUInt
620  toAIA.wdata.valid := wenLegal && Seq(mireg, sireg, vsireg).map(
621    _.addr.U === addr
622  ).reduce(_ || _)
623  toAIA.wdata.bits.data := wdata
624  toAIA.mClaim := wenLegal && mtopei.addr.U === addr
625  toAIA.sClaim := wenLegal && stopei.addr.U === addr
626  toAIA.vsClaim := wenLegal && vstopei.addr.U === addr
627
628  // tlb
629  io.tlb.satpASIDChanged := wenLegal && addr === CSRs.satp.U && satp.rdata.ASID =/= wdata.asTypeOf(new SatpBundle).ASID
630  io.tlb.satp := satp.rdata
631  io.tlb.mxr := mstatus.rdata.MXR.asBool
632  io.tlb.sum := mstatus.rdata.SUM.asBool
633  io.tlb.imode := PRVM.asUInt
634  io.tlb.dmode := Mux((debugMode && dcsr.rdata.MPRVEN.asBool || !debugMode) && mstatus.rdata.MPRV.asBool, mstatus.rdata.MPP.asUInt, PRVM.asUInt)
635
636  // customCtrl
637  io.customCtrl.sbpctl := sbpctl.rdata.asUInt
638  io.customCtrl.spfctl := spfctl.rdata.asUInt
639  io.customCtrl.slvpredctl := slvpredctl.rdata.asUInt
640  io.customCtrl.smblockctl := smblockctl.rdata.asUInt
641  io.customCtrl.srnctl := srnctl.rdata.asUInt
642  io.customCtrl.sdsid := sdsid.rdata.asUInt
643  io.customCtrl.sfetchctl := sfetchctl.rdata.ICACHE_PARITY_ENABLE.asBool
644
645  // Always instantiate basic difftest modules.
646  if (env.AlwaysBasicDiff || env.EnableDifftest) {
647    val hartId = io.fromTop.hartId
648    val trapValid = io.fromRob.trap.valid
649    val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt
650    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
651    val interruptNO = Mux(interrupt, trapNO, 0.U)
652    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
653    val ivmHS = privState.isModeHS && satp.rdata.MODE =/= SatpMode.Bare
654    val ivmVS = privState.isModeVS && vsatp.rdata.MODE =/= SatpMode.Bare
655    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
656    val exceptionPC = Mux(ivmHS || ivmVS, SignExt(trapPC, XLEN), ZeroExt(trapPC, XLEN))
657
658    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
659    diffArchEvent.coreid := hartId
660    diffArchEvent.valid := trapValid
661    diffArchEvent.interrupt := interruptNO
662    diffArchEvent.exception := exceptionNO
663    diffArchEvent.exceptionPC := exceptionPC
664    if (env.EnableDifftest) {
665      diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr
666    }
667
668    val diffCSRState = DifftestModule(new DiffCSRState)
669    diffCSRState.coreid         := hartId
670    diffCSRState.privilegeMode  := privState.PRVM.asUInt
671    diffCSRState.mstatus        := mstatus.rdata.asUInt
672    diffCSRState.sstatus        := mstatus.sstatus.asUInt
673    diffCSRState.mepc           := mepc.rdata.asUInt
674    diffCSRState.sepc           := sepc.rdata.asUInt
675    diffCSRState.mtval          := mtval.rdata.asUInt
676    diffCSRState.stval          := stval.rdata.asUInt
677    diffCSRState.mtvec          := mtvec.rdata.asUInt
678    diffCSRState.stvec          := stvec.rdata.asUInt
679    diffCSRState.mcause         := mcause.rdata.asUInt
680    diffCSRState.scause         := scause.rdata.asUInt
681    diffCSRState.satp           := satp.rdata.asUInt
682    diffCSRState.mip            := mip.regOut.asUInt
683    diffCSRState.mie            := mie.rdata.asUInt
684    diffCSRState.mscratch       := mscratch.rdata.asUInt
685    diffCSRState.sscratch       := sscratch.rdata.asUInt
686    diffCSRState.mideleg        := mideleg.rdata.asUInt
687    diffCSRState.medeleg        := medeleg.rdata.asUInt
688
689    val diffDebugMode = DifftestModule(new DiffDebugMode)
690    diffDebugMode.coreid    := hartId
691    diffDebugMode.debugMode := debugMode
692    diffDebugMode.dcsr      := dcsr.rdata.asUInt
693    diffDebugMode.dpc       := dpc.rdata.asUInt
694    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
695    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
696
697    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
698    diffVecCSRState.coreid := hartId
699    diffVecCSRState.vstart := vstart.rdata.asUInt
700    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
701    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
702    diffVecCSRState.vcsr := vcsr.rdata.asUInt
703    diffVecCSRState.vl := vl.rdata.asUInt
704    diffVecCSRState.vtype := vtype.rdata.asUInt
705    diffVecCSRState.vlenb := vlenb.rdata.asUInt
706
707    val diffHCSRState = DifftestModule(new DiffHCSRState)
708    diffHCSRState.coreid      := hartId
709    diffHCSRState.virtMode    := privState.V.asBool
710    diffHCSRState.mtval2      := mtval2.rdata.asUInt
711    diffHCSRState.mtinst      := mtinst.rdata.asUInt
712    diffHCSRState.hstatus     := hstatus.rdata.asUInt
713    diffHCSRState.hideleg     := hideleg.rdata.asUInt
714    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
715    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
716    diffHCSRState.htval       := htval.rdata.asUInt
717    diffHCSRState.htinst      := htinst.rdata.asUInt
718    diffHCSRState.hgatp       := hgatp.rdata.asUInt
719    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
720    diffHCSRState.vstvec      := vstvec.rdata.asUInt
721    diffHCSRState.vsepc       := vsepc.rdata.asUInt
722    diffHCSRState.vscause     := vscause.rdata.asUInt
723    diffHCSRState.vstval      := vstval.rdata.asUInt
724    diffHCSRState.vsatp       := vsatp.rdata.asUInt
725    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
726
727  }
728}
729
730trait SupervisorMachineAliasConnect { self: NewCSR with MachineLevel with SupervisorLevel =>
731  mip.fromMvip := mvip.toMip
732  mip.fromSip := sip.toMip
733  mie.fromSie := sie.toMie
734}
735
736object NewCSRMain extends App {
737  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
738    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
739
740  val defaultConfig = config.alterPartial({
741    // Get XSCoreParams and pass it to the "small module"
742    case XSCoreParamsKey => config(XSTileKey).head
743  })
744
745  Generator.execute(
746    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
747    new NewCSR()(defaultConfig),
748    firtoolOpts
749  )
750
751  println("done")
752}