xref: /XiangShan/src/main/scala/xiangshan/XSCore.scala (revision ad879770035509f1ebb208419268032c0eb1202a)
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, 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  exuBlocks(0).io.scheExtra.loadFastImm.get <> memBlock.io.loadFastImm
334
335  val stdIssue = exuBlocks(0).io.issue.get.takeRight(exuParameters.StuCnt)
336  exuBlocks.map(_.io).foreach { exu =>
337    exu.redirect <> ctrlBlock.io.redirect
338    exu.allocPregs <> ctrlBlock.io.allocPregs
339    exu.rfWriteback <> rfWriteback
340    exu.fastUopIn <> allFastUop1
341    exu.scheExtra.jumpPc <> ctrlBlock.io.jumpPc
342    exu.scheExtra.jalr_target <> ctrlBlock.io.jalr_target
343    exu.scheExtra.stIssuePtr <> memBlock.io.stIssuePtr
344    exu.scheExtra.debug_fp_rat <> ctrlBlock.io.debug_fp_rat
345    exu.scheExtra.debug_int_rat <> ctrlBlock.io.debug_int_rat
346    exu.scheExtra.memWaitUpdateReq.staIssue.zip(memBlock.io.stIn).foreach{case (sink, src) => {
347      sink.bits := src.bits
348      sink.valid := src.valid
349    }}
350    exu.scheExtra.memWaitUpdateReq.stdIssue.zip(stdIssue).foreach{case (sink, src) => {
351      sink.valid := src.valid
352      sink.bits := src.bits
353    }}
354  }
355  XSPerfHistogram("fastIn_count", PopCount(allFastUop1.map(_.valid)), true.B, 0, allFastUop1.length, 1)
356  XSPerfHistogram("wakeup_count", PopCount(rfWriteback.map(_.valid)), true.B, 0, rfWriteback.length, 1)
357
358  ctrlBlock.perfinfo.perfEventsEu0 := exuBlocks(0).getPerf.dropRight(outer.exuBlocks(0).scheduler.numRs)
359  ctrlBlock.perfinfo.perfEventsEu1 := exuBlocks(1).getPerf.dropRight(outer.exuBlocks(1).scheduler.numRs)
360  memBlock.io.perfEventsPTW  := ptw.getPerf
361  ctrlBlock.perfinfo.perfEventsRs  := outer.exuBlocks.flatMap(b => b.module.getPerf.takeRight(b.scheduler.numRs))
362
363  csrioIn.hartId <> io.hartId
364  csrioIn.perf <> DontCare
365  csrioIn.perf.retiredInstr <> ctrlBlock.io.robio.toCSR.perfinfo.retiredInstr
366  csrioIn.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo
367  csrioIn.perf.memInfo <> memBlock.io.memInfo
368  csrioIn.perf.frontendInfo <> frontend.io.frontendInfo
369
370  csrioIn.perf.perfEventsFrontend <> frontend.getPerf
371  csrioIn.perf.perfEventsCtrl     <> ctrlBlock.getPerf
372  csrioIn.perf.perfEventsLsu      <> memBlock.getPerf
373  csrioIn.perf.perfEventsHc       <> io.perfEvents
374
375  csrioIn.fpu.fflags <> ctrlBlock.io.robio.toCSR.fflags
376  csrioIn.fpu.isIllegal := false.B
377  csrioIn.fpu.dirty_fs <> ctrlBlock.io.robio.toCSR.dirty_fs
378  csrioIn.fpu.frm <> exuBlocks(1).io.fuExtra.frm.get
379  csrioIn.exception <> ctrlBlock.io.robio.exception
380  csrioIn.isXRet <> ctrlBlock.io.robio.toCSR.isXRet
381  csrioIn.trapTarget <> ctrlBlock.io.robio.toCSR.trapTarget
382  csrioIn.interrupt <> ctrlBlock.io.robio.toCSR.intrBitSet
383  csrioIn.wfi_event <> ctrlBlock.io.robio.toCSR.wfiEvent
384  csrioIn.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr
385
386  csrioIn.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0)
387  csrioIn.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1)
388  csrioIn.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0)
389  csrioIn.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0)
390  csrioIn.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0)
391
392  csrioIn.distributedUpdate(0).w.valid := memBlock.io.csrUpdate.w.valid
393  csrioIn.distributedUpdate(0).w.bits := memBlock.io.csrUpdate.w.bits
394  csrioIn.distributedUpdate(1).w.valid := frontend.io.csrUpdate.w.valid
395  csrioIn.distributedUpdate(1).w.bits := frontend.io.csrUpdate.w.bits
396
397  fenceio.sfence <> memBlock.io.sfence
398  fenceio.sbuffer <> memBlock.io.fenceToSbuffer
399
400  memBlock.io.redirect <> ctrlBlock.io.redirect
401  memBlock.io.rsfeedback <> exuBlocks(0).io.scheExtra.feedback.get
402  memBlock.io.csrCtrl <> csrioIn.customCtrl
403  memBlock.io.tlbCsr <> csrioIn.tlb
404  memBlock.io.lsqio.rob <> ctrlBlock.io.robio.lsq
405  memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.robio.exception.bits.uop.ctrl.commitType)
406
407  val itlbRepeater1 = PTWFilter(itlbParams.fenceDelay,frontend.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.ifilterSize)
408  val itlbRepeater2 = PTWRepeaterNB(passReady = false, itlbParams.fenceDelay, itlbRepeater1.io.ptw, ptw.io.tlb(0), fenceio.sfence, csrioIn.tlb)
409  val dtlbRepeater1  = PTWFilter(ldtlbParams.fenceDelay, memBlock.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.dfilterSize)
410  val dtlbRepeater2  = PTWRepeaterNB(passReady = false, ldtlbParams.fenceDelay, dtlbRepeater1.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb)
411  ptw.io.sfence <> fenceio.sfence
412  ptw.io.csr.tlb <> csrioIn.tlb
413  ptw.io.csr.distribute_csr <> csrioIn.customCtrl.distribute_csr
414
415  // if l2 prefetcher use stream prefetch, it should be placed in XSCore
416  io.l2_pf_enable := csrioIn.customCtrl.l2_pf_enable
417
418  // Modules are reset one by one
419  val resetTree = ResetGenNode(
420    Seq(
421      ModuleNode(memBlock), ModuleNode(dtlbRepeater1),
422      ResetGenNode(Seq(
423        ModuleNode(itlbRepeater2),
424        ModuleNode(ptw),
425        ModuleNode(dtlbRepeater2),
426        ModuleNode(ptw_to_l2_buffer),
427      )),
428      ResetGenNode(Seq(
429        ModuleNode(exuBlocks.head),
430        ResetGenNode(
431          exuBlocks.tail.map(m => ModuleNode(m)) :+ ModuleNode(outer.wbArbiter.module)
432        ),
433        ResetGenNode(Seq(
434          ModuleNode(ctrlBlock),
435          ResetGenNode(Seq(
436            ModuleNode(frontend), ModuleNode(itlbRepeater1)
437          ))
438        ))
439      ))
440    )
441  )
442
443  ResetGen(resetTree, reset.asBool, !debugOpts.FPGAPlatform)
444
445}
446