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