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