xref: /XiangShan/src/main/scala/xiangshan/XSCore.scala (revision 00210c34f22e07539e32a7bc422e175b81cc67cf)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package xiangshan
18
19import chipsalliance.rocketchip.config
20import chipsalliance.rocketchip.config.Parameters
21import chisel3._
22import chisel3.util._
23import freechips.rocketchip.diplomacy.{BundleBridgeSource, LazyModule, LazyModuleImp}
24import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
25import freechips.rocketchip.tile.HasFPUParameters
26import freechips.rocketchip.tilelink.TLBuffer
27import system.HasSoCParameter
28import utils._
29import xiangshan.backend._
30import xiangshan.backend.exu.{ExuConfig, Wb2Ctrl, WbArbiterWrapper}
31import xiangshan.cache.mmu._
32import xiangshan.frontend._
33
34import scala.collection.mutable.ListBuffer
35
36abstract class XSModule(implicit val p: Parameters) extends MultiIOModule
37  with HasXSParameter
38  with HasFPUParameters {
39  def io: Record
40}
41
42//remove this trait after impl module logic
43trait NeedImpl {
44  this: RawModule =>
45  override protected def IO[T <: Data](iodef: T): T = {
46    println(s"[Warn]: (${this.name}) please reomve 'NeedImpl' after implement this module")
47    val io = chisel3.experimental.IO(iodef)
48    io <> DontCare
49    io
50  }
51}
52
53class WritebackSourceParams(
54  var exuConfigs: Seq[Seq[ExuConfig]] = Seq()
55 ) {
56  def length: Int = exuConfigs.length
57  def ++(that: WritebackSourceParams): WritebackSourceParams = {
58    new WritebackSourceParams(exuConfigs ++ that.exuConfigs)
59  }
60}
61
62trait HasWritebackSource {
63  val writebackSourceParams: Seq[WritebackSourceParams]
64  final def writebackSource(sourceMod: HasWritebackSourceImp): Seq[Seq[Valid[ExuOutput]]] = {
65    require(sourceMod.writebackSource.isDefined, "should not use Valid[ExuOutput]")
66    val source = sourceMod.writebackSource.get
67    require(source.length == writebackSourceParams.length, "length mismatch between sources")
68    for ((s, p) <- source.zip(writebackSourceParams)) {
69      require(s.length == p.length, "params do not match with the exuOutput")
70    }
71    source
72  }
73  final def writebackSource1(sourceMod: HasWritebackSourceImp): Seq[Seq[DecoupledIO[ExuOutput]]] = {
74    require(sourceMod.writebackSource1.isDefined, "should not use DecoupledIO[ExuOutput]")
75    val source = sourceMod.writebackSource1.get
76    require(source.length == writebackSourceParams.length, "length mismatch between sources")
77    for ((s, p) <- source.zip(writebackSourceParams)) {
78      require(s.length == p.length, "params do not match with the exuOutput")
79    }
80    source
81  }
82  val writebackSourceImp: HasWritebackSourceImp
83}
84
85trait HasWritebackSourceImp {
86  def writebackSource: Option[Seq[Seq[Valid[ExuOutput]]]] = None
87  def writebackSource1: Option[Seq[Seq[DecoupledIO[ExuOutput]]]] = None
88}
89
90trait HasWritebackSink {
91  // Caches all sources. The selected source will be the one with smallest length.
92  var writebackSinks = ListBuffer.empty[(Seq[HasWritebackSource], Seq[Int])]
93  def addWritebackSink(source: Seq[HasWritebackSource], index: Option[Seq[Int]] = None): HasWritebackSink = {
94    val realIndex = if (index.isDefined) index.get else Seq.fill(source.length)(0)
95    writebackSinks += ((source, realIndex))
96    this
97  }
98
99  def writebackSinksParams: Seq[WritebackSourceParams] = {
100    writebackSinks.map{ case (s, i) => s.zip(i).map(x => x._1.writebackSourceParams(x._2)).reduce(_ ++ _) }
101  }
102  final def writebackSinksMod(
103     thisMod: Option[HasWritebackSource] = None,
104     thisModImp: Option[HasWritebackSourceImp] = None
105   ): Seq[Seq[HasWritebackSourceImp]] = {
106    require(thisMod.isDefined == thisModImp.isDefined)
107    writebackSinks.map(_._1.map(source =>
108      if (thisMod.isDefined && source == thisMod.get) thisModImp.get else source.writebackSourceImp)
109    )
110  }
111  final def writebackSinksImp(
112    thisMod: Option[HasWritebackSource] = None,
113    thisModImp: Option[HasWritebackSourceImp] = None
114  ): Seq[Seq[ValidIO[ExuOutput]]] = {
115    val sourceMod = writebackSinksMod(thisMod, thisModImp)
116    writebackSinks.zip(sourceMod).map{ case ((s, i), m) =>
117      s.zip(i).zip(m).flatMap(x => x._1._1.writebackSource(x._2)(x._1._2))
118    }
119  }
120  def selWritebackSinks(func: WritebackSourceParams => Int): Int = {
121    writebackSinksParams.zipWithIndex.minBy(params => func(params._1))._2
122  }
123  def generateWritebackIO(
124    thisMod: Option[HasWritebackSource] = None,
125    thisModImp: Option[HasWritebackSourceImp] = None
126   ): Unit
127}
128
129abstract class XSBundle(implicit val p: Parameters) extends Bundle
130  with HasXSParameter
131
132abstract class XSCoreBase()(implicit p: config.Parameters) extends LazyModule
133  with HasXSParameter with HasExuWbHelper
134{
135  // interrupt sinks
136  val clint_int_sink = IntSinkNode(IntSinkPortSimple(1, 2))
137  val debug_int_sink = IntSinkNode(IntSinkPortSimple(1, 1))
138  val plic_int_sink = IntSinkNode(IntSinkPortSimple(2, 1))
139  // outer facing nodes
140  val frontend = LazyModule(new Frontend())
141  val ptw = LazyModule(new L2TLBWrapper())
142  val ptw_to_l2_buffer = LazyModule(new TLBuffer)
143  val csrOut = BundleBridgeSource(Some(() => new DistributedCSRIO()))
144
145  ptw_to_l2_buffer.node := ptw.node
146
147  val wbArbiter = LazyModule(new WbArbiterWrapper(exuConfigs, NRIntWritePorts, NRFpWritePorts))
148  val intWbPorts = wbArbiter.intWbPorts
149  val fpWbPorts = wbArbiter.fpWbPorts
150
151  // TODO: better RS organization
152  // generate rs according to number of function units
153  require(exuParameters.JmpCnt == 1)
154  require(exuParameters.MduCnt <= exuParameters.AluCnt && exuParameters.MduCnt > 0)
155  require(exuParameters.FmiscCnt <= exuParameters.FmacCnt && exuParameters.FmiscCnt > 0)
156  require(exuParameters.LduCnt == exuParameters.StuCnt) // TODO: remove this limitation
157
158  // one RS every 2 MDUs
159  val schedulePorts = Seq(
160    // exuCfg, numDeq, intFastWakeupTarget, fpFastWakeupTarget
161    Seq(
162      (AluExeUnitCfg, exuParameters.AluCnt, Seq(AluExeUnitCfg, MulDivExeUnitCfg, JumpCSRExeUnitCfg, LdExeUnitCfg, StaExeUnitCfg), Seq()),
163      (MulDivExeUnitCfg, exuParameters.MduCnt, Seq(AluExeUnitCfg, MulDivExeUnitCfg), Seq()),
164      (JumpCSRExeUnitCfg, 1, Seq(), Seq()),
165      (LdExeUnitCfg, exuParameters.LduCnt, Seq(AluExeUnitCfg, LdExeUnitCfg), Seq()),
166      (StaExeUnitCfg, exuParameters.StuCnt, Seq(), Seq()),
167      (StdExeUnitCfg, exuParameters.StuCnt, Seq(), Seq())
168    ),
169    Seq(
170      (FmacExeUnitCfg, exuParameters.FmacCnt, Seq(), Seq(FmacExeUnitCfg, FmiscExeUnitCfg)),
171      (FmiscExeUnitCfg, exuParameters.FmiscCnt, Seq(), Seq())
172    )
173  )
174
175  // should do outer fast wakeup ports here
176  val otherFastPorts = schedulePorts.zipWithIndex.map { case (sche, i) =>
177    val otherCfg = schedulePorts.zipWithIndex.filter(_._2 != i).map(_._1).reduce(_ ++ _)
178    val outerPorts = sche.map(cfg => {
179      // exe units from this scheduler need fastUops from exeunits
180      val outerWakeupInSche = sche.filter(_._1.wakeupFromExu)
181      val intraIntScheOuter = outerWakeupInSche.filter(_._3.contains(cfg._1)).map(_._1)
182      val intraFpScheOuter = outerWakeupInSche.filter(_._4.contains(cfg._1)).map(_._1)
183      // exe units from other schedulers need fastUop from outside
184      val otherIntSource = otherCfg.filter(_._3.contains(cfg._1)).map(_._1)
185      val otherFpSource = otherCfg.filter(_._4.contains(cfg._1)).map(_._1)
186      val intSource = findInWbPorts(intWbPorts, intraIntScheOuter ++ otherIntSource)
187      val fpSource = findInWbPorts(fpWbPorts, intraFpScheOuter ++ otherFpSource)
188      getFastWakeupIndex(cfg._1, intSource, fpSource, intWbPorts.length).sorted
189    })
190    println(s"inter-scheduler wakeup sources for $i: $outerPorts")
191    outerPorts
192  }
193
194  // allow mdu and fmisc to have 2*numDeq enqueue ports
195  val intDpPorts = (0 until exuParameters.AluCnt).map(i => {
196    if (i < exuParameters.JmpCnt) Seq((0, i), (1, i), (2, i))
197    else if (i < 2 * exuParameters.MduCnt) Seq((0, i), (1, i))
198    else Seq((0, i))
199  })
200  val lsDpPorts = (0 until exuParameters.LduCnt).map(i => Seq((3, i))) ++
201                  (0 until exuParameters.StuCnt).map(i => Seq((4, i))) ++
202                  (0 until exuParameters.StuCnt).map(i => Seq((5, i)))
203  val fpDpPorts = (0 until exuParameters.FmacCnt).map(i => {
204    if (i < 2 * exuParameters.FmiscCnt) Seq((0, i), (1, i))
205    else Seq((0, i))
206  })
207
208  val dispatchPorts = Seq(intDpPorts ++ lsDpPorts, fpDpPorts)
209
210  val outIntRfReadPorts = Seq(0, 0)
211  val outFpRfReadPorts = Seq(0, StorePipelineWidth)
212  val hasIntRf = Seq(true, false)
213  val hasFpRf = Seq(false, true)
214  val exuBlocks = schedulePorts.zip(dispatchPorts).zip(otherFastPorts).zipWithIndex.map {
215    case (((sche, disp), other), i) =>
216      LazyModule(new ExuBlock(sche, disp, intWbPorts, fpWbPorts, other, outIntRfReadPorts(i), outFpRfReadPorts(i), hasIntRf(i), hasFpRf(i)))
217  }
218
219  val memBlock = LazyModule(new MemBlock()(p.alter((site, here, up) => {
220    case XSCoreParamsKey => up(XSCoreParamsKey).copy(
221      IssQueSize = exuBlocks.head.scheduler.getMemRsEntries
222    )
223  })))
224
225  val wb2Ctrl = LazyModule(new Wb2Ctrl(exuConfigs))
226  wb2Ctrl.addWritebackSink(exuBlocks :+ memBlock)
227  val ctrlBlock = LazyModule(new CtrlBlock)
228  val writebackSources = Seq(Seq(wb2Ctrl), Seq(wbArbiter))
229  writebackSources.foreach(s => ctrlBlock.addWritebackSink(s))
230}
231
232class XSCore()(implicit p: config.Parameters) extends XSCoreBase
233  with HasXSDts
234{
235  lazy val module = new XSCoreImp(this)
236}
237
238class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
239  with HasXSParameter
240  with HasSoCParameter {
241  val io = IO(new Bundle {
242    val hartId = Input(UInt(64.W))
243    val reset_vector = Input(UInt(PAddrBits.W))
244    val cpu_halt = Output(Bool())
245    val l2_pf_enable = Output(Bool())
246    val perfEvents = Input(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
247    val beu_errors = Output(new XSL1BusErrors())
248  })
249
250  println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}")
251
252  val frontend = outer.frontend.module
253  val ctrlBlock = outer.ctrlBlock.module
254  val wb2Ctrl = outer.wb2Ctrl.module
255  val memBlock = outer.memBlock.module
256  val ptw = outer.ptw.module
257  val ptw_to_l2_buffer = outer.ptw_to_l2_buffer.module
258  val exuBlocks = outer.exuBlocks.map(_.module)
259
260  frontend.io.hartId  := io.hartId
261  ctrlBlock.io.hartId := io.hartId
262  exuBlocks.foreach(_.io.hartId := io.hartId)
263  memBlock.io.hartId := io.hartId
264  outer.wbArbiter.module.io.hartId := io.hartId
265  frontend.io.reset_vector := io.reset_vector
266
267  io.cpu_halt := ctrlBlock.io.cpu_halt
268
269  outer.wbArbiter.module.io.redirect <> ctrlBlock.io.redirect
270  val allWriteback = exuBlocks.flatMap(_.io.fuWriteback) ++ memBlock.io.writeback
271  require(exuConfigs.length == allWriteback.length, s"${exuConfigs.length} != ${allWriteback.length}")
272  outer.wbArbiter.module.io.in <> allWriteback
273  val rfWriteback = outer.wbArbiter.module.io.out
274
275  // memblock error exception writeback, 1 cycle after normal writeback
276  wb2Ctrl.io.delayedLoadError <> memBlock.io.delayedLoadError
277
278  wb2Ctrl.io.redirect <> ctrlBlock.io.redirect
279  outer.wb2Ctrl.generateWritebackIO()
280
281  io.beu_errors.icache <> frontend.io.error.toL1BusErrorUnitInfo()
282  io.beu_errors.dcache <> memBlock.io.error.toL1BusErrorUnitInfo()
283
284  require(exuBlocks.count(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)) == 1)
285  val csrFenceMod = exuBlocks.filter(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)).head
286  val csrioIn = csrFenceMod.io.fuExtra.csrio.get
287  val fenceio = csrFenceMod.io.fuExtra.fenceio.get
288
289  frontend.io.backend <> ctrlBlock.io.frontend
290  frontend.io.sfence <> fenceio.sfence
291  frontend.io.tlbCsr <> csrioIn.tlb
292  frontend.io.csrCtrl <> csrioIn.customCtrl
293  frontend.io.fencei := fenceio.fencei
294
295  ctrlBlock.io.csrCtrl <> csrioIn.customCtrl
296  val redirectBlocks = exuBlocks.reverse.filter(_.fuConfigs.map(_._1).map(_.hasRedirect).reduce(_ || _))
297  ctrlBlock.io.exuRedirect <> redirectBlocks.flatMap(_.io.fuExtra.exuRedirect)
298  ctrlBlock.io.stIn <> memBlock.io.stIn
299  ctrlBlock.io.memoryViolation <> memBlock.io.memoryViolation
300  exuBlocks.head.io.scheExtra.enqLsq.get <> memBlock.io.enqLsq
301  exuBlocks.foreach(b => {
302    b.io.scheExtra.lcommit := ctrlBlock.io.robio.lsq.lcommit
303    b.io.scheExtra.scommit := memBlock.io.sqDeq
304    b.io.scheExtra.lqCancelCnt := memBlock.io.lqCancelCnt
305    b.io.scheExtra.sqCancelCnt := memBlock.io.sqCancelCnt
306  })
307  val sourceModules = outer.writebackSources.map(_.map(_.module.asInstanceOf[HasWritebackSourceImp]))
308  outer.ctrlBlock.generateWritebackIO()
309
310  val allFastUop = exuBlocks.flatMap(b => b.io.fastUopOut.dropRight(b.numOutFu)) ++ memBlock.io.otherFastWakeup
311  require(allFastUop.length == exuConfigs.length, s"${allFastUop.length} != ${exuConfigs.length}")
312  val intFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeIntRf).map(_._1)
313  val fpFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeFpRf).map(_._1)
314  val intFastUop1 = outer.wbArbiter.intConnections.map(c => intFastUop(c.head))
315  val fpFastUop1 = outer.wbArbiter.fpConnections.map(c => fpFastUop(c.head))
316  val allFastUop1 = intFastUop1 ++ fpFastUop1
317
318  ctrlBlock.io.dispatch <> exuBlocks.flatMap(_.io.in)
319
320  exuBlocks(0).io.scheExtra.fpRfReadIn.get <> exuBlocks(1).io.scheExtra.fpRfReadOut.get
321  exuBlocks(0).io.scheExtra.fpStateReadIn.get <> exuBlocks(1).io.scheExtra.fpStateReadOut.get
322
323  memBlock.io.issue <> exuBlocks(0).io.issue.get
324  // By default, instructions do not have exceptions when they enter the function units.
325  memBlock.io.issue.map(_.bits.uop.clearExceptions())
326  exuBlocks(0).io.scheExtra.loadFastMatch.get <> memBlock.io.loadFastMatch
327
328  val stdIssue = exuBlocks(0).io.issue.get.takeRight(exuParameters.StuCnt)
329  exuBlocks.map(_.io).foreach { exu =>
330    exu.redirect <> ctrlBlock.io.redirect
331    exu.allocPregs <> ctrlBlock.io.allocPregs
332    exu.rfWriteback <> rfWriteback
333    exu.fastUopIn <> allFastUop1
334    exu.scheExtra.jumpPc <> ctrlBlock.io.jumpPc
335    exu.scheExtra.jalr_target <> ctrlBlock.io.jalr_target
336    exu.scheExtra.stIssuePtr <> memBlock.io.stIssuePtr
337    exu.scheExtra.debug_fp_rat <> ctrlBlock.io.debug_fp_rat
338    exu.scheExtra.debug_int_rat <> ctrlBlock.io.debug_int_rat
339    exu.scheExtra.memWaitUpdateReq.staIssue.zip(memBlock.io.stIn).foreach{case (sink, src) => {
340      sink.bits := src.bits
341      sink.valid := src.valid
342    }}
343    exu.scheExtra.memWaitUpdateReq.stdIssue.zip(stdIssue).foreach{case (sink, src) => {
344      sink.valid := src.valid
345      sink.bits := src.bits
346    }}
347  }
348  XSPerfHistogram("fastIn_count", PopCount(allFastUop1.map(_.valid)), true.B, 0, allFastUop1.length, 1)
349  XSPerfHistogram("wakeup_count", PopCount(rfWriteback.map(_.valid)), true.B, 0, rfWriteback.length, 1)
350
351  ctrlBlock.perfinfo.perfEventsEu0 := exuBlocks(0).getPerf.dropRight(outer.exuBlocks(0).scheduler.numRs)
352  ctrlBlock.perfinfo.perfEventsEu1 := exuBlocks(1).getPerf.dropRight(outer.exuBlocks(1).scheduler.numRs)
353  memBlock.io.perfEventsPTW  := ptw.getPerf
354  ctrlBlock.perfinfo.perfEventsRs  := outer.exuBlocks.flatMap(b => b.module.getPerf.takeRight(b.scheduler.numRs))
355
356  csrioIn.hartId <> io.hartId
357  csrioIn.perf <> DontCare
358  csrioIn.perf.retiredInstr <> ctrlBlock.io.robio.toCSR.perfinfo.retiredInstr
359  csrioIn.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo
360  csrioIn.perf.memInfo <> memBlock.io.memInfo
361  csrioIn.perf.frontendInfo <> frontend.io.frontendInfo
362
363  csrioIn.perf.perfEventsFrontend <> frontend.getPerf
364  csrioIn.perf.perfEventsCtrl     <> ctrlBlock.getPerf
365  csrioIn.perf.perfEventsLsu      <> memBlock.getPerf
366  csrioIn.perf.perfEventsHc       <> io.perfEvents
367
368  csrioIn.fpu.fflags <> ctrlBlock.io.robio.toCSR.fflags
369  csrioIn.fpu.isIllegal := false.B
370  csrioIn.fpu.dirty_fs <> ctrlBlock.io.robio.toCSR.dirty_fs
371  csrioIn.fpu.frm <> exuBlocks(1).io.fuExtra.frm.get
372  csrioIn.exception <> ctrlBlock.io.robio.exception
373  csrioIn.isXRet <> ctrlBlock.io.robio.toCSR.isXRet
374  csrioIn.trapTarget <> ctrlBlock.io.robio.toCSR.trapTarget
375  csrioIn.interrupt <> ctrlBlock.io.robio.toCSR.intrBitSet
376  csrioIn.wfi_event <> ctrlBlock.io.robio.toCSR.wfiEvent
377  csrioIn.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr
378
379  csrioIn.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0)
380  csrioIn.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1)
381  csrioIn.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0)
382  csrioIn.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0)
383  csrioIn.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0)
384
385  csrioIn.distributedUpdate(0).w.valid := memBlock.io.csrUpdate.w.valid
386  csrioIn.distributedUpdate(0).w.bits := memBlock.io.csrUpdate.w.bits
387  csrioIn.distributedUpdate(1).w.valid := frontend.io.csrUpdate.w.valid
388  csrioIn.distributedUpdate(1).w.bits := frontend.io.csrUpdate.w.bits
389
390  fenceio.sfence <> memBlock.io.sfence
391  fenceio.sbuffer <> memBlock.io.fenceToSbuffer
392
393  memBlock.io.redirect <> ctrlBlock.io.redirect
394  memBlock.io.rsfeedback <> exuBlocks(0).io.scheExtra.feedback.get
395  memBlock.io.csrCtrl <> csrioIn.customCtrl
396  memBlock.io.tlbCsr <> csrioIn.tlb
397  memBlock.io.lsqio.rob <> ctrlBlock.io.robio.lsq
398  memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.robio.exception.bits.uop.ctrl.commitType)
399
400  val itlbRepeater1 = PTWRepeater(frontend.io.ptw, fenceio.sfence, csrioIn.tlb)
401  val itlbRepeater2 = PTWRepeater(itlbRepeater1.io.ptw, ptw.io.tlb(0), fenceio.sfence, csrioIn.tlb)
402  val dtlbRepeater1  = PTWFilter(memBlock.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.filterSize)
403  val dtlbRepeater2  = PTWRepeaterNB(passReady = false, dtlbRepeater1.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb)
404  ptw.io.sfence <> fenceio.sfence
405  ptw.io.csr.tlb <> csrioIn.tlb
406  ptw.io.csr.distribute_csr <> csrioIn.customCtrl.distribute_csr
407
408  // if l2 prefetcher use stream prefetch, it should be placed in XSCore
409  io.l2_pf_enable := csrioIn.customCtrl.l2_pf_enable
410
411  // Modules are reset one by one
412  val resetTree = ResetGenNode(
413    Seq(
414      ModuleNode(memBlock), ModuleNode(dtlbRepeater1),
415      ResetGenNode(Seq(
416        ModuleNode(itlbRepeater2),
417        ModuleNode(ptw),
418        ModuleNode(dtlbRepeater2),
419        ModuleNode(ptw_to_l2_buffer),
420      )),
421      ResetGenNode(Seq(
422        ModuleNode(exuBlocks.head),
423        ResetGenNode(
424          exuBlocks.tail.map(m => ModuleNode(m)) :+ ModuleNode(outer.wbArbiter.module)
425        ),
426        ResetGenNode(Seq(
427          ModuleNode(ctrlBlock),
428          ResetGenNode(Seq(
429            ModuleNode(frontend), ModuleNode(itlbRepeater1)
430          ))
431        ))
432      ))
433    )
434  )
435
436  ResetGen(resetTree, reset.asBool, !debugOpts.FPGAPlatform)
437
438}
439