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