xref: /XiangShan/src/main/scala/xiangshan/XSCore.scala (revision eb163ef08fc5ac1da1f32d948699bd6de053e444)
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.lqFull := memBlock.io.lqFull
345    exu.scheExtra.sqFull := memBlock.io.sqFull
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