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, MulDivExeUnitCfg, JumpCSRExeUnitCfg, 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 ctrlBlock = LazyModule(new CtrlBlock) 228 val writebackSources = Seq(Seq(wb2Ctrl), Seq(wbArbiter)) 229 writebackSources.foreach(s => ctrlBlock.addWritebackSink(s)) 230} 231 232class XSCore()(implicit p: config.Parameters) extends XSCoreBase 233 with HasXSDts 234{ 235 lazy val module = new XSCoreImp(this) 236} 237 238class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer) 239 with HasXSParameter 240 with HasSoCParameter { 241 val io = IO(new Bundle { 242 val hartId = Input(UInt(64.W)) 243 val reset_vector = Input(UInt(PAddrBits.W)) 244 val cpu_halt = Output(Bool()) 245 val l2_pf_enable = Output(Bool()) 246 val perfEvents = Input(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 247 val beu_errors = Output(new XSL1BusErrors()) 248 }) 249 250 println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}") 251 252 val frontend = outer.frontend.module 253 val ctrlBlock = outer.ctrlBlock.module 254 val wb2Ctrl = outer.wb2Ctrl.module 255 val memBlock = outer.memBlock.module 256 val ptw = outer.ptw.module 257 val ptw_to_l2_buffer = outer.ptw_to_l2_buffer.module 258 val exuBlocks = outer.exuBlocks.map(_.module) 259 260 frontend.io.hartId := io.hartId 261 ctrlBlock.io.hartId := io.hartId 262 exuBlocks.foreach(_.io.hartId := io.hartId) 263 memBlock.io.hartId := io.hartId 264 outer.wbArbiter.module.io.hartId := io.hartId 265 frontend.io.reset_vector := io.reset_vector 266 267 io.cpu_halt := ctrlBlock.io.cpu_halt 268 269 outer.wbArbiter.module.io.redirect <> ctrlBlock.io.redirect 270 val allWriteback = exuBlocks.flatMap(_.io.fuWriteback) ++ memBlock.io.writeback 271 require(exuConfigs.length == allWriteback.length, s"${exuConfigs.length} != ${allWriteback.length}") 272 outer.wbArbiter.module.io.in <> allWriteback 273 val rfWriteback = outer.wbArbiter.module.io.out 274 275 // memblock error exception writeback, 1 cycle after normal writeback 276 wb2Ctrl.io.delayedLoadError <> memBlock.io.delayedLoadError 277 278 wb2Ctrl.io.redirect <> ctrlBlock.io.redirect 279 outer.wb2Ctrl.generateWritebackIO() 280 281 io.beu_errors.icache <> frontend.io.error.toL1BusErrorUnitInfo() 282 io.beu_errors.dcache <> memBlock.io.error.toL1BusErrorUnitInfo() 283 284 require(exuBlocks.count(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)) == 1) 285 val csrFenceMod = exuBlocks.filter(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)).head 286 val csrioIn = csrFenceMod.io.fuExtra.csrio.get 287 val fenceio = csrFenceMod.io.fuExtra.fenceio.get 288 289 frontend.io.backend <> ctrlBlock.io.frontend 290 frontend.io.sfence <> fenceio.sfence 291 frontend.io.tlbCsr <> csrioIn.tlb 292 frontend.io.csrCtrl <> csrioIn.customCtrl 293 frontend.io.fencei := fenceio.fencei 294 295 ctrlBlock.io.csrCtrl <> csrioIn.customCtrl 296 val redirectBlocks = exuBlocks.reverse.filter(_.fuConfigs.map(_._1).map(_.hasRedirect).reduce(_ || _)) 297 ctrlBlock.io.exuRedirect <> redirectBlocks.flatMap(_.io.fuExtra.exuRedirect) 298 ctrlBlock.io.stIn <> memBlock.io.stIn 299 ctrlBlock.io.memoryViolation <> memBlock.io.memoryViolation 300 exuBlocks.head.io.scheExtra.enqLsq.get <> memBlock.io.enqLsq 301 exuBlocks.foreach(b => { 302 b.io.scheExtra.lcommit := ctrlBlock.io.robio.lsq.lcommit 303 b.io.scheExtra.scommit := memBlock.io.sqDeq 304 b.io.scheExtra.lqCancelCnt := memBlock.io.lqCancelCnt 305 b.io.scheExtra.sqCancelCnt := memBlock.io.sqCancelCnt 306 }) 307 val sourceModules = outer.writebackSources.map(_.map(_.module.asInstanceOf[HasWritebackSourceImp])) 308 outer.ctrlBlock.generateWritebackIO() 309 310 val allFastUop = exuBlocks.flatMap(b => b.io.fastUopOut.dropRight(b.numOutFu)) ++ memBlock.io.otherFastWakeup 311 require(allFastUop.length == exuConfigs.length, s"${allFastUop.length} != ${exuConfigs.length}") 312 val intFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeIntRf).map(_._1) 313 val fpFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeFpRf).map(_._1) 314 val intFastUop1 = outer.wbArbiter.intConnections.map(c => intFastUop(c.head)) 315 val fpFastUop1 = outer.wbArbiter.fpConnections.map(c => fpFastUop(c.head)) 316 val allFastUop1 = intFastUop1 ++ fpFastUop1 317 318 ctrlBlock.io.dispatch <> exuBlocks.flatMap(_.io.in) 319 320 exuBlocks(0).io.scheExtra.fpRfReadIn.get <> exuBlocks(1).io.scheExtra.fpRfReadOut.get 321 exuBlocks(0).io.scheExtra.fpStateReadIn.get <> exuBlocks(1).io.scheExtra.fpStateReadOut.get 322 323 memBlock.io.issue <> exuBlocks(0).io.issue.get 324 // By default, instructions do not have exceptions when they enter the function units. 325 memBlock.io.issue.map(_.bits.uop.clearExceptions()) 326 exuBlocks(0).io.scheExtra.loadFastMatch.get <> memBlock.io.loadFastMatch 327 328 val stdIssue = exuBlocks(0).io.issue.get.takeRight(exuParameters.StuCnt) 329 exuBlocks.map(_.io).foreach { exu => 330 exu.redirect <> ctrlBlock.io.redirect 331 exu.allocPregs <> ctrlBlock.io.allocPregs 332 exu.rfWriteback <> rfWriteback 333 exu.fastUopIn <> allFastUop1 334 exu.scheExtra.jumpPc <> ctrlBlock.io.jumpPc 335 exu.scheExtra.jalr_target <> ctrlBlock.io.jalr_target 336 exu.scheExtra.stIssuePtr <> memBlock.io.stIssuePtr 337 exu.scheExtra.debug_fp_rat <> ctrlBlock.io.debug_fp_rat 338 exu.scheExtra.debug_int_rat <> ctrlBlock.io.debug_int_rat 339 exu.scheExtra.memWaitUpdateReq.staIssue.zip(memBlock.io.stIn).foreach{case (sink, src) => { 340 sink.bits := src.bits 341 sink.valid := src.valid 342 }} 343 exu.scheExtra.memWaitUpdateReq.stdIssue.zip(stdIssue).foreach{case (sink, src) => { 344 sink.valid := src.valid 345 sink.bits := src.bits 346 }} 347 } 348 XSPerfHistogram("fastIn_count", PopCount(allFastUop1.map(_.valid)), true.B, 0, allFastUop1.length, 1) 349 XSPerfHistogram("wakeup_count", PopCount(rfWriteback.map(_.valid)), true.B, 0, rfWriteback.length, 1) 350 351 ctrlBlock.perfinfo.perfEventsEu0 := exuBlocks(0).getPerf.dropRight(outer.exuBlocks(0).scheduler.numRs) 352 ctrlBlock.perfinfo.perfEventsEu1 := exuBlocks(1).getPerf.dropRight(outer.exuBlocks(1).scheduler.numRs) 353 memBlock.io.perfEventsPTW := ptw.getPerf 354 ctrlBlock.perfinfo.perfEventsRs := outer.exuBlocks.flatMap(b => b.module.getPerf.takeRight(b.scheduler.numRs)) 355 356 csrioIn.hartId <> io.hartId 357 csrioIn.perf <> DontCare 358 csrioIn.perf.retiredInstr <> ctrlBlock.io.robio.toCSR.perfinfo.retiredInstr 359 csrioIn.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo 360 csrioIn.perf.memInfo <> memBlock.io.memInfo 361 csrioIn.perf.frontendInfo <> frontend.io.frontendInfo 362 363 csrioIn.perf.perfEventsFrontend <> frontend.getPerf 364 csrioIn.perf.perfEventsCtrl <> ctrlBlock.getPerf 365 csrioIn.perf.perfEventsLsu <> memBlock.getPerf 366 csrioIn.perf.perfEventsHc <> io.perfEvents 367 368 csrioIn.fpu.fflags <> ctrlBlock.io.robio.toCSR.fflags 369 csrioIn.fpu.isIllegal := false.B 370 csrioIn.fpu.dirty_fs <> ctrlBlock.io.robio.toCSR.dirty_fs 371 csrioIn.fpu.frm <> exuBlocks(1).io.fuExtra.frm.get 372 csrioIn.exception <> ctrlBlock.io.robio.exception 373 csrioIn.isXRet <> ctrlBlock.io.robio.toCSR.isXRet 374 csrioIn.trapTarget <> ctrlBlock.io.robio.toCSR.trapTarget 375 csrioIn.interrupt <> ctrlBlock.io.robio.toCSR.intrBitSet 376 csrioIn.wfi_event <> ctrlBlock.io.robio.toCSR.wfiEvent 377 csrioIn.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr 378 379 csrioIn.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0) 380 csrioIn.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1) 381 csrioIn.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0) 382 csrioIn.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0) 383 csrioIn.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0) 384 385 csrioIn.distributedUpdate(0).w.valid := memBlock.io.csrUpdate.w.valid 386 csrioIn.distributedUpdate(0).w.bits := memBlock.io.csrUpdate.w.bits 387 csrioIn.distributedUpdate(1).w.valid := frontend.io.csrUpdate.w.valid 388 csrioIn.distributedUpdate(1).w.bits := frontend.io.csrUpdate.w.bits 389 390 fenceio.sfence <> memBlock.io.sfence 391 fenceio.sbuffer <> memBlock.io.fenceToSbuffer 392 393 memBlock.io.redirect <> ctrlBlock.io.redirect 394 memBlock.io.rsfeedback <> exuBlocks(0).io.scheExtra.feedback.get 395 memBlock.io.csrCtrl <> csrioIn.customCtrl 396 memBlock.io.tlbCsr <> csrioIn.tlb 397 memBlock.io.lsqio.rob <> ctrlBlock.io.robio.lsq 398 memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.robio.exception.bits.uop.ctrl.commitType) 399 400 val itlbRepeater1 = PTWRepeater(frontend.io.ptw, fenceio.sfence, csrioIn.tlb) 401 val itlbRepeater2 = PTWRepeater(itlbRepeater1.io.ptw, ptw.io.tlb(0), fenceio.sfence, csrioIn.tlb) 402 val dtlbRepeater1 = PTWFilter(memBlock.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.filterSize) 403 val dtlbRepeater2 = PTWRepeaterNB(passReady = false, dtlbRepeater1.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb) 404 ptw.io.sfence <> fenceio.sfence 405 ptw.io.csr.tlb <> csrioIn.tlb 406 ptw.io.csr.distribute_csr <> csrioIn.customCtrl.distribute_csr 407 408 // if l2 prefetcher use stream prefetch, it should be placed in XSCore 409 io.l2_pf_enable := csrioIn.customCtrl.l2_pf_enable 410 411 // Modules are reset one by one 412 val resetTree = ResetGenNode( 413 Seq( 414 ModuleNode(memBlock), ModuleNode(dtlbRepeater1), 415 ResetGenNode(Seq( 416 ModuleNode(itlbRepeater2), 417 ModuleNode(ptw), 418 ModuleNode(dtlbRepeater2), 419 ModuleNode(ptw_to_l2_buffer), 420 )), 421 ResetGenNode(Seq( 422 ModuleNode(exuBlocks.head), 423 ResetGenNode( 424 exuBlocks.tail.map(m => ModuleNode(m)) :+ ModuleNode(outer.wbArbiter.module) 425 ), 426 ResetGenNode(Seq( 427 ModuleNode(ctrlBlock), 428 ResetGenNode(Seq( 429 ModuleNode(frontend), ModuleNode(itlbRepeater1) 430 )) 431 )) 432 )) 433 ) 434 ) 435 436 ResetGen(resetTree, reset.asBool, !debugOpts.FPGAPlatform) 437 438} 439