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