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