xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision 15ed99a7d4c12613ea837c94a00d17f8c7cb3ee7)
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.{DataHoldBypass, 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, TrapEntryDEventSinkBundle, TrapEntryEventInput, TrapEntryHSEventSinkBundle, TrapEntryMEventSinkBundle, TrapEntryVSEventSinkBundle}
15import xiangshan.backend.fu.fpu.Bundles.Frm
16import xiangshan.backend.fu.vector.Bundles.{Vl, Vstart, Vxrm, Vxsat}
17import xiangshan.backend.fu.wrapper.CSRToDecode
18import xiangshan.{FrontendTdataDistributeIO, HasXSParameter, MemTdataDistributeIO, XSCoreParamsKey, XSTileKey}
19import xiangshan._
20import xiangshan.backend.fu.util.CSRConst
21
22import scala.collection.immutable.SeqMap
23
24object CSRConfig {
25  final val GEILEN = 63
26
27  final val ASIDLEN = 16 // the length of ASID of XS implementation
28
29  final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec
30
31  final val HIIDWidth = 12 // support Hvictl[27:16](IID)
32
33  final val VMIDLEN = 14 // the length of VMID of XS implementation
34
35  final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec
36
37  // the width of VGEIN
38  final val VGEINWidth = 6
39
40  final val VaddrMaxWidth = 41 // only Sv39 and Sv39x4
41
42  final val XLEN = 64 // Todo: use XSParams
43
44  final val VLEN = 128
45
46  // Since we need macro to compute the width of CSR field, the input of macro should be the value that can be computed
47  // at compile time. The log2Up function cannot be used as meta-programming function, so we use litral value here
48  // log2Up(128 + 1), hold 0~128
49  final val VlWidth = 8
50
51  final val PAddrWidth = 36
52
53  final val AddrWidthInPage = 12
54
55  final val PMPAddrWidth = 36
56
57  final val PMPOffBits = 2
58
59  final val PMPAddrBits = PMPAddrWidth - PMPOffBits
60
61  // trigger
62  final val triggerNum    = 4     // Todo: use XSParams
63  final val tselectWidth  = 2     // log2Up(triggerNum)
64}
65
66class NewCSR(implicit val p: Parameters) extends Module
67  with HasXSParameter
68  with MachineLevel
69  with SupervisorLevel
70  with HypervisorLevel
71  with VirtualSupervisorLevel
72  with Unprivileged
73  with CSRAIA
74  with HasExternalInterruptBundle
75  with SupervisorMachineAliasConnect
76  with CSREvents
77  with DebugLevel
78  with CSRCustom
79  with CSRPMP
80{
81
82  import CSRConfig._
83
84  val io = IO(new Bundle {
85    val fromTop = Input(new Bundle {
86      val hartId = UInt(hartIdLen.W)
87    })
88    val in = Input(new Bundle {
89      val wen = Bool()
90      val ren = Bool()
91      val addr = UInt(12.W)
92      val wdata = UInt(64.W)
93    })
94    val fromMem = Input(new Bundle {
95      val excpVA  = UInt(VaddrMaxWidth.W)
96      val excpGPA = UInt(VaddrMaxWidth.W) // Todo: use guest physical address width
97    })
98    val fromRob = Input(new Bundle {
99      val trap = ValidIO(new Bundle {
100        val pc = UInt(VaddrMaxWidth.W)
101        val instr = UInt(32.W)
102        val trapVec = UInt(64.W)
103        val singleStep = Bool()
104        val triggerCf = new TriggerCf
105        val crossPageIPFFix = Bool()
106        val isInterrupt = Bool()
107      })
108      val commit = Input(new RobCommitCSR)
109    })
110    val mret = Input(Bool())
111    val sret = Input(Bool())
112    val dret = Input(Bool())
113    val wfi  = Input(Bool())
114    val ebreak = Input(Bool())
115
116    val out = Output(new Bundle {
117      val EX_II = Bool()
118      val EX_VI = Bool()
119      val flushPipe = Bool()
120      val rData = UInt(64.W)
121      val targetPc = UInt(VaddrMaxWidth.W)
122      val regOut = UInt(64.W)
123      val privState = new PrivState
124      val interrupt = Bool()
125      val wfiEvent = Bool()
126      val tvm = Bool()
127      val vtvm = Bool()
128      // fp
129      val fpState = new Bundle {
130        val off = Bool()
131        val frm = Frm()
132      }
133      // vec
134      val vecState = new Bundle {
135        val vstart = Vstart()
136        val vxsat = Vxsat()
137        val vxrm = Vxrm()
138        val vcsr = UInt(XLEN.W)
139        val vl = Vl()
140        val vtype = UInt(XLEN.W)
141        val vlenb = UInt(XLEN.W)
142        val off = Bool()
143      }
144      // perf
145      val isPerfCnt = Bool()
146      // debug
147      val debugMode = Bool()
148      val singleStepFlag = Bool()
149      // trigger
150      val frontendTrigger = new FrontendTdataDistributeIO()
151      val memTrigger = new MemTdataDistributeIO()
152      // custom
153      val custom = new CSRCustomState
154    })
155    // tlb
156    val tlb = Output(new Bundle {
157      val satpASIDChanged = Bool()
158      val vsatpASIDChanged = Bool()
159      val hgatpVMIDChanged = Bool()
160      val satp = new SatpBundle
161      val vsatp = new SatpBundle
162      val hgatp = new HgatpBundle
163      val mxr = Bool()
164      val sum = Bool()
165      val vmxr = Bool()
166      val vsum = Bool()
167      val spvp = Bool()
168      val imode = UInt(2.W)
169      val dmode = UInt(2.W)
170    })
171
172    val toDecode = new CSRToDecode
173  })
174
175  val toAIA   = IO(Output(new CSRToAIABundle))
176  val fromAIA = IO(Flipped(Output(new AIAToCSRBundle)))
177
178  dontTouch(toAIA)
179  dontTouch(fromAIA)
180
181  val wen   = io.in.wen
182  val addr  = io.in.addr
183  val wdata = io.in.wdata
184
185  val ren   = io.in.ren
186  val raddr = io.in.addr
187
188  val hasTrap = io.fromRob.trap.valid
189  val trapVec = io.fromRob.trap.bits.trapVec
190  val trapPC = io.fromRob.trap.bits.pc
191  val trapIsInterrupt = io.fromRob.trap.bits.isInterrupt
192  val trapIsCrossPageIPF = io.fromRob.trap.bits.crossPageIPFFix
193  val triggerCf = io.fromRob.trap.bits.triggerCf
194
195  // debug_intrrupt
196  val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable
197  val debugIntr = platformIRP.debugIP && debugIntrEnable
198
199  // CSR Privilege State
200  val PRVM = RegInit(PrivMode(0), PrivMode.M)
201  val V = RegInit(VirtMode(0), VirtMode.Off)
202  val debugMode = RegInit(false.B)
203
204  private val privState = Wire(new PrivState)
205  privState.PRVM := PRVM
206  privState.V := V
207
208  private val isModeM              = privState.isModeM
209  private val (isModeHS, isModeHU) = (privState.isModeHS, privState.isModeHU)
210  private val (isModeVS, isModeVU) = (privState.isModeVS, privState.isModeVU)
211
212  val permitMod = Module(new CSRPermitModule)
213
214  private val wenLegal = permitMod.io.out.hasLegalWen
215
216  val legalSret = permitMod.io.out.hasLegalSret
217  val legalMret = permitMod.io.out.hasLegalMret
218  val isDret = io.dret // Todo: check permission
219  val isWfi  = permitMod.io.out.hasLegalWfi
220
221  var csrRwMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] =
222    machineLevelCSRMap ++
223    supervisorLevelCSRMap ++
224    hypervisorCSRMap ++
225    virtualSupervisorCSRMap ++
226    unprivilegedCSRMap ++
227    debugCSRMap ++
228    aiaCSRMap ++
229    customCSRMap ++
230    pmpCSRMap
231
232  val csrMods: Seq[CSRModule[_]] =
233    machineLevelCSRMods ++
234    supervisorLevelCSRMods ++
235    hypervisorCSRMods ++
236    virtualSupervisorCSRMods ++
237    unprivilegedCSRMods ++
238    debugCSRMods ++
239    aiaCSRMods ++
240    customCSRMods ++
241    pmpCSRMods
242
243  var csrOutMap: SeqMap[Int, UInt] =
244    machineLevelCSROutMap ++
245    supervisorLevelCSROutMap ++
246    hypervisorCSROutMap ++
247    virtualSupervisorCSROutMap ++
248    unprivilegedCSROutMap ++
249    debugCSROutMap ++
250    aiaCSROutMap ++
251    customCSROutMap ++
252    pmpCSROutMap
253
254  // interrupt
255  val intrMod = Module(new InterruptFilter)
256  intrMod.io.in.privState := privState
257  intrMod.io.in.mstatusMIE := mstatus.regOut.MIE.asBool
258  intrMod.io.in.sstatusSIE := mstatus.regOut.SIE.asBool
259  intrMod.io.in.vsstatusSIE := vsstatus.regOut.SIE.asBool
260  intrMod.io.in.mip := mip.rdata.asUInt
261  intrMod.io.in.mie := mie.rdata.asUInt
262  intrMod.io.in.mideleg := mideleg.rdata.asUInt
263  intrMod.io.in.sip := sip.rdata.asUInt
264  intrMod.io.in.sie := sie.rdata.asUInt
265  intrMod.io.in.hip := hip.rdata.asUInt
266  intrMod.io.in.hie := hie.rdata.asUInt
267  intrMod.io.in.hideleg := hideleg.rdata.asUInt
268  intrMod.io.in.vsip := vsip.rdata.asUInt
269  intrMod.io.in.vsie := vsie.rdata.asUInt
270  intrMod.io.in.hvictl := hvictl.rdata.asUInt
271  intrMod.io.in.hstatus := hstatus.rdata.asUInt
272  intrMod.io.in.mtopei := mtopei.rdata.asUInt
273  intrMod.io.in.stopei := stopei.rdata.asUInt
274  intrMod.io.in.vstopei := vstopei.rdata.asUInt
275  intrMod.io.in.hviprio1 := hviprio1.rdata.asUInt
276  intrMod.io.in.hviprio2 := hviprio2.rdata.asUInt
277  intrMod.io.in.miprios := Cat(miregiprios.map(_.rdata).reverse)
278  intrMod.io.in.hsiprios := Cat(siregiprios.map(_.rdata).reverse)
279  // val disableInterrupt = debugMode || (dcsr.rdata.STEP.asBool && !dcsr.rdata.STEPIE.asBool)
280  // val intrVec = Cat(debugIntr && !debugMode, mie.rdata.asUInt(11, 0) & mip.rdata.asUInt & intrVecEnable.asUInt) // Todo: asUInt(11,0) is ok?
281
282  val intrVec = RegEnable(intrMod.io.out.interruptVec.bits, 0.U, intrMod.io.out.interruptVec.valid)
283
284  val trapHandleMod = Module(new TrapHandleModule)
285
286  trapHandleMod.io.in.trapInfo.valid := hasTrap
287  trapHandleMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt
288  trapHandleMod.io.in.trapInfo.bits.intrVec := intrVec
289  trapHandleMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
290  trapHandleMod.io.in.privState := privState
291  trapHandleMod.io.in.mideleg := mideleg.regOut
292  trapHandleMod.io.in.medeleg := medeleg.regOut
293  trapHandleMod.io.in.hideleg := hideleg.regOut
294  trapHandleMod.io.in.hedeleg := hedeleg.regOut
295  trapHandleMod.io.in.mtvec := mtvec.regOut
296  trapHandleMod.io.in.stvec := stvec.regOut
297  trapHandleMod.io.in.vstvec := vstvec.regOut
298
299  val entryPrivState = trapHandleMod.io.out.entryPrivState
300
301  // PMP
302  val pmpEntryMod = Module(new PMPEntryHandleModule)
303  pmpEntryMod.io.in.pmpCfg  := cfgs.map(_.regOut.asInstanceOf[PMPCfgBundle])
304  pmpEntryMod.io.in.pmpAddr := pmpaddr.map(_.regOut.asInstanceOf[PMPAddrBundle])
305  pmpEntryMod.io.in.ren   := ren
306  pmpEntryMod.io.in.wen   := wen
307  pmpEntryMod.io.in.addr  := addr
308  pmpEntryMod.io.in.wdata := wdata
309
310  for ((id, (wBundle, _)) <- csrRwMap) {
311    if (vsMapS.contains(id)) {
312      // VS access CSR by S: privState.isModeVS && addrMappedToVS === sMapVS(id).U
313      wBundle.wen := wenLegal && ((isModeVS && addr === vsMapS(id).U) || (!isModeVS && addr === id.U))
314      wBundle.wdata := wdata
315    } else if (sMapVS.contains(id)) {
316      wBundle.wen := wenLegal && !isModeVS && addr === id.U
317      wBundle.wdata := wdata
318    } else {
319      wBundle.wen := wenLegal && addr === id.U
320      wBundle.wdata := wdata
321    }
322  }
323
324  // Todo: support set dirty only when fcsr has changed
325  private val writeFpState = wenLegal && Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _)
326  private val writeVecState = wenLegal && Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _)
327
328  permitMod.io.in.csrAccess.ren := ren
329  permitMod.io.in.csrAccess.wen := wen
330  permitMod.io.in.csrAccess.addr := addr
331
332  permitMod.io.in.privState := privState
333  permitMod.io.in.debugMode := debugMode
334
335  permitMod.io.in.mret := io.mret
336  permitMod.io.in.sret := io.sret
337  permitMod.io.in.wfi  := io.wfi
338
339  permitMod.io.in.status.tsr := mstatus.regOut.TSR.asBool
340  permitMod.io.in.status.vtsr := hstatus.regOut.VTSR.asBool
341
342  permitMod.io.in.status.tw := mstatus.regOut.TW.asBool
343  permitMod.io.in.status.vtw := hstatus.regOut.VTW.asBool
344
345  permitMod.io.in.status.tvm  := mstatus.regOut.TVM.asBool
346  permitMod.io.in.status.vtvm := hstatus.regOut.VTVM.asBool
347
348  miregiprios.foreach { mod =>
349    mod.w.wen := (addr === mireg.addr.U) && (miselect.regOut.ALL.asUInt === mod.addr.U)
350    mod.w.wdata := wdata
351  }
352
353  siregiprios.foreach { mod =>
354    mod.w.wen := (addr === sireg.addr.U) && (siselect.regOut.ALL.asUInt === mod.addr.U)
355    mod.w.wdata := wdata
356  }
357
358  mhartid.hartid := this.io.fromTop.hartId
359
360  cfgs.zipWithIndex.foreach { case (mod, i) =>
361    mod.w.wen := wen && (addr === (0x3A0 + i / 8 * 2).U)
362    mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8))
363  }
364
365  pmpaddr.zipWithIndex.foreach{ case(mod, i) =>
366    mod.w.wen := wen && (addr === (0x3B0 + i).U)
367    mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i)
368  }
369
370  csrMods.foreach { mod =>
371    mod match {
372      case m: HypervisorBundle =>
373        m.hstatus := hstatus.regOut
374        m.hvip := hvip.regOut
375        m.hideleg := hideleg.regOut
376        m.hedeleg := hedeleg.regOut
377        m.hgeip := hgeip.regOut
378        m.hgeie := hgeie.regOut
379        m.hip := hip.regOut
380        m.hie := hie.regOut
381      case _ =>
382    }
383    mod match {
384      case m: HasMachineInterruptBundle =>
385        m.mvien := mvien.regOut
386        m.mvip := mvip.regOut
387        m.mip := mip.regOut
388        m.mie := mie.regOut
389      case _ =>
390    }
391    mod match {
392      case m: HasMachineDelegBundle =>
393        m.mideleg := mideleg.regOut
394        m.medeleg := medeleg.regOut
395      case _ =>
396    }
397    mod match {
398      case m: HasMachineCounterControlBundle =>
399        m.mcountinhibit := mcountinhibit.regOut
400      case _ =>
401    }
402    mod match {
403      case m: HasExternalInterruptBundle =>
404        m.platformIRP := this.platformIRP
405      case _ =>
406    }
407    mod match {
408      case m: HasRobCommitBundle =>
409        m.robCommit := io.fromRob.commit
410        m.robCommit.fsDirty := io.fromRob.commit.fsDirty || writeFpState
411        m.robCommit.vsDirty := io.fromRob.commit.vsDirty || writeVecState
412      case _ =>
413    }
414    mod match {
415      case m: TrapEntryDEventSinkBundle =>
416        m.trapToD := trapEntryDEvent.out
417      case _ =>
418    }
419    mod match {
420      case m: TrapEntryMEventSinkBundle =>
421        m.trapToM := trapEntryMEvent.out
422      case _ =>
423    }
424    mod match {
425      case m: TrapEntryHSEventSinkBundle =>
426        m.trapToHS := trapEntryHSEvent.out
427      case _ =>
428    }
429    mod match {
430      case m: TrapEntryVSEventSinkBundle =>
431        m.trapToVS := trapEntryVSEvent.out
432      case _ =>
433    }
434    mod match {
435      case m: MretEventSinkBundle =>
436        m.retFromM := mretEvent.out
437      case _ =>
438    }
439    mod match {
440      case m: SretEventSinkBundle =>
441        m.retFromS := sretEvent.out
442      case _ =>
443    }
444    mod match {
445      case m: DretEventSinkBundle =>
446        m.retFromD := dretEvent.out
447      case _ =>
448    }
449    mod match {
450      case m: HasAIABundle =>
451        m.aiaToCSR.rdata.valid := fromAIA.rdata.valid
452        m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data
453        m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal
454        m.aiaToCSR.mtopei.valid := fromAIA.mtopei.valid
455        m.aiaToCSR.stopei.valid := fromAIA.stopei.valid
456        m.aiaToCSR.vstopei.valid := fromAIA.vstopei.valid
457        m.aiaToCSR.mtopei.bits := fromAIA.mtopei.bits
458        m.aiaToCSR.stopei.bits := fromAIA.stopei.bits
459        m.aiaToCSR.vstopei.bits := fromAIA.vstopei.bits
460      case _ =>
461    }
462    mod match {
463      case m: HasInterruptFilterSink =>
464        m.topIR.mtopi  := intrMod.io.out.mtopi
465        m.topIR.stopi  := intrMod.io.out.stopi
466        m.topIR.vstopi := intrMod.io.out.vstopi
467      case _ =>
468    }
469    mod match {
470      case m: HasISelectBundle =>
471        m.privState := privState
472        m.miselect := miselect.regOut
473        m.siselect := siselect.regOut
474        m.mireg := mireg.regOut.asUInt
475        m.sireg := sireg.regOut.asUInt
476      case _ =>
477    }
478    mod match {
479      case m: HasPMPAddrSink =>
480        m.addrRData := pmpEntryMod.io.out.pmpAddrRData
481      case _ =>
482    }
483  }
484
485  csrMods.foreach { mod =>
486    println(s"${mod.modName}: ")
487    println(mod.dumpFields)
488  }
489
490  trapEntryMEvent .valid := hasTrap && entryPrivState.isModeM
491  trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS
492  trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS
493
494  Seq(trapEntryMEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod =>
495    eMod.in match {
496      case in: TrapEntryEventInput =>
497        in.causeNO := trapHandleMod.io.out.causeNO
498        in.trapPc := trapPC
499        in.isCrossPageIPF := trapIsCrossPageIPF
500
501        in.iMode.PRVM := PRVM
502        in.iMode.V := V
503        in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool, mstatus.regOut.MPP, PRVM)
504        in.dMode.V := Mux(mstatus.regOut.MPRV.asBool, mstatus.regOut.MPV, V)
505
506        in.privState := privState
507        in.mstatus := mstatus.regOut
508        in.hstatus := hstatus.regOut
509        in.sstatus := mstatus.sstatus
510        in.vsstatus := vsstatus.regOut
511        in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec
512
513        in.satp  := satp.regOut
514        in.vsatp := vsatp.regOut
515        in.hgatp := hgatp.regOut
516
517        in.memExceptionVAddr := io.fromMem.excpVA
518        in.memExceptionGPAddr := io.fromMem.excpGPA
519    }
520  }
521
522  mretEvent.valid := legalMret
523  mretEvent.in match {
524    case in =>
525      in.mstatus := mstatus.regOut
526      in.mepc := mepc.regOut
527  }
528
529  sretEvent.valid := legalSret
530  sretEvent.in match {
531    case in =>
532      in.privState := privState
533      in.sstatus := mstatus.sstatus
534      in.hstatus := hstatus.regOut
535      in.vsstatus := vsstatus.regOut
536      in.sepc := sepc.regOut
537      in.vsepc := vsepc.regOut
538  }
539
540  dretEvent.valid := isDret
541  dretEvent.in match {
542    case in =>
543      in.dcsr := dcsr.regOut
544      in.dpc  := dpc.regOut
545      in.mstatus := mstatus.regOut
546  }
547
548  PRVM := MuxCase(
549    PRVM,
550    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
551      x => x.out match {
552        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
553      }
554    }
555  )
556
557  V := MuxCase(
558    V,
559    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
560      x => x.out match {
561        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
562      }
563    }
564  )
565
566  debugMode := MuxCase(
567    debugMode,
568    Seq(
569      dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits,
570      trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits
571    )
572  )
573
574  debugIntrEnable := MuxCase(
575    debugIntrEnable,
576    Seq(
577      dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits,
578      trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits
579    )
580  )
581
582  // perf
583  val addrInPerfCnt = (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) ||
584    (addr >= mcountinhibit.addr.U) && (addr <= mhpmevents.last.addr.U) ||
585    (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) ||
586    (addr === CSRs.mip.U) ||
587    (addr === CSRs.hip.U) ||
588    Cat(aiaCSRMap.keys.toSeq.sorted.map(_.U === addr)).orR ||
589    (addr === CSRs.stimecmp.U) ||
590    (addr === CSRs.mcounteren.U) ||
591    (addr === CSRs.scounteren.U) ||
592    (addr === CSRs.menvcfg.U)
593  // Todo: may be vsip and sip
594
595  // flush
596  val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed
597
598  val wFcsrChangeRM = addr === fcsr.addr.U && wenLegal && wdata(7, 5) =/= fcsr.frm
599  val wFrmChangeRM  = addr === CSRs.frm.U  && wenLegal && wdata(2, 0) =/= fcsr.frm
600  val frmChange = wFcsrChangeRM || wFrmChangeRM
601
602  val wVcsrChangeRM = addr === CSRs.vcsr.U && wenLegal && wdata(2, 1) =/= vcsr.vxrm
603  val wVxrmChangeRM = addr === CSRs.vxrm.U && wenLegal && wdata(1, 0) =/= vcsr.vxrm
604  val vxrmChange = wVcsrChangeRM || wVxrmChangeRM
605
606  val triggerFrontendChange = Wire(Bool())
607  val flushPipe = resetSatp || frmChange || vxrmChange || triggerFrontendChange
608
609  // fence
610  val tvm = mstatus.regOut.TVM.asBool
611  val vtvm = hstatus.regOut.VTVM.asBool
612
613  private val rdata = Mux1H(csrRwMap.map { case (id, (_, rBundle)) =>
614    (raddr === id.U) -> rBundle.asUInt
615  })
616
617  private val regOut = Mux1H(csrOutMap.map { case (id, regOut) =>
618    (raddr === id.U) -> regOut
619  })
620
621  private val needTargetUpdate = mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid ||
622    trapEntryMEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid
623
624  private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR
625
626  io.out.EX_II := permitMod.io.out.EX_II || noCSRIllegal
627  io.out.EX_VI := permitMod.io.out.EX_VI
628  io.out.flushPipe := flushPipe
629
630  io.out.rData := Mux(ren, rdata, 0.U)
631  io.out.regOut := regOut
632  io.out.targetPc := DataHoldBypass(
633    Mux(trapEntryDEvent.out.targetPc.valid,
634      trapEntryDEvent.out.targetPc.bits,
635      Mux1H(Seq(
636        mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits,
637        sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits,
638        dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits,
639        trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits,
640        trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits,
641        trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits)
642      )
643    ),
644  needTargetUpdate)
645
646  io.out.privState := privState
647
648  io.out.fpState.frm := fcsr.frm
649  io.out.fpState.off := mstatus.regOut.FS === ContextStatus.Off
650  io.out.vecState.vstart := vstart.rdata.asUInt
651  io.out.vecState.vxsat := vcsr.vxsat
652  io.out.vecState.vxrm := vcsr.vxrm
653  io.out.vecState.vcsr := vcsr.rdata.asUInt
654  io.out.vecState.vl := vl.rdata.asUInt
655  io.out.vecState.vtype := vtype.rdata.asUInt // Todo: check correct
656  io.out.vecState.vlenb := vlenb.rdata.asUInt
657  io.out.vecState.off := mstatus.regOut.VS === ContextStatus.Off
658  io.out.isPerfCnt := addrInPerfCnt
659  io.out.interrupt := intrMod.io.out.interruptVec.valid
660  io.out.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR
661  io.out.debugMode := debugMode
662  io.out.singleStepFlag := !debugMode && dcsr.regOut.STEP
663  io.out.tvm := tvm
664  io.out.vtvm := vtvm
665
666  /**
667   * debug_begin
668   */
669  // debug_intr
670  val hasIntr = hasTrap && trapIsInterrupt
671  val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG)
672
673  // debug_exception_ebreak
674  val hasExp = hasTrap && !trapIsInterrupt
675  val breakPoint = trapVec(ExceptionNO.breakPoint).asBool
676  val hasBreakPoint = hasExp && breakPoint
677  val ebreakEnterDebugMode =
678    (privState.isModeM && dcsr.regOut.EBREAKM.asBool) ||
679      (privState.isModeHS && dcsr.regOut.EBREAKS.asBool) ||
680      (privState.isModeHU && dcsr.regOut.EBREAKU.asBool)
681  val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode
682
683  // debug_exception_trigger
684  val triggerFrontendHitVec = triggerCf.frontendHit
685  val triggerMemHitVec = triggerCf.backendHit
686  val triggerHitVec = triggerFrontendHitVec.asUInt | triggerMemHitVec.asUInt // Todo: update mcontrol.hit
687  val triggerFrontendCanFireVec = triggerCf.frontendCanFire.asUInt
688  val triggerMemCanFireVec = triggerCf.backendCanFire.asUInt
689  val triggerCanFireVec = triggerFrontendCanFireVec | triggerMemCanFireVec
690  val tdata1WireVec = tdata1RegVec.map{ mod => {
691      val tdata1Wire = Wire(new Tdata1Bundle)
692      tdata1Wire := mod.rdata
693      tdata1Wire
694  }}
695  val tdata2WireVec = tdata2RegVec.map{ mod => {
696      val tdata2Wire = Wire(new Tdata2Bundle)
697      tdata2Wire := mod.rdata
698      tdata2Wire
699  }}
700  val mcontrolWireVec = tdata1WireVec.map{ mod => {
701    val mcontrolWire = Wire(new Mcontrol)
702    mcontrolWire := mod.DATA.asUInt
703    mcontrolWire
704  }}
705
706  // More than one triggers can hit at the same time, but only fire one
707  // We select the first hit trigger to fire
708  val triggerFireOH = PriorityEncoderOH(triggerCanFireVec)
709  val triggerFireAction = PriorityMux(triggerFireOH, tdata1WireVec.map(_.getTriggerAction)).asUInt
710  val hasTriggerFire = hasExp && triggerCf.canFire
711  val hasDebugTriggerException = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt)
712
713  // debug_exception_single
714  val hasSingleStep = hasExp && io.fromRob.trap.bits.singleStep
715
716  val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep
717  val hasDebugTrap = hasDebugException || hasDebugIntr
718
719  trapEntryDEvent.valid                       := hasDebugTrap && !debugMode
720  trapEntryDEvent.in.hasDebugIntr             := hasDebugIntr
721  trapEntryDEvent.in.debugMode                := debugMode
722  trapEntryDEvent.in.hasTrap                  := hasTrap
723  trapEntryDEvent.in.hasSingleStep            := hasSingleStep
724  trapEntryDEvent.in.hasTriggerFire           := hasTriggerFire
725  trapEntryDEvent.in.hasDebugEbreakException  := hasDebugEbreakException
726  trapEntryDEvent.in.breakPoint               := breakPoint
727
728  trapHandleMod.io.in.trapInfo.bits.singleStep  := hasSingleStep
729  trapHandleMod.io.in.trapInfo.bits.triggerFire := hasTriggerFire
730
731  intrMod.io.in.debugMode := debugMode
732  intrMod.io.in.debugIntr := debugIntr
733  intrMod.io.in.dcsr      := dcsr.rdata.asUInt
734
735  val tselect1H = UIntToOH(tselect.rdata.asUInt, TriggerNum).asBools
736  val chainVec = mcontrolWireVec.map(_.CHAIN.asBool)
737  val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b}
738  val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength)
739
740  val tdata1Update  = addr === tdata1.addr.U && wenLegal
741  val tdata2Update  = addr === tdata2.addr.U && wenLegal
742  val triggerUpdate = tdata1Update || tdata2Update
743
744  tdata1RegVec.foreach { mod =>
745    mod match {
746      case m: HasdebugModeBundle =>
747        m.debugMode := debugMode
748        m.chainable := newTriggerChainIsLegal
749      case _ =>
750    }
751  }
752  tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
753      mod1.w.wen    := tdata1Update && (tselect.rdata === idx.U)
754      mod1.w.wdata  := wdata
755      mod2.w.wen    := tdata2Update && (tselect.rdata === idx.U)
756      mod2.w.wdata  := wdata
757    }
758  }
759
760  val tdata1Wdata = Wire(new Tdata1Bundle)
761  tdata1Wdata := wdata
762  val mcontrolWdata = Wire(new Mcontrol)
763  mcontrolWdata := tdata1Wdata.DATA.asUInt
764  val tdata1TypeWdata = tdata1Wdata.TYPE
765
766  val tdata1Selected = Wire(new Tdata1Bundle)
767  tdata1Selected := tdata1.rdata.asUInt
768  val mcontrolSelected = Wire(new Mcontrol)
769  mcontrolSelected := tdata1Selected.DATA.asUInt
770  val tdata2Selected = Wire(new Tdata2Bundle)
771  tdata2Selected := tdata2.rdata.asUInt
772
773  val frontendTriggerUpdate =
774    tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isFetchTrigger ||
775      mcontrolSelected.isFetchTrigger && triggerUpdate
776
777  val memTriggerUpdate =
778    tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isMemAccTrigger ||
779      mcontrolSelected.isMemAccTrigger && triggerUpdate
780
781  val triggerEnableVec = tdata1WireVec.zip(mcontrolWireVec).map { case(tdata1, mcontrol) =>
782    tdata1.TYPE.isLegal && (
783      mcontrol.M && privState.isModeM ||
784        mcontrol.S && (privState.isModeHS) ||
785        mcontrol.U && privState.isModeHU)
786  }
787
788  val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map {
789    case (tEnable, mod) => tEnable && mod.isFetchTrigger
790  }
791  val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map {
792    case (tEnable, mod) => tEnable && mod.isMemAccTrigger
793  }
794
795  triggerFrontendChange := frontendTriggerUpdate
796
797  io.out.frontendTrigger.tUpdate.valid       := RegNext(RegNext(frontendTriggerUpdate))
798  io.out.frontendTrigger.tUpdate.bits.addr   := tselect.rdata.asUInt
799  io.out.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected)
800  io.out.frontendTrigger.tEnableVec          := fetchTriggerEnableVec
801  io.out.memTrigger.tUpdate.valid            := RegNext(RegNext(memTriggerUpdate))
802  io.out.memTrigger.tUpdate.bits.addr        := tselect.rdata.asUInt
803  io.out.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected)
804  io.out.memTrigger.tEnableVec               := memAccTriggerEnableVec
805  /**
806   * debug_end
807   */
808
809  /**
810   * [[io.out.custom]] connection
811   */
812  io.out.custom.l1I_pf_enable           := spfctl.regOut.L1I_PF_ENABLE.asBool
813  io.out.custom.l2_pf_enable            := spfctl.regOut.L2_PF_ENABLE.asBool
814  io.out.custom.l1D_pf_enable           := spfctl.regOut.L1D_PF_ENABLE.asBool
815  io.out.custom.l1D_pf_train_on_hit     := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool
816  io.out.custom.l1D_pf_enable_agt       := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool
817  io.out.custom.l1D_pf_enable_pht       := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool
818  io.out.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt
819  io.out.custom.l1D_pf_active_stride    := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt
820  io.out.custom.l1D_pf_enable_stride    := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool
821  io.out.custom.l2_pf_store_only        := spfctl.regOut.L2_PF_STORE_ONLY.asBool
822
823  io.out.custom.icache_parity_enable    := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool
824
825  io.out.custom.lvpred_disable          := slvpredctl.regOut.LVPRED_DISABLE.asBool
826  io.out.custom.no_spec_load            := slvpredctl.regOut.NO_SPEC_LOAD.asBool
827  io.out.custom.storeset_wait_store     := slvpredctl.regOut.STORESET_WAIT_STORE.asBool
828  io.out.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool
829  io.out.custom.lvpred_timeout          := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt
830
831  io.out.custom.bp_ctrl.ubtb_enable     := sbpctl.regOut.UBTB_ENABLE .asBool
832  io.out.custom.bp_ctrl.btb_enable      := sbpctl.regOut.BTB_ENABLE  .asBool
833  io.out.custom.bp_ctrl.bim_enable      := sbpctl.regOut.BIM_ENABLE  .asBool
834  io.out.custom.bp_ctrl.tage_enable     := sbpctl.regOut.TAGE_ENABLE .asBool
835  io.out.custom.bp_ctrl.sc_enable       := sbpctl.regOut.SC_ENABLE   .asBool
836  io.out.custom.bp_ctrl.ras_enable      := sbpctl.regOut.RAS_ENABLE  .asBool
837  io.out.custom.bp_ctrl.loop_enable     := sbpctl.regOut.LOOP_ENABLE .asBool
838
839  io.out.custom.sbuffer_threshold                := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt
840  io.out.custom.ldld_vio_check_enable            := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool
841  io.out.custom.soft_prefetch_enable             := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool
842  io.out.custom.cache_error_enable               := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool
843  io.out.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
844
845  io.out.custom.fusion_enable           := srnctl.regOut.FUSION_ENABLE.asBool
846  io.out.custom.wfi_enable              := srnctl.regOut.WFI_ENABLE.asBool
847
848  // Todo: record the last address to avoid xireg is different with xiselect
849  toAIA.addr.valid := wenLegal && Seq(miselect, siselect, vsiselect).map(
850    _.addr.U === addr
851  ).reduce(_ || _)
852  toAIA.addr.bits.addr := addr
853  toAIA.addr.bits.prvm := PRVM
854  toAIA.addr.bits.v := V
855  toAIA.vgein := hstatus.regOut.VGEIN.asUInt
856  toAIA.wdata.valid := wenLegal && Seq(mireg, sireg, vsireg).map(
857    _.addr.U === addr
858  ).reduce(_ || _)
859  toAIA.wdata.bits.data := wdata
860  toAIA.mClaim := wenLegal && mtopei.addr.U === addr
861  toAIA.sClaim := wenLegal && stopei.addr.U === addr
862  toAIA.vsClaim := wenLegal && vstopei.addr.U === addr
863
864  // tlb
865  io.tlb.satpASIDChanged  := wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/= wdata.asTypeOf(new SatpBundle).ASID
866  io.tlb.vsatpASIDChanged := wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= wdata.asTypeOf(new SatpBundle).ASID
867  io.tlb.hgatpVMIDChanged := wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= wdata.asTypeOf(new HgatpBundle).VMID
868  io.tlb.satp := satp.rdata
869  io.tlb.vsatp := vsatp.rdata
870  io.tlb.hgatp := hgatp.rdata
871  io.tlb.mxr  :=  mstatus.regOut.MXR.asBool
872  io.tlb.sum  :=  mstatus.regOut.SUM.asBool
873  io.tlb.vmxr := vsstatus.regOut.MXR.asBool
874  io.tlb.vsum := vsstatus.regOut.SUM.asBool
875  io.tlb.spvp :=  hstatus.regOut.SPVP.asBool
876
877  io.tlb.imode := PRVM.asUInt
878  io.tlb.dmode := Mux((debugMode && dcsr.regOut.MPRVEN.asBool || !debugMode) && mstatus.regOut.MPRV.asBool, mstatus.regOut.MPP.asUInt, PRVM.asUInt)
879
880  io.toDecode.illegalInst.sfenceVMA  := isModeHS && mstatus.regOut.TVM  || isModeHU
881  io.toDecode.virtualInst.sfenceVMA  := isModeVS && hstatus.regOut.VTVM || isModeVU
882  io.toDecode.illegalInst.sfencePart := isModeHU
883  io.toDecode.virtualInst.sfencePart := isModeVU
884  io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU
885  io.toDecode.illegalInst.hfenceVVMA := isModeHU
886  io.toDecode.virtualInst.hfence     := isModeVS || isModeVU
887  io.toDecode.illegalInst.hlsv       := isModeHU && hstatus.regOut.HU
888  io.toDecode.virtualInst.hlsv       := isModeVS || isModeVU
889
890  // Always instantiate basic difftest modules.
891  if (env.AlwaysBasicDiff || env.EnableDifftest) {
892    val hartId = io.fromTop.hartId
893    val trapValid = io.fromRob.trap.valid
894    val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt
895    val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool
896    val interruptNO = Mux(interrupt, trapNO, 0.U)
897    val exceptionNO = Mux(!interrupt, trapNO, 0.U)
898    val ivmHS = isModeHS &&  satp.regOut.MODE =/= SatpMode.Bare
899    val ivmVS = isModeVS && vsatp.regOut.MODE =/= SatpMode.Bare
900    // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
901    val exceptionPC = Mux(ivmHS || ivmVS, SignExt(trapPC, XLEN), ZeroExt(trapPC, XLEN))
902
903    val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true)
904    diffArchEvent.coreid := hartId
905    diffArchEvent.valid := trapValid
906    diffArchEvent.interrupt := interruptNO
907    diffArchEvent.exception := exceptionNO
908    diffArchEvent.exceptionPC := exceptionPC
909    if (env.EnableDifftest) {
910      diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr
911    }
912
913    val diffCSRState = DifftestModule(new DiffCSRState)
914    diffCSRState.coreid         := hartId
915    diffCSRState.privilegeMode  := privState.PRVM.asUInt
916    diffCSRState.mstatus        := mstatus.rdata.asUInt
917    diffCSRState.sstatus        := mstatus.sstatus.asUInt
918    diffCSRState.mepc           := mepc.rdata.asUInt
919    diffCSRState.sepc           := sepc.rdata.asUInt
920    diffCSRState.mtval          := mtval.rdata.asUInt
921    diffCSRState.stval          := stval.rdata.asUInt
922    diffCSRState.mtvec          := mtvec.rdata.asUInt
923    diffCSRState.stvec          := stvec.rdata.asUInt
924    diffCSRState.mcause         := mcause.rdata.asUInt
925    diffCSRState.scause         := scause.rdata.asUInt
926    diffCSRState.satp           := satp.rdata.asUInt
927    diffCSRState.mip            := mip.regOut.asUInt
928    diffCSRState.mie            := mie.rdata.asUInt
929    diffCSRState.mscratch       := mscratch.rdata.asUInt
930    diffCSRState.sscratch       := sscratch.rdata.asUInt
931    diffCSRState.mideleg        := mideleg.rdata.asUInt
932    diffCSRState.medeleg        := medeleg.rdata.asUInt
933
934    val diffDebugMode = DifftestModule(new DiffDebugMode)
935    diffDebugMode.coreid    := hartId
936    diffDebugMode.debugMode := debugMode
937    diffDebugMode.dcsr      := dcsr.rdata.asUInt
938    diffDebugMode.dpc       := dpc.rdata.asUInt
939    diffDebugMode.dscratch0 := dscratch0.rdata.asUInt
940    diffDebugMode.dscratch1 := dscratch1.rdata.asUInt
941
942    val diffVecCSRState = DifftestModule(new DiffVecCSRState)
943    diffVecCSRState.coreid := hartId
944    diffVecCSRState.vstart := vstart.rdata.asUInt
945    diffVecCSRState.vxsat := vcsr.vxsat.asUInt
946    diffVecCSRState.vxrm := vcsr.vxrm.asUInt
947    diffVecCSRState.vcsr := vcsr.rdata.asUInt
948    diffVecCSRState.vl := vl.rdata.asUInt
949    diffVecCSRState.vtype := vtype.rdata.asUInt
950    diffVecCSRState.vlenb := vlenb.rdata.asUInt
951
952    val diffHCSRState = DifftestModule(new DiffHCSRState)
953    diffHCSRState.coreid      := hartId
954    diffHCSRState.virtMode    := privState.V.asBool
955    diffHCSRState.mtval2      := mtval2.rdata.asUInt
956    diffHCSRState.mtinst      := mtinst.rdata.asUInt
957    diffHCSRState.hstatus     := hstatus.rdata.asUInt
958    diffHCSRState.hideleg     := hideleg.rdata.asUInt
959    diffHCSRState.hedeleg     := hedeleg.rdata.asUInt
960    diffHCSRState.hcounteren  := hcounteren.rdata.asUInt
961    diffHCSRState.htval       := htval.rdata.asUInt
962    diffHCSRState.htinst      := htinst.rdata.asUInt
963    diffHCSRState.hgatp       := hgatp.rdata.asUInt
964    diffHCSRState.vsstatus    := vsstatus.rdata.asUInt
965    diffHCSRState.vstvec      := vstvec.rdata.asUInt
966    diffHCSRState.vsepc       := vsepc.rdata.asUInt
967    diffHCSRState.vscause     := vscause.rdata.asUInt
968    diffHCSRState.vstval      := vstval.rdata.asUInt
969    diffHCSRState.vsatp       := vsatp.rdata.asUInt
970    diffHCSRState.vsscratch   := vsscratch.rdata.asUInt
971
972  }
973}
974
975trait SupervisorMachineAliasConnect { self: NewCSR with MachineLevel with SupervisorLevel =>
976  mip.fromMvip := mvip.toMip
977  mip.fromSip := sip.toMip
978  mie.fromSie := sie.toMie
979}
980
981object NewCSRMain extends App {
982  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
983    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
984
985  val defaultConfig = config.alterPartial({
986    // Get XSCoreParams and pass it to the "small module"
987    case XSCoreParamsKey => config(XSTileKey).head
988  })
989
990  Generator.execute(
991    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
992    new NewCSR()(defaultConfig),
993    firtoolOpts
994  )
995
996  println("done")
997}