xref: /XiangShan/src/main/scala/xiangshan/XSCore.scala (revision 1cee9cb85eece1a7a6880f1e9945a35c62cb4b3a)
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 dpExuConfigs = exuBlocks.flatMap(_.scheduler.dispatch2.map(_.configs))
228  val ctrlBlock = LazyModule(new CtrlBlock(dpExuConfigs))
229  val writebackSources = Seq(Seq(wb2Ctrl), Seq(wbArbiter))
230  writebackSources.foreach(s => ctrlBlock.addWritebackSink(s))
231}
232
233class XSCore()(implicit p: config.Parameters) extends XSCoreBase
234  with HasXSDts
235{
236  lazy val module = new XSCoreImp(this)
237}
238
239class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
240  with HasXSParameter
241  with HasSoCParameter {
242  val io = IO(new Bundle {
243    val hartId = Input(UInt(64.W))
244    val reset_vector = Input(UInt(PAddrBits.W))
245    val cpu_halt = Output(Bool())
246    val l2_pf_enable = Output(Bool())
247    val perfEvents = Input(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
248    val beu_errors = Output(new XSL1BusErrors())
249  })
250
251  println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}")
252
253  val frontend = outer.frontend.module
254  val ctrlBlock = outer.ctrlBlock.module
255  val wb2Ctrl = outer.wb2Ctrl.module
256  val memBlock = outer.memBlock.module
257  val ptw = outer.ptw.module
258  val ptw_to_l2_buffer = outer.ptw_to_l2_buffer.module
259  val exuBlocks = outer.exuBlocks.map(_.module)
260
261  frontend.io.hartId  := io.hartId
262  ctrlBlock.io.hartId := io.hartId
263  exuBlocks.foreach(_.io.hartId := io.hartId)
264  memBlock.io.hartId := io.hartId
265  outer.wbArbiter.module.io.hartId := io.hartId
266  frontend.io.reset_vector := io.reset_vector
267
268  io.cpu_halt := ctrlBlock.io.cpu_halt
269
270  outer.wbArbiter.module.io.redirect <> ctrlBlock.io.redirect
271  val allWriteback = exuBlocks.flatMap(_.io.fuWriteback) ++ memBlock.io.writeback
272  require(exuConfigs.length == allWriteback.length, s"${exuConfigs.length} != ${allWriteback.length}")
273  outer.wbArbiter.module.io.in <> allWriteback
274  val rfWriteback = outer.wbArbiter.module.io.out
275
276  // memblock error exception writeback, 1 cycle after normal writeback
277  wb2Ctrl.io.delayedLoadError <> memBlock.io.delayedLoadError
278
279  wb2Ctrl.io.redirect <> ctrlBlock.io.redirect
280  outer.wb2Ctrl.generateWritebackIO()
281
282  io.beu_errors.icache <> frontend.io.error.toL1BusErrorUnitInfo()
283  io.beu_errors.dcache <> memBlock.io.error.toL1BusErrorUnitInfo()
284
285  require(exuBlocks.count(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)) == 1)
286  val csrFenceMod = exuBlocks.filter(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)).head
287  val csrioIn = csrFenceMod.io.fuExtra.csrio.get
288  val fenceio = csrFenceMod.io.fuExtra.fenceio.get
289
290  frontend.io.backend <> ctrlBlock.io.frontend
291  frontend.io.sfence <> fenceio.sfence
292  frontend.io.tlbCsr <> csrioIn.tlb
293  frontend.io.csrCtrl <> csrioIn.customCtrl
294  frontend.io.fencei := fenceio.fencei
295
296  ctrlBlock.io.csrCtrl <> csrioIn.customCtrl
297  val redirectBlocks = exuBlocks.reverse.filter(_.fuConfigs.map(_._1).map(_.hasRedirect).reduce(_ || _))
298  ctrlBlock.io.exuRedirect <> redirectBlocks.flatMap(_.io.fuExtra.exuRedirect)
299  ctrlBlock.io.stIn <> memBlock.io.stIn
300  ctrlBlock.io.memoryViolation <> memBlock.io.memoryViolation
301  exuBlocks.head.io.scheExtra.enqLsq.get <> memBlock.io.enqLsq
302  exuBlocks.foreach(b => {
303    b.io.scheExtra.lcommit := ctrlBlock.io.robio.lsq.lcommit
304    b.io.scheExtra.scommit := memBlock.io.sqDeq
305    b.io.scheExtra.lqCancelCnt := memBlock.io.lqCancelCnt
306    b.io.scheExtra.sqCancelCnt := memBlock.io.sqCancelCnt
307  })
308  val sourceModules = outer.writebackSources.map(_.map(_.module.asInstanceOf[HasWritebackSourceImp]))
309  outer.ctrlBlock.generateWritebackIO()
310
311  val allFastUop = exuBlocks.flatMap(b => b.io.fastUopOut.dropRight(b.numOutFu)) ++ memBlock.io.otherFastWakeup
312  require(allFastUop.length == exuConfigs.length, s"${allFastUop.length} != ${exuConfigs.length}")
313  val intFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeIntRf).map(_._1)
314  val fpFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeFpRf).map(_._1)
315  val intFastUop1 = outer.wbArbiter.intConnections.map(c => intFastUop(c.head))
316  val fpFastUop1 = outer.wbArbiter.fpConnections.map(c => fpFastUop(c.head))
317  val allFastUop1 = intFastUop1 ++ fpFastUop1
318
319  ctrlBlock.io.dispatch <> exuBlocks.flatMap(_.io.in)
320  ctrlBlock.io.rsReady := exuBlocks.flatMap(_.io.scheExtra.rsReady)
321  ctrlBlock.io.enqLsq <> memBlock.io.enqLsq
322  ctrlBlock.io.sqDeq := memBlock.io.sqDeq
323  ctrlBlock.io.lqCancelCnt := memBlock.io.lqCancelCnt
324  ctrlBlock.io.sqCancelCnt := memBlock.io.sqCancelCnt
325
326  exuBlocks(0).io.scheExtra.fpRfReadIn.get <> exuBlocks(1).io.scheExtra.fpRfReadOut.get
327  exuBlocks(0).io.scheExtra.fpStateReadIn.get <> exuBlocks(1).io.scheExtra.fpStateReadOut.get
328
329  memBlock.io.issue <> exuBlocks(0).io.issue.get
330  // By default, instructions do not have exceptions when they enter the function units.
331  memBlock.io.issue.map(_.bits.uop.clearExceptions())
332  exuBlocks(0).io.scheExtra.loadFastMatch.get <> memBlock.io.loadFastMatch
333
334  val stdIssue = exuBlocks(0).io.issue.get.takeRight(exuParameters.StuCnt)
335  exuBlocks.map(_.io).foreach { exu =>
336    exu.redirect <> ctrlBlock.io.redirect
337    exu.allocPregs <> ctrlBlock.io.allocPregs
338    exu.rfWriteback <> rfWriteback
339    exu.fastUopIn <> allFastUop1
340    exu.scheExtra.jumpPc <> ctrlBlock.io.jumpPc
341    exu.scheExtra.jalr_target <> ctrlBlock.io.jalr_target
342    exu.scheExtra.stIssuePtr <> memBlock.io.stIssuePtr
343    exu.scheExtra.debug_fp_rat <> ctrlBlock.io.debug_fp_rat
344    exu.scheExtra.debug_int_rat <> ctrlBlock.io.debug_int_rat
345    exu.scheExtra.memWaitUpdateReq.staIssue.zip(memBlock.io.stIn).foreach{case (sink, src) => {
346      sink.bits := src.bits
347      sink.valid := src.valid
348    }}
349    exu.scheExtra.memWaitUpdateReq.stdIssue.zip(stdIssue).foreach{case (sink, src) => {
350      sink.valid := src.valid
351      sink.bits := src.bits
352    }}
353  }
354  XSPerfHistogram("fastIn_count", PopCount(allFastUop1.map(_.valid)), true.B, 0, allFastUop1.length, 1)
355  XSPerfHistogram("wakeup_count", PopCount(rfWriteback.map(_.valid)), true.B, 0, rfWriteback.length, 1)
356
357  ctrlBlock.perfinfo.perfEventsEu0 := exuBlocks(0).getPerf.dropRight(outer.exuBlocks(0).scheduler.numRs)
358  ctrlBlock.perfinfo.perfEventsEu1 := exuBlocks(1).getPerf.dropRight(outer.exuBlocks(1).scheduler.numRs)
359  memBlock.io.perfEventsPTW  := ptw.getPerf
360  ctrlBlock.perfinfo.perfEventsRs  := outer.exuBlocks.flatMap(b => b.module.getPerf.takeRight(b.scheduler.numRs))
361
362  csrioIn.hartId <> io.hartId
363  csrioIn.perf <> DontCare
364  csrioIn.perf.retiredInstr <> ctrlBlock.io.robio.toCSR.perfinfo.retiredInstr
365  csrioIn.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo
366  csrioIn.perf.memInfo <> memBlock.io.memInfo
367  csrioIn.perf.frontendInfo <> frontend.io.frontendInfo
368
369  csrioIn.perf.perfEventsFrontend <> frontend.getPerf
370  csrioIn.perf.perfEventsCtrl     <> ctrlBlock.getPerf
371  csrioIn.perf.perfEventsLsu      <> memBlock.getPerf
372  csrioIn.perf.perfEventsHc       <> io.perfEvents
373
374  csrioIn.fpu.fflags <> ctrlBlock.io.robio.toCSR.fflags
375  csrioIn.fpu.isIllegal := false.B
376  csrioIn.fpu.dirty_fs <> ctrlBlock.io.robio.toCSR.dirty_fs
377  csrioIn.fpu.frm <> exuBlocks(1).io.fuExtra.frm.get
378  csrioIn.exception <> ctrlBlock.io.robio.exception
379  csrioIn.isXRet <> ctrlBlock.io.robio.toCSR.isXRet
380  csrioIn.trapTarget <> ctrlBlock.io.robio.toCSR.trapTarget
381  csrioIn.interrupt <> ctrlBlock.io.robio.toCSR.intrBitSet
382  csrioIn.wfi_event <> ctrlBlock.io.robio.toCSR.wfiEvent
383  csrioIn.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr
384
385  csrioIn.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0)
386  csrioIn.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1)
387  csrioIn.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0)
388  csrioIn.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0)
389  csrioIn.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0)
390
391  csrioIn.distributedUpdate(0).w.valid := memBlock.io.csrUpdate.w.valid
392  csrioIn.distributedUpdate(0).w.bits := memBlock.io.csrUpdate.w.bits
393  csrioIn.distributedUpdate(1).w.valid := frontend.io.csrUpdate.w.valid
394  csrioIn.distributedUpdate(1).w.bits := frontend.io.csrUpdate.w.bits
395
396  fenceio.sfence <> memBlock.io.sfence
397  fenceio.sbuffer <> memBlock.io.fenceToSbuffer
398
399  memBlock.io.redirect <> ctrlBlock.io.redirect
400  memBlock.io.rsfeedback <> exuBlocks(0).io.scheExtra.feedback.get
401  memBlock.io.csrCtrl <> csrioIn.customCtrl
402  memBlock.io.tlbCsr <> csrioIn.tlb
403  memBlock.io.lsqio.rob <> ctrlBlock.io.robio.lsq
404  memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.robio.exception.bits.uop.ctrl.commitType)
405
406  val itlbRepeater1 = PTWRepeater(frontend.io.ptw, fenceio.sfence, csrioIn.tlb)
407  val itlbRepeater2 = PTWRepeater(itlbRepeater1.io.ptw, ptw.io.tlb(0), fenceio.sfence, csrioIn.tlb)
408  val dtlbRepeater1  = PTWFilter(memBlock.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.filterSize)
409  val dtlbRepeater2  = PTWRepeaterNB(passReady = false, dtlbRepeater1.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb)
410  ptw.io.sfence <> fenceio.sfence
411  ptw.io.csr.tlb <> csrioIn.tlb
412  ptw.io.csr.distribute_csr <> csrioIn.customCtrl.distribute_csr
413
414  // if l2 prefetcher use stream prefetch, it should be placed in XSCore
415  io.l2_pf_enable := csrioIn.customCtrl.l2_pf_enable
416
417  // Modules are reset one by one
418  val resetTree = ResetGenNode(
419    Seq(
420      ModuleNode(memBlock), ModuleNode(dtlbRepeater1),
421      ResetGenNode(Seq(
422        ModuleNode(itlbRepeater2),
423        ModuleNode(ptw),
424        ModuleNode(dtlbRepeater2),
425        ModuleNode(ptw_to_l2_buffer),
426      )),
427      ResetGenNode(Seq(
428        ModuleNode(exuBlocks.head),
429        ResetGenNode(
430          exuBlocks.tail.map(m => ModuleNode(m)) :+ ModuleNode(outer.wbArbiter.module)
431        ),
432        ResetGenNode(Seq(
433          ModuleNode(ctrlBlock),
434          ResetGenNode(Seq(
435            ModuleNode(frontend), ModuleNode(itlbRepeater1)
436          ))
437        ))
438      ))
439    )
440  )
441
442  ResetGen(resetTree, reset.asBool, !debugOpts.FPGAPlatform)
443
444}
445