xref: /XiangShan/src/main/scala/xiangshan/XSCore.scala (revision 40a70bd6dfd3d57045629b3cc57f870a2d2bba4b)
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: Seq[Seq[ExuConfig]] = wbArbiter.intWbPorts
147  val fpWbPorts: Seq[Seq[ExuConfig]] = 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 aluScheLaneCfg = ScheLaneConfig(
158    aluRSMod,
159    AluExeUnitCfg,
160    exuParameters.AluCnt,
161    Seq(AluExeUnitCfg, LdExeUnitCfg, StaExeUnitCfg))
162  val mulScheLaneCfg = ScheLaneConfig(
163    mulRSMod,
164    MulDivExeUnitCfg,
165    exuParameters.MduCnt,
166    Seq(AluExeUnitCfg, MulDivExeUnitCfg))
167  val jumpScheLaneCfg = ScheLaneConfig(
168    jumpRSMod,
169    JumpCSRExeUnitCfg,
170    1)
171  val loadScheLaneCfg = ScheLaneConfig(
172    loadRSMod,
173    LdExeUnitCfg,
174    exuParameters.LduCnt,
175    Seq(AluExeUnitCfg, LdExeUnitCfg))
176  val staScheLaneCfg = ScheLaneConfig(
177    staRSMod,
178    StaExeUnitCfg,
179    exuParameters.StuCnt)
180  val stdScheLaneCfg = ScheLaneConfig(
181    stdRSMod,
182    StdExeUnitCfg,
183    exuParameters.StuCnt)
184  val fmaScheLaneCfg = ScheLaneConfig(
185    fmaRSMod,
186    FmacExeUnitCfg,
187    exuParameters.FmacCnt,
188    Seq(),
189    Seq(FmacExeUnitCfg, FmiscExeUnitCfg))
190  val fmiscScheLaneCfg = ScheLaneConfig(
191    fmiscRSMod,
192    FmiscExeUnitCfg,
193    exuParameters.FmiscCnt)
194
195  val scheduleCfgs = Seq(
196    Seq(
197      aluScheLaneCfg,
198      mulScheLaneCfg,
199      jumpScheLaneCfg,
200      loadScheLaneCfg,
201      staScheLaneCfg,
202      stdScheLaneCfg
203    ),
204    Seq(
205      fmaScheLaneCfg,
206      fmiscScheLaneCfg
207    )
208  )
209  // should do outer fast wakeup ports here
210  val otherFastPorts: Seq[Seq[Seq[Int]]] = scheduleCfgs.zipWithIndex.map { case (sche, i) =>
211    val otherCfg = scheduleCfgs.zipWithIndex.filter(_._2 != i).map(_._1).reduce(_ ++ _)
212    val outerPorts = sche.map(cfg => {
213      // exe units from this scheduler need fastUops from exeunits
214      val outerWakeupInSche = sche.filter(_.exuConfig.wakeupFromExu)
215      val intraIntScheOuter = outerWakeupInSche.filter(_.intFastWakeupTarget.contains(cfg.exuConfig)).map(_.exuConfig)
216      val intraFpScheOuter = outerWakeupInSche.filter(_.fpFastWakeupTarget.contains(cfg.exuConfig)).map(_.exuConfig)
217      // exe units from other schedulers need fastUop from outside
218      val otherIntSource = otherCfg.filter(_.intFastWakeupTarget.contains(cfg.exuConfig)).map(_.exuConfig)
219      val otherFpSource = otherCfg.filter(_.fpFastWakeupTarget.contains(cfg.exuConfig)).map(_.exuConfig)
220      val intSource = findInWbPorts(intWbPorts, intraIntScheOuter ++ otherIntSource)
221      val fpSource = findInWbPorts(fpWbPorts, intraFpScheOuter ++ otherFpSource)
222      getFastWakeupIndex(cfg.exuConfig, intSource, fpSource, intWbPorts.length).sorted
223    })
224    println(s"inter-scheduler wakeup sources for $i: $outerPorts")
225    outerPorts
226  }
227
228  // allow mdu and fmisc to have 2*numDeq enqueue ports
229  val intDpPorts = (0 until exuParameters.AluCnt).map(i => {
230    if (i < exuParameters.JmpCnt) Seq(
231      DpPortMapConfig(0, i),
232      DpPortMapConfig(1, i),
233      DpPortMapConfig(2, i))
234    else if (i < 2 * exuParameters.MduCnt) Seq(
235      DpPortMapConfig(0, i),
236      DpPortMapConfig(1, i))
237    else Seq(DpPortMapConfig(0, i))
238  })
239  val lsDpPorts = (0 until exuParameters.LduCnt).map(i => Seq(DpPortMapConfig(3, i))) ++
240                  (0 until exuParameters.StuCnt).map(i => Seq(DpPortMapConfig(4, i))) ++
241                  (0 until exuParameters.StuCnt).map(i => Seq(DpPortMapConfig(5, i)))
242  val fpDpPorts = (0 until exuParameters.FmacCnt).map(i => {
243    if (i < 2 * exuParameters.FmiscCnt) Seq(DpPortMapConfig(0, i), DpPortMapConfig(1, i))
244    else Seq(DpPortMapConfig(0, i))
245  })
246
247  val dispatchPorts = Seq(intDpPorts ++ lsDpPorts, fpDpPorts)
248
249  val outIntRfReadPorts = Seq(0, 0)
250  val outFpRfReadPorts = Seq(0, StorePipelineWidth)
251  val hasIntRf = Seq(true, false)
252  val hasFpRf = Seq(false, true)
253  val exuBlocks = scheduleCfgs.zip(dispatchPorts).zip(otherFastPorts).zipWithIndex.map {
254    case (((sche, disp), other), i) =>
255      LazyModule(new ExuBlock(sche, disp, intWbPorts, fpWbPorts, other, outIntRfReadPorts(i), outFpRfReadPorts(i), hasIntRf(i), hasFpRf(i)))
256  }
257
258  val memBlock = LazyModule(new MemBlock()(p.alter((site, here, up) => {
259    case XSCoreParamsKey => up(XSCoreParamsKey).copy(
260      IssQueSize = exuBlocks.head.scheduler.getMemRsEntries
261    )
262  })))
263
264  val wb2Ctrl = LazyModule(new Wb2Ctrl(exuConfigs))
265  wb2Ctrl.addWritebackSink(exuBlocks :+ memBlock)
266  val dpExuConfigs = exuBlocks.flatMap(_.scheduler.dispatch2.map(_.configs))
267  val ctrlBlock = LazyModule(new CtrlBlock(dpExuConfigs))
268  val writebackSources = Seq(Seq(wb2Ctrl), Seq(wbArbiter))
269  writebackSources.foreach(s => ctrlBlock.addWritebackSink(s))
270}
271
272class XSCore()(implicit p: config.Parameters) extends XSCoreBase
273  with HasXSDts
274{
275  lazy val module = new XSCoreImp(this)
276}
277
278class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
279  with HasXSParameter
280  with HasSoCParameter {
281  val io = IO(new Bundle {
282    val hartId = Input(UInt(64.W))
283    val reset_vector = Input(UInt(PAddrBits.W))
284    val cpu_halt = Output(Bool())
285    val l2_pf_enable = Output(Bool())
286    val perfEvents = Input(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent))
287    val beu_errors = Output(new XSL1BusErrors())
288  })
289
290  println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}")
291
292  val frontend = outer.frontend.module
293  val ctrlBlock = outer.ctrlBlock.module
294  val wb2Ctrl = outer.wb2Ctrl.module
295  val memBlock = outer.memBlock.module
296  val ptw = outer.ptw.module
297  val ptw_to_l2_buffer = outer.ptw_to_l2_buffer.module
298  val exuBlocks = outer.exuBlocks.map(_.module)
299
300  frontend.io.hartId  := io.hartId
301  ctrlBlock.io.hartId := io.hartId
302  exuBlocks.foreach(_.io.hartId := io.hartId)
303  memBlock.io.hartId := io.hartId
304  outer.wbArbiter.module.io.hartId := io.hartId
305  frontend.io.reset_vector := io.reset_vector
306
307  io.cpu_halt := ctrlBlock.io.cpu_halt
308
309  outer.wbArbiter.module.io.redirect <> ctrlBlock.io.redirect
310  val allWriteback = exuBlocks.flatMap(_.io.fuWriteback) ++ memBlock.io.writeback
311  require(exuConfigs.length == allWriteback.length, s"${exuConfigs.length} != ${allWriteback.length}")
312  outer.wbArbiter.module.io.in <> allWriteback
313  val rfWriteback = outer.wbArbiter.module.io.out
314
315  // memblock error exception writeback, 1 cycle after normal writeback
316  wb2Ctrl.io.s3_delayed_load_error <> memBlock.io.s3_delayed_load_error
317
318  wb2Ctrl.io.redirect <> ctrlBlock.io.redirect
319  outer.wb2Ctrl.generateWritebackIO()
320
321  io.beu_errors.icache <> frontend.io.error.toL1BusErrorUnitInfo()
322  io.beu_errors.dcache <> memBlock.io.error.toL1BusErrorUnitInfo()
323
324  require(exuBlocks.count(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)) == 1)
325  val csrFenceMod = exuBlocks.filter(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)).head
326  val csrioIn = csrFenceMod.io.fuExtra.csrio.get
327  val fenceio = csrFenceMod.io.fuExtra.fenceio.get
328
329  frontend.io.backend <> ctrlBlock.io.frontend
330  frontend.io.sfence <> fenceio.sfence
331  frontend.io.tlbCsr <> csrioIn.tlb
332  frontend.io.csrCtrl <> csrioIn.customCtrl
333  frontend.io.fencei := fenceio.fencei
334
335  ctrlBlock.io.csrCtrl <> csrioIn.customCtrl
336  val redirectBlocks = exuBlocks.reverse.filter(_.fuConfigs.map(_._1).map(_.hasRedirect).reduce(_ || _))
337  ctrlBlock.io.exuRedirect <> redirectBlocks.flatMap(_.io.fuExtra.exuRedirect)
338  ctrlBlock.io.stIn <> memBlock.io.stIn
339  ctrlBlock.io.memoryViolation <> memBlock.io.memoryViolation
340  exuBlocks.head.io.scheExtra.enqLsq.get <> memBlock.io.enqLsq
341  exuBlocks.foreach(b => {
342    b.io.scheExtra.lcommit := ctrlBlock.io.robio.lsq.lcommit
343    b.io.scheExtra.scommit := memBlock.io.sqDeq
344    b.io.scheExtra.lqCancelCnt := memBlock.io.lqCancelCnt
345    b.io.scheExtra.sqCancelCnt := memBlock.io.sqCancelCnt
346  })
347  val sourceModules = outer.writebackSources.map(_.map(_.module.asInstanceOf[HasWritebackSourceImp]))
348  outer.ctrlBlock.generateWritebackIO()
349
350  val allFastUop = exuBlocks.flatMap(b => b.io.fastUopOut.dropRight(b.numOutFu)) ++ memBlock.io.otherFastWakeup
351  require(allFastUop.length == exuConfigs.length, s"${allFastUop.length} != ${exuConfigs.length}")
352  val intFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeIntRf).map(_._1)
353  val fpFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeFpRf).map(_._1)
354  val intFastUop1 = outer.wbArbiter.intConnections.map(c => intFastUop(c.head))
355  val fpFastUop1 = outer.wbArbiter.fpConnections.map(c => fpFastUop(c.head))
356  val allFastUop1 = intFastUop1 ++ fpFastUop1
357
358  ctrlBlock.io.dispatch <> exuBlocks.flatMap(_.io.in)
359  ctrlBlock.io.rsReady := exuBlocks.flatMap(_.io.scheExtra.rsReady)
360  ctrlBlock.io.enqLsq <> memBlock.io.enqLsq
361  ctrlBlock.io.sqDeq := memBlock.io.sqDeq
362  ctrlBlock.io.lqCancelCnt := memBlock.io.lqCancelCnt
363  ctrlBlock.io.sqCancelCnt := memBlock.io.sqCancelCnt
364
365  exuBlocks(0).io.scheExtra.fpRfReadIn.get <> exuBlocks(1).io.scheExtra.fpRfReadOut.get
366  exuBlocks(0).io.scheExtra.fpStateReadIn.get <> exuBlocks(1).io.scheExtra.fpStateReadOut.get
367
368  memBlock.io.issue <> exuBlocks(0).io.issue.get
369  // By default, instructions do not have exceptions when they enter the function units.
370  memBlock.io.issue.map(_.bits.uop.clearExceptions())
371  exuBlocks(0).io.scheExtra.loadFastMatch.get <> memBlock.io.loadFastMatch
372  exuBlocks(0).io.scheExtra.loadFastImm.get <> memBlock.io.loadFastImm
373
374  val stdIssue = exuBlocks(0).io.issue.get.takeRight(exuParameters.StuCnt)
375  exuBlocks.map(_.io).foreach { exu =>
376    exu.redirect <> ctrlBlock.io.redirect
377    exu.allocPregs <> ctrlBlock.io.allocPregs
378    exu.rfWritebackInt <> rfWriteback.take(NRIntWritePorts)
379    exu.rfWritebackFp <> rfWriteback.drop(NRIntWritePorts)
380    exu.fastUopIn <> allFastUop1
381    exu.scheExtra.jumpPc <> ctrlBlock.io.jumpPc
382    exu.scheExtra.jalr_target <> ctrlBlock.io.jalr_target
383    exu.scheExtra.stIssuePtr <> memBlock.io.stIssuePtr
384    exu.scheExtra.debug_fp_rat <> ctrlBlock.io.debug_fp_rat
385    exu.scheExtra.debug_int_rat <> ctrlBlock.io.debug_int_rat
386    exu.scheExtra.debug_vec_rat <> ctrlBlock.io.debug_vec_rat
387    exu.scheExtra.lqFull := memBlock.io.lqFull
388    exu.scheExtra.sqFull := memBlock.io.sqFull
389    exu.scheExtra.memWaitUpdateReq.staIssue.zip(memBlock.io.stIn).foreach{case (sink, src) => {
390      sink.bits := src.bits
391      sink.valid := src.valid
392    }}
393    exu.scheExtra.memWaitUpdateReq.stdIssue.zip(stdIssue).foreach{case (sink, src) => {
394      sink.valid := src.valid
395      sink.bits := src.bits
396    }}
397  }
398  XSPerfHistogram("fastIn_count", PopCount(allFastUop1.map(_.valid)), true.B, 0, allFastUop1.length, 1)
399  XSPerfHistogram("wakeup_count", PopCount(rfWriteback.map(_.valid)), true.B, 0, rfWriteback.length, 1)
400
401  ctrlBlock.perfinfo.perfEventsEu0 := exuBlocks(0).getPerf.dropRight(outer.exuBlocks(0).scheduler.numRs)
402  ctrlBlock.perfinfo.perfEventsEu1 := exuBlocks(1).getPerf.dropRight(outer.exuBlocks(1).scheduler.numRs)
403  memBlock.io.perfEventsPTW  := ptw.getPerf
404  ctrlBlock.perfinfo.perfEventsRs  := outer.exuBlocks.flatMap(b => b.module.getPerf.takeRight(b.scheduler.numRs))
405
406  csrioIn.hartId <> io.hartId
407  csrioIn.perf <> DontCare
408  csrioIn.perf.retiredInstr <> ctrlBlock.io.robio.toCSR.perfinfo.retiredInstr
409  csrioIn.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo
410  csrioIn.perf.memInfo <> memBlock.io.memInfo
411  csrioIn.perf.frontendInfo <> frontend.io.frontendInfo
412
413  csrioIn.perf.perfEventsFrontend <> frontend.getPerf
414  csrioIn.perf.perfEventsCtrl     <> ctrlBlock.getPerf
415  csrioIn.perf.perfEventsLsu      <> memBlock.getPerf
416  csrioIn.perf.perfEventsHc       <> io.perfEvents
417
418  csrioIn.fpu.fflags <> ctrlBlock.io.robio.toCSR.fflags
419  csrioIn.fpu.isIllegal := false.B
420  csrioIn.fpu.dirty_fs <> ctrlBlock.io.robio.toCSR.dirty_fs
421  csrioIn.fpu.frm <> exuBlocks(1).io.fuExtra.frm.get
422  csrioIn.vpu <> DontCare
423  csrioIn.exception <> ctrlBlock.io.robio.exception
424  csrioIn.isXRet <> ctrlBlock.io.robio.toCSR.isXRet
425  csrioIn.trapTarget <> ctrlBlock.io.robio.toCSR.trapTarget
426  csrioIn.interrupt <> ctrlBlock.io.robio.toCSR.intrBitSet
427  csrioIn.wfi_event <> ctrlBlock.io.robio.toCSR.wfiEvent
428  csrioIn.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr
429
430  csrioIn.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0)
431  csrioIn.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1)
432  csrioIn.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0)
433  csrioIn.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0)
434  csrioIn.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0)
435
436  csrioIn.distributedUpdate(0).w.valid := memBlock.io.csrUpdate.w.valid
437  csrioIn.distributedUpdate(0).w.bits := memBlock.io.csrUpdate.w.bits
438  csrioIn.distributedUpdate(1).w.valid := frontend.io.csrUpdate.w.valid
439  csrioIn.distributedUpdate(1).w.bits := frontend.io.csrUpdate.w.bits
440
441  fenceio.sfence <> memBlock.io.sfence
442  fenceio.sbuffer <> memBlock.io.fenceToSbuffer
443
444  memBlock.io.redirect <> ctrlBlock.io.redirect
445  memBlock.io.rsfeedback <> exuBlocks(0).io.scheExtra.feedback.get
446  memBlock.io.csrCtrl <> csrioIn.customCtrl
447  memBlock.io.tlbCsr <> csrioIn.tlb
448  memBlock.io.lsqio.rob <> ctrlBlock.io.robio.lsq
449  memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.robio.exception.bits.uop.ctrl.commitType)
450
451  val itlbRepeater1 = PTWFilter(itlbParams.fenceDelay,frontend.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.ifilterSize)
452  val itlbRepeater2 = PTWRepeaterNB(passReady = false, itlbParams.fenceDelay, itlbRepeater1.io.ptw, ptw.io.tlb(0), fenceio.sfence, csrioIn.tlb)
453  val dtlbRepeater1  = PTWFilter(ldtlbParams.fenceDelay, memBlock.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.dfilterSize)
454  val dtlbRepeater2  = PTWRepeaterNB(passReady = false, ldtlbParams.fenceDelay, dtlbRepeater1.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb)
455  ptw.io.sfence <> fenceio.sfence
456  ptw.io.csr.tlb <> csrioIn.tlb
457  ptw.io.csr.distribute_csr <> csrioIn.customCtrl.distribute_csr
458
459  // if l2 prefetcher use stream prefetch, it should be placed in XSCore
460  io.l2_pf_enable := csrioIn.customCtrl.l2_pf_enable
461
462  // Modules are reset one by one
463  val resetTree = ResetGenNode(
464    Seq(
465      ModuleNode(memBlock), ModuleNode(dtlbRepeater1),
466      ResetGenNode(Seq(
467        ModuleNode(itlbRepeater2),
468        ModuleNode(ptw),
469        ModuleNode(dtlbRepeater2),
470        ModuleNode(ptw_to_l2_buffer),
471      )),
472      ResetGenNode(Seq(
473        ModuleNode(exuBlocks.head),
474        ResetGenNode(
475          exuBlocks.tail.map(m => ModuleNode(m)) :+ ModuleNode(outer.wbArbiter.module)
476        ),
477        ResetGenNode(Seq(
478          ModuleNode(ctrlBlock),
479          ResetGenNode(Seq(
480            ModuleNode(frontend), ModuleNode(itlbRepeater1)
481          ))
482        ))
483      ))
484    )
485  )
486
487  ResetGen(resetTree, reset.asBool, !debugOpts.FPGAPlatform)
488
489}
490