1*4e12f40bSzhanglinjuan/*************************************************************************************** 2*4e12f40bSzhanglinjuan* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*4e12f40bSzhanglinjuan* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*4e12f40bSzhanglinjuan* 5*4e12f40bSzhanglinjuan* XiangShan is licensed under Mulan PSL v2. 6*4e12f40bSzhanglinjuan* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*4e12f40bSzhanglinjuan* You may obtain a copy of Mulan PSL v2 at: 8*4e12f40bSzhanglinjuan* http://license.coscl.org.cn/MulanPSL2 9*4e12f40bSzhanglinjuan* 10*4e12f40bSzhanglinjuan* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*4e12f40bSzhanglinjuan* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*4e12f40bSzhanglinjuan* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*4e12f40bSzhanglinjuan* 14*4e12f40bSzhanglinjuan* See the Mulan PSL v2 for more details. 15*4e12f40bSzhanglinjuan***************************************************************************************/ 16*4e12f40bSzhanglinjuan 17*4e12f40bSzhanglinjuanpackage xiangshan.backend 18*4e12f40bSzhanglinjuan 19*4e12f40bSzhanglinjuanimport org.chipsalliance.cde.config.Parameters 20*4e12f40bSzhanglinjuanimport chisel3._ 21*4e12f40bSzhanglinjuanimport chisel3.util._ 22*4e12f40bSzhanglinjuanimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 23*4e12f40bSzhanglinjuanimport utils._ 24*4e12f40bSzhanglinjuanimport utility._ 25*4e12f40bSzhanglinjuanimport xiangshan._ 26*4e12f40bSzhanglinjuanimport xiangshan.backend.exu._ 27*4e12f40bSzhanglinjuanimport xiangshan.backend.fu._ 28*4e12f40bSzhanglinjuanimport xiangshan.backend.rob._ 29*4e12f40bSzhanglinjuanimport xiangshan.backend.dispatch._ 30*4e12f40bSzhanglinjuanimport xiangshan.mem._ 31*4e12f40bSzhanglinjuan 32*4e12f40bSzhanglinjuanclass FakeMemBlockWbSource()(implicit p: Parameters) extends LazyModule 33*4e12f40bSzhanglinjuan with HasXSParameter with HasWritebackSource { 34*4e12f40bSzhanglinjuan lazy val module = new FakeMemBlockWbSourceImp(this) 35*4e12f40bSzhanglinjuan 36*4e12f40bSzhanglinjuan override val writebackSourceParams: Seq[WritebackSourceParams] = { 37*4e12f40bSzhanglinjuan val params = new WritebackSourceParams 38*4e12f40bSzhanglinjuan params.exuConfigs = (loadExuConfigs ++ storeExuConfigs).map(cfg => Seq(cfg)) 39*4e12f40bSzhanglinjuan Seq(params) 40*4e12f40bSzhanglinjuan } 41*4e12f40bSzhanglinjuan override lazy val writebackSourceImp: HasWritebackSourceImp = module 42*4e12f40bSzhanglinjuan} 43*4e12f40bSzhanglinjuan 44*4e12f40bSzhanglinjuanclass FakeMemBlockWbSourceImp(outer: FakeMemBlockWbSource) extends LazyModuleImp(outer) 45*4e12f40bSzhanglinjuan with HasXSParameter 46*4e12f40bSzhanglinjuan with HasWritebackSourceImp 47*4e12f40bSzhanglinjuan{ 48*4e12f40bSzhanglinjuan val io = IO(new Bundle() { 49*4e12f40bSzhanglinjuan val in = Vec(exuParameters.LsExuCnt + exuParameters.StuCnt, Flipped(DecoupledIO(new ExuOutput))) 50*4e12f40bSzhanglinjuan val out = Vec(exuParameters.LsExuCnt + exuParameters.StuCnt, DecoupledIO(new ExuOutput)) 51*4e12f40bSzhanglinjuan }) 52*4e12f40bSzhanglinjuan override def writebackSource1: Option[Seq[Seq[DecoupledIO[ExuOutput]]]] = Some(Seq(io.out)) 53*4e12f40bSzhanglinjuan io.out <> io.in 54*4e12f40bSzhanglinjuan} 55*4e12f40bSzhanglinjuan 56*4e12f40bSzhanglinjuan// Merge CtrlBlock, exuBlocks, wbArbiter, wb2Ctrl, etc into 1 module 57*4e12f40bSzhanglinjuanclass Backend(memWbSource: HasWritebackSource)(implicit p: Parameters) extends LazyModule 58*4e12f40bSzhanglinjuan with HasXSParameter 59*4e12f40bSzhanglinjuan with HasExuWbHelper 60*4e12f40bSzhanglinjuan{ 61*4e12f40bSzhanglinjuan val wbArbiter = LazyModule(new WbArbiterWrapper(exuConfigs, NRIntWritePorts, NRFpWritePorts)) 62*4e12f40bSzhanglinjuan val intWbPorts = wbArbiter.intWbPorts 63*4e12f40bSzhanglinjuan val fpWbPorts = wbArbiter.fpWbPorts 64*4e12f40bSzhanglinjuan 65*4e12f40bSzhanglinjuan // TODO: better RS organization 66*4e12f40bSzhanglinjuan // generate rs according to number of function units 67*4e12f40bSzhanglinjuan require(exuParameters.JmpCnt == 1) 68*4e12f40bSzhanglinjuan require(exuParameters.MduCnt <= exuParameters.AluCnt && exuParameters.MduCnt > 0) 69*4e12f40bSzhanglinjuan require(exuParameters.FmiscCnt <= exuParameters.FmacCnt && exuParameters.FmiscCnt > 0) 70*4e12f40bSzhanglinjuan require(exuParameters.LduCnt == exuParameters.StuCnt) // TODO: remove this limitation 71*4e12f40bSzhanglinjuan 72*4e12f40bSzhanglinjuan // one RS every 2 MDUs 73*4e12f40bSzhanglinjuan val schedulePorts = Seq( 74*4e12f40bSzhanglinjuan // exuCfg, numDeq, intFastWakeupTarget, fpFastWakeupTarget 75*4e12f40bSzhanglinjuan Seq( 76*4e12f40bSzhanglinjuan (AluExeUnitCfg, exuParameters.AluCnt, Seq(AluExeUnitCfg, LdExeUnitCfg, StaExeUnitCfg), Seq()), 77*4e12f40bSzhanglinjuan (MulDivExeUnitCfg, exuParameters.MduCnt, Seq(AluExeUnitCfg, MulDivExeUnitCfg), Seq()), 78*4e12f40bSzhanglinjuan (JumpCSRExeUnitCfg, 1, Seq(), Seq()), 79*4e12f40bSzhanglinjuan (LdExeUnitCfg, exuParameters.LduCnt, Seq(AluExeUnitCfg, LdExeUnitCfg), Seq()), 80*4e12f40bSzhanglinjuan (StaExeUnitCfg, exuParameters.StuCnt, Seq(), Seq()), 81*4e12f40bSzhanglinjuan (StdExeUnitCfg, exuParameters.StuCnt, Seq(), Seq()) 82*4e12f40bSzhanglinjuan ), 83*4e12f40bSzhanglinjuan Seq( 84*4e12f40bSzhanglinjuan (FmacExeUnitCfg, exuParameters.FmacCnt, Seq(), Seq(FmacExeUnitCfg, FmiscExeUnitCfg)), 85*4e12f40bSzhanglinjuan (FmiscExeUnitCfg, exuParameters.FmiscCnt, Seq(), Seq()) 86*4e12f40bSzhanglinjuan ) 87*4e12f40bSzhanglinjuan ) 88*4e12f40bSzhanglinjuan 89*4e12f40bSzhanglinjuan // should do outer fast wakeup ports here 90*4e12f40bSzhanglinjuan val otherFastPorts = schedulePorts.zipWithIndex.map { case (sche, i) => 91*4e12f40bSzhanglinjuan val otherCfg = schedulePorts.zipWithIndex.filter(_._2 != i).map(_._1).reduce(_ ++ _) 92*4e12f40bSzhanglinjuan val outerPorts = sche.map(cfg => { 93*4e12f40bSzhanglinjuan // exe units from this scheduler need fastUops from exeunits 94*4e12f40bSzhanglinjuan val outerWakeupInSche = sche.filter(_._1.wakeupFromExu) 95*4e12f40bSzhanglinjuan val intraIntScheOuter = outerWakeupInSche.filter(_._3.contains(cfg._1)).map(_._1) 96*4e12f40bSzhanglinjuan val intraFpScheOuter = outerWakeupInSche.filter(_._4.contains(cfg._1)).map(_._1) 97*4e12f40bSzhanglinjuan // exe units from other schedulers need fastUop from outside 98*4e12f40bSzhanglinjuan val otherIntSource = otherCfg.filter(_._3.contains(cfg._1)).map(_._1) 99*4e12f40bSzhanglinjuan val otherFpSource = otherCfg.filter(_._4.contains(cfg._1)).map(_._1) 100*4e12f40bSzhanglinjuan val intSource = findInWbPorts(intWbPorts, intraIntScheOuter ++ otherIntSource) 101*4e12f40bSzhanglinjuan val fpSource = findInWbPorts(fpWbPorts, intraFpScheOuter ++ otherFpSource) 102*4e12f40bSzhanglinjuan getFastWakeupIndex(cfg._1, intSource, fpSource, intWbPorts.length).sorted 103*4e12f40bSzhanglinjuan }) 104*4e12f40bSzhanglinjuan println(s"inter-scheduler wakeup sources for $i: $outerPorts") 105*4e12f40bSzhanglinjuan outerPorts 106*4e12f40bSzhanglinjuan } 107*4e12f40bSzhanglinjuan 108*4e12f40bSzhanglinjuan // allow mdu and fmisc to have 2*numDeq enqueue ports 109*4e12f40bSzhanglinjuan val intDpPorts = (0 until exuParameters.AluCnt).map(i => { 110*4e12f40bSzhanglinjuan if (i < exuParameters.JmpCnt) Seq((0, i), (1, i), (2, i)) 111*4e12f40bSzhanglinjuan else if (i < 2 * exuParameters.MduCnt) Seq((0, i), (1, i)) 112*4e12f40bSzhanglinjuan else Seq((0, i)) 113*4e12f40bSzhanglinjuan }) 114*4e12f40bSzhanglinjuan val lsDpPorts = (0 until exuParameters.LduCnt).map(i => Seq((3, i))) ++ 115*4e12f40bSzhanglinjuan (0 until exuParameters.StuCnt).map(i => Seq((4, i))) ++ 116*4e12f40bSzhanglinjuan (0 until exuParameters.StuCnt).map(i => Seq((5, i))) 117*4e12f40bSzhanglinjuan val fpDpPorts = (0 until exuParameters.FmacCnt).map(i => { 118*4e12f40bSzhanglinjuan if (i < 2 * exuParameters.FmiscCnt) Seq((0, i), (1, i)) 119*4e12f40bSzhanglinjuan else Seq((0, i)) 120*4e12f40bSzhanglinjuan }) 121*4e12f40bSzhanglinjuan 122*4e12f40bSzhanglinjuan val dispatchPorts = Seq(intDpPorts ++ lsDpPorts, fpDpPorts) 123*4e12f40bSzhanglinjuan 124*4e12f40bSzhanglinjuan val outIntRfReadPorts = Seq(0, 0) 125*4e12f40bSzhanglinjuan val outFpRfReadPorts = Seq(0, StorePipelineWidth) 126*4e12f40bSzhanglinjuan val hasIntRf = Seq(true, false) 127*4e12f40bSzhanglinjuan val hasFpRf = Seq(false, true) 128*4e12f40bSzhanglinjuan 129*4e12f40bSzhanglinjuan val exuBlocks = schedulePorts.zip(dispatchPorts).zip(otherFastPorts).zipWithIndex.map { 130*4e12f40bSzhanglinjuan case (((sche, disp), other), i) => 131*4e12f40bSzhanglinjuan LazyModule(new ExuBlock(sche, disp, intWbPorts, fpWbPorts, other, outIntRfReadPorts(i), outFpRfReadPorts(i), hasIntRf(i), hasFpRf(i))) 132*4e12f40bSzhanglinjuan } 133*4e12f40bSzhanglinjuan 134*4e12f40bSzhanglinjuan val fakeMemBlockWbSource = LazyModule(new FakeMemBlockWbSource()) 135*4e12f40bSzhanglinjuan 136*4e12f40bSzhanglinjuan val wb2Ctrl = LazyModule(new Wb2Ctrl(exuConfigs)) 137*4e12f40bSzhanglinjuan wb2Ctrl.addWritebackSink(exuBlocks :+ fakeMemBlockWbSource) 138*4e12f40bSzhanglinjuan val dpExuConfigs = exuBlocks.flatMap(_.scheduler.dispatch2.map(_.configs)) 139*4e12f40bSzhanglinjuan val ctrlBlock = LazyModule(new CtrlBlock(dpExuConfigs)) 140*4e12f40bSzhanglinjuan val writebackSources = Seq(Seq(wb2Ctrl), Seq(wbArbiter)) 141*4e12f40bSzhanglinjuan writebackSources.foreach(s => ctrlBlock.addWritebackSink(s)) 142*4e12f40bSzhanglinjuan 143*4e12f40bSzhanglinjuan lazy val module = new BackendImp(this) 144*4e12f40bSzhanglinjuan} 145*4e12f40bSzhanglinjuan 146*4e12f40bSzhanglinjuanclass BackendImp(outer: Backend)(implicit p: Parameters) extends LazyModuleImp(outer) 147*4e12f40bSzhanglinjuan with HasXSParameter 148*4e12f40bSzhanglinjuan{ 149*4e12f40bSzhanglinjuan val io = IO(new Bundle() { 150*4e12f40bSzhanglinjuan val hartId = Input(UInt(64.W)) 151*4e12f40bSzhanglinjuan val cpu_halt = Output(Bool()) 152*4e12f40bSzhanglinjuan 153*4e12f40bSzhanglinjuan val memBlock = new Bundle() { // TODO: use class 154*4e12f40bSzhanglinjuan val redirect = ValidIO(new Redirect) 155*4e12f40bSzhanglinjuan val issue = Vec(exuParameters.LsExuCnt + exuParameters.StuCnt, DecoupledIO(new ExuInput)) 156*4e12f40bSzhanglinjuan val loadFastMatch = Vec(exuParameters.LduCnt, Output(UInt(exuParameters.LduCnt.W))) 157*4e12f40bSzhanglinjuan val loadFastFuOpType = Vec(exuParameters.LduCnt, Output(FuOpType())) 158*4e12f40bSzhanglinjuan val loadFastImm = Vec(exuParameters.LduCnt, Output(UInt(12.W))) 159*4e12f40bSzhanglinjuan val rsfeedback = Vec(exuParameters.LsExuCnt, Flipped(new MemRSFeedbackIO()(p.alter((site, here, up) => { 160*4e12f40bSzhanglinjuan case XSCoreParamsKey => up(XSCoreParamsKey).copy( 161*4e12f40bSzhanglinjuan IssQueSize = IssQueSize * 2 162*4e12f40bSzhanglinjuan ) 163*4e12f40bSzhanglinjuan })))) 164*4e12f40bSzhanglinjuan val loadPc = Vec(exuParameters.LduCnt, Output(UInt(VAddrBits.W))) 165*4e12f40bSzhanglinjuan val storePc = Vec(exuParameters.StuCnt, Output(UInt(VAddrBits.W))) 166*4e12f40bSzhanglinjuan val stIssuePtr = Input(new SqPtr()) 167*4e12f40bSzhanglinjuan val writeback = Vec(exuParameters.LsExuCnt + exuParameters.StuCnt, Flipped(DecoupledIO(new ExuOutput))) 168*4e12f40bSzhanglinjuan val s3_delayed_load_error = Vec(exuParameters.LduCnt, Input(Bool())) 169*4e12f40bSzhanglinjuan val otherFastWakeup = Vec(exuParameters.LduCnt + 2 * exuParameters.StuCnt, Flipped(ValidIO(new MicroOp))) 170*4e12f40bSzhanglinjuan val stIn = Vec(exuParameters.StuCnt, Flipped(ValidIO(new ExuInput))) 171*4e12f40bSzhanglinjuan val memoryViolation = Flipped(ValidIO(new Redirect)) 172*4e12f40bSzhanglinjuan val sfence = Output(new SfenceBundle) 173*4e12f40bSzhanglinjuan val tlbCsr = Output(new TlbCsrBundle) 174*4e12f40bSzhanglinjuan val fenceToSbuffer = new FenceToSbuffer 175*4e12f40bSzhanglinjuan val enqLsq = Flipped(new LsqEnqIO) 176*4e12f40bSzhanglinjuan val lsqio = new Bundle { 177*4e12f40bSzhanglinjuan val exceptionAddr = Flipped(new ExceptionAddrIO) // to csr 178*4e12f40bSzhanglinjuan val rob = new RobLsqIO // rob to lsq 179*4e12f40bSzhanglinjuan val lqCanAccept = Input(Bool()) 180*4e12f40bSzhanglinjuan val sqCanAccept = Input(Bool()) 181*4e12f40bSzhanglinjuan } 182*4e12f40bSzhanglinjuan val csrCtrl = new CustomCSRCtrlIO 183*4e12f40bSzhanglinjuan val lqCancelCnt = Input(UInt(log2Up(VirtualLoadQueueSize + 1).W)) 184*4e12f40bSzhanglinjuan val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 185*4e12f40bSzhanglinjuan val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) 186*4e12f40bSzhanglinjuan val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 187*4e12f40bSzhanglinjuan val debug_ls = Flipped(new DebugLSIO) 188*4e12f40bSzhanglinjuan val lsTopdownInfo = Vec(exuParameters.LduCnt, Input(new LsTopdownInfo)) 189*4e12f40bSzhanglinjuan } 190*4e12f40bSzhanglinjuan 191*4e12f40bSzhanglinjuan val frontend = new Bundle() { // TODO: use class 192*4e12f40bSzhanglinjuan val frontend2Ctrl = Flipped(new FrontendToCtrlIO) 193*4e12f40bSzhanglinjuan val sfence = Output(new SfenceBundle) 194*4e12f40bSzhanglinjuan val tlbCsr = Output(new TlbCsrBundle) 195*4e12f40bSzhanglinjuan val csrCtrl = Output(new CustomCSRCtrlIO) 196*4e12f40bSzhanglinjuan val fencei = Output(Bool()) 197*4e12f40bSzhanglinjuan } 198*4e12f40bSzhanglinjuan 199*4e12f40bSzhanglinjuan // CSR related 200*4e12f40bSzhanglinjuan val perf = Input(new PerfCounterIO) 201*4e12f40bSzhanglinjuan val externalInterrupt = new ExternalInterruptIO 202*4e12f40bSzhanglinjuan val distributedUpdate = Vec(2, Flipped(new DistributedCSRUpdateReq)) 203*4e12f40bSzhanglinjuan 204*4e12f40bSzhanglinjuan val l2_pf_enable = Output(Bool()) 205*4e12f40bSzhanglinjuan 206*4e12f40bSzhanglinjuan val debugTopDown = new Bundle { 207*4e12f40bSzhanglinjuan val fromRob = new RobCoreTopDownIO 208*4e12f40bSzhanglinjuan val fromCore = new CoreDispatchTopDownIO 209*4e12f40bSzhanglinjuan } 210*4e12f40bSzhanglinjuan val debugRolling = new RobDebugRollingIO 211*4e12f40bSzhanglinjuan }) 212*4e12f40bSzhanglinjuan 213*4e12f40bSzhanglinjuan private val ctrlBlock = outer.ctrlBlock.module 214*4e12f40bSzhanglinjuan private val wb2Ctrl = outer.wb2Ctrl.module 215*4e12f40bSzhanglinjuan private val exuBlocks = outer.exuBlocks.map(_.module) 216*4e12f40bSzhanglinjuan private val wbArbiter = outer.wbArbiter.module 217*4e12f40bSzhanglinjuan 218*4e12f40bSzhanglinjuan val mem = io.memBlock 219*4e12f40bSzhanglinjuan val frontend = io.frontend 220*4e12f40bSzhanglinjuan 221*4e12f40bSzhanglinjuan outer.fakeMemBlockWbSource.module.io.in <> mem.writeback 222*4e12f40bSzhanglinjuan 223*4e12f40bSzhanglinjuan ctrlBlock.io.hartId := io.hartId 224*4e12f40bSzhanglinjuan exuBlocks.foreach(_.io.hartId := io.hartId) 225*4e12f40bSzhanglinjuan wbArbiter.io.hartId := io.hartId 226*4e12f40bSzhanglinjuan 227*4e12f40bSzhanglinjuan io.cpu_halt := ctrlBlock.io.cpu_halt 228*4e12f40bSzhanglinjuan 229*4e12f40bSzhanglinjuan wbArbiter.io.redirect <> ctrlBlock.io.redirect 230*4e12f40bSzhanglinjuan 231*4e12f40bSzhanglinjuan val allWriteback = exuBlocks.flatMap(_.io.fuWriteback) ++ outer.fakeMemBlockWbSource.module.io.out 232*4e12f40bSzhanglinjuan require(exuConfigs.length == allWriteback.length, s"${exuConfigs.length} != ${allWriteback.length}") 233*4e12f40bSzhanglinjuan wbArbiter.io.in <> allWriteback 234*4e12f40bSzhanglinjuan val rfWriteback = wbArbiter.io.out 235*4e12f40bSzhanglinjuan 236*4e12f40bSzhanglinjuan // memblock error exception writeback, 1 cycle after normal writeback 237*4e12f40bSzhanglinjuan wb2Ctrl.io.s3_delayed_load_error <> mem.s3_delayed_load_error 238*4e12f40bSzhanglinjuan 239*4e12f40bSzhanglinjuan wb2Ctrl.io.redirect <> ctrlBlock.io.redirect 240*4e12f40bSzhanglinjuan outer.wb2Ctrl.generateWritebackIO() 241*4e12f40bSzhanglinjuan 242*4e12f40bSzhanglinjuan require(exuBlocks.count(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)) == 1) 243*4e12f40bSzhanglinjuan val csrFenceMod = exuBlocks.filter(_.fuConfigs.map(_._1).contains(JumpCSRExeUnitCfg)).head 244*4e12f40bSzhanglinjuan val csrioIn = csrFenceMod.io.fuExtra.csrio.get 245*4e12f40bSzhanglinjuan val fenceio = csrFenceMod.io.fuExtra.fenceio.get 246*4e12f40bSzhanglinjuan 247*4e12f40bSzhanglinjuan ctrlBlock.io.frontend <> frontend.frontend2Ctrl 248*4e12f40bSzhanglinjuan frontend.sfence <> fenceio.sfence 249*4e12f40bSzhanglinjuan frontend.tlbCsr <> csrioIn.tlb 250*4e12f40bSzhanglinjuan frontend.csrCtrl <> csrioIn.customCtrl 251*4e12f40bSzhanglinjuan frontend.fencei := fenceio.fencei 252*4e12f40bSzhanglinjuan 253*4e12f40bSzhanglinjuan ctrlBlock.io.csrCtrl <> csrioIn.customCtrl 254*4e12f40bSzhanglinjuan val redirectBlocks = exuBlocks.reverse.filter(_.fuConfigs.map(_._1).map(_.hasRedirect).reduce(_ || _)) 255*4e12f40bSzhanglinjuan ctrlBlock.io.exuRedirect <> redirectBlocks.flatMap(_.io.fuExtra.exuRedirect) 256*4e12f40bSzhanglinjuan ctrlBlock.io.stIn <> mem.stIn 257*4e12f40bSzhanglinjuan ctrlBlock.io.memoryViolation <> mem.memoryViolation 258*4e12f40bSzhanglinjuan exuBlocks.head.io.scheExtra.enqLsq.get <> mem.enqLsq 259*4e12f40bSzhanglinjuan exuBlocks.foreach(b => { 260*4e12f40bSzhanglinjuan b.io.scheExtra.lcommit := mem.lcommit 261*4e12f40bSzhanglinjuan b.io.scheExtra.scommit := mem.scommit 262*4e12f40bSzhanglinjuan b.io.scheExtra.lqCancelCnt := mem.lqCancelCnt 263*4e12f40bSzhanglinjuan b.io.scheExtra.sqCancelCnt := mem.sqCancelCnt 264*4e12f40bSzhanglinjuan }) 265*4e12f40bSzhanglinjuan val sourceModules = outer.writebackSources.map(_.map(_.module.asInstanceOf[HasWritebackSourceImp])) 266*4e12f40bSzhanglinjuan outer.ctrlBlock.generateWritebackIO() 267*4e12f40bSzhanglinjuan 268*4e12f40bSzhanglinjuan val allFastUop = exuBlocks.flatMap(b => b.io.fastUopOut.dropRight(b.numOutFu)) ++ mem.otherFastWakeup 269*4e12f40bSzhanglinjuan require(allFastUop.length == exuConfigs.length, s"${allFastUop.length} != ${exuConfigs.length}") 270*4e12f40bSzhanglinjuan val intFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeIntRf).map(_._1) 271*4e12f40bSzhanglinjuan val fpFastUop = allFastUop.zip(exuConfigs).filter(_._2.writeFpRf).map(_._1) 272*4e12f40bSzhanglinjuan val intFastUop1 = outer.wbArbiter.intConnections.map(c => intFastUop(c.head)) 273*4e12f40bSzhanglinjuan val fpFastUop1 = outer.wbArbiter.fpConnections.map(c => fpFastUop(c.head)) 274*4e12f40bSzhanglinjuan val allFastUop1 = intFastUop1 ++ fpFastUop1 275*4e12f40bSzhanglinjuan 276*4e12f40bSzhanglinjuan ctrlBlock.io.dispatch <> exuBlocks.flatMap(_.io.in) 277*4e12f40bSzhanglinjuan ctrlBlock.io.rsReady := exuBlocks.flatMap(_.io.scheExtra.rsReady) 278*4e12f40bSzhanglinjuan ctrlBlock.io.enqLsq <> mem.enqLsq 279*4e12f40bSzhanglinjuan ctrlBlock.io.lqDeq := mem.lcommit 280*4e12f40bSzhanglinjuan ctrlBlock.io.sqDeq := mem.scommit 281*4e12f40bSzhanglinjuan ctrlBlock.io.lqCanAccept := mem.lsqio.lqCanAccept 282*4e12f40bSzhanglinjuan ctrlBlock.io.sqCanAccept := mem.lsqio.sqCanAccept 283*4e12f40bSzhanglinjuan ctrlBlock.io.lqCancelCnt := mem.lqCancelCnt 284*4e12f40bSzhanglinjuan ctrlBlock.io.sqCancelCnt := mem.sqCancelCnt 285*4e12f40bSzhanglinjuan ctrlBlock.io.robHeadLsIssue := exuBlocks.map(_.io.scheExtra.robHeadLsIssue).reduce(_ || _) 286*4e12f40bSzhanglinjuan 287*4e12f40bSzhanglinjuan exuBlocks(0).io.scheExtra.fpRfReadIn.get <> exuBlocks(1).io.scheExtra.fpRfReadOut.get 288*4e12f40bSzhanglinjuan exuBlocks(0).io.scheExtra.fpStateReadIn.get <> exuBlocks(1).io.scheExtra.fpStateReadOut.get 289*4e12f40bSzhanglinjuan 290*4e12f40bSzhanglinjuan for((c, e) <- ctrlBlock.io.ld_pc_read.zip(exuBlocks(0).io.issue.get)){ 291*4e12f40bSzhanglinjuan // read load pc at load s0 292*4e12f40bSzhanglinjuan c.ptr := e.bits.uop.cf.ftqPtr 293*4e12f40bSzhanglinjuan c.offset := e.bits.uop.cf.ftqOffset 294*4e12f40bSzhanglinjuan } 295*4e12f40bSzhanglinjuan // return load pc at load s2 296*4e12f40bSzhanglinjuan mem.loadPc <> VecInit(ctrlBlock.io.ld_pc_read.map(_.data)) 297*4e12f40bSzhanglinjuan 298*4e12f40bSzhanglinjuan for((c, e) <- ctrlBlock.io.st_pc_read.zip(exuBlocks(0).io.issue.get.drop(exuParameters.LduCnt))){ 299*4e12f40bSzhanglinjuan // read store pc at store s0 300*4e12f40bSzhanglinjuan c.ptr := e.bits.uop.cf.ftqPtr 301*4e12f40bSzhanglinjuan c.offset := e.bits.uop.cf.ftqOffset 302*4e12f40bSzhanglinjuan } 303*4e12f40bSzhanglinjuan // return store pc at store s2 304*4e12f40bSzhanglinjuan mem.storePc <> VecInit(ctrlBlock.io.st_pc_read.map(_.data)) 305*4e12f40bSzhanglinjuan 306*4e12f40bSzhanglinjuan mem.issue <> exuBlocks(0).io.issue.get 307*4e12f40bSzhanglinjuan // By default, instructions do not have exceptions when they enter the function units. 308*4e12f40bSzhanglinjuan mem.issue.map(_.bits.uop.clearExceptions()) 309*4e12f40bSzhanglinjuan exuBlocks(0).io.scheExtra.loadFastMatch.get <> mem.loadFastMatch 310*4e12f40bSzhanglinjuan exuBlocks(0).io.scheExtra.loadFastFuOpType.get <> mem.loadFastFuOpType 311*4e12f40bSzhanglinjuan exuBlocks(0).io.scheExtra.loadFastImm.get <> mem.loadFastImm 312*4e12f40bSzhanglinjuan 313*4e12f40bSzhanglinjuan val stdIssue = exuBlocks(0).io.issue.get.takeRight(exuParameters.StuCnt) 314*4e12f40bSzhanglinjuan exuBlocks.map(_.io).foreach { exu => 315*4e12f40bSzhanglinjuan exu.redirect <> ctrlBlock.io.redirect 316*4e12f40bSzhanglinjuan exu.allocPregs <> ctrlBlock.io.allocPregs 317*4e12f40bSzhanglinjuan exu.rfWriteback <> rfWriteback 318*4e12f40bSzhanglinjuan exu.fastUopIn <> allFastUop1 319*4e12f40bSzhanglinjuan exu.scheExtra.jumpPc <> ctrlBlock.io.jumpPc 320*4e12f40bSzhanglinjuan exu.scheExtra.jalr_target <> ctrlBlock.io.jalr_target 321*4e12f40bSzhanglinjuan exu.scheExtra.stIssuePtr <> mem.stIssuePtr 322*4e12f40bSzhanglinjuan exu.scheExtra.debug_fp_rat <> ctrlBlock.io.debug_fp_rat 323*4e12f40bSzhanglinjuan exu.scheExtra.debug_int_rat <> ctrlBlock.io.debug_int_rat 324*4e12f40bSzhanglinjuan exu.scheExtra.robDeqPtr := ctrlBlock.io.robDeqPtr 325*4e12f40bSzhanglinjuan exu.scheExtra.memWaitUpdateReq.staIssue.zip(mem.stIn).foreach{case (sink, src) => { 326*4e12f40bSzhanglinjuan sink.bits := src.bits 327*4e12f40bSzhanglinjuan sink.valid := src.valid 328*4e12f40bSzhanglinjuan }} 329*4e12f40bSzhanglinjuan exu.scheExtra.memWaitUpdateReq.stdIssue.zip(stdIssue).foreach{case (sink, src) => { 330*4e12f40bSzhanglinjuan sink.valid := src.valid 331*4e12f40bSzhanglinjuan sink.bits := src.bits 332*4e12f40bSzhanglinjuan }} 333*4e12f40bSzhanglinjuan } 334*4e12f40bSzhanglinjuan 335*4e12f40bSzhanglinjuan XSPerfHistogram("fastIn_count", PopCount(allFastUop1.map(_.valid)), true.B, 0, allFastUop1.length, 1) 336*4e12f40bSzhanglinjuan XSPerfHistogram("wakeup_count", PopCount(rfWriteback.map(_.valid)), true.B, 0, rfWriteback.length, 1) 337*4e12f40bSzhanglinjuan 338*4e12f40bSzhanglinjuan ctrlBlock.perfinfo.perfEventsEu0 := exuBlocks(0).getPerf.dropRight(outer.exuBlocks(0).scheduler.numRs) 339*4e12f40bSzhanglinjuan ctrlBlock.perfinfo.perfEventsEu1 := exuBlocks(1).getPerf.dropRight(outer.exuBlocks(1).scheduler.numRs) 340*4e12f40bSzhanglinjuan ctrlBlock.perfinfo.perfEventsRs := outer.exuBlocks.flatMap(b => b.module.getPerf.takeRight(b.scheduler.numRs)) 341*4e12f40bSzhanglinjuan 342*4e12f40bSzhanglinjuan csrioIn.hartId <> io.hartId 343*4e12f40bSzhanglinjuan 344*4e12f40bSzhanglinjuan val perf = WireInit(io.perf) // other perf events are assigned outside the backend 345*4e12f40bSzhanglinjuan perf.retiredInstr <> ctrlBlock.io.robio.toCSR.perfinfo.retiredInstr 346*4e12f40bSzhanglinjuan perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo 347*4e12f40bSzhanglinjuan perf.perfEventsCtrl <> ctrlBlock.getPerf 348*4e12f40bSzhanglinjuan csrioIn.perf <> perf 349*4e12f40bSzhanglinjuan 350*4e12f40bSzhanglinjuan csrioIn.fpu.fflags <> ctrlBlock.io.robio.toCSR.fflags 351*4e12f40bSzhanglinjuan csrioIn.fpu.isIllegal := false.B 352*4e12f40bSzhanglinjuan csrioIn.fpu.dirty_fs <> ctrlBlock.io.robio.toCSR.dirty_fs 353*4e12f40bSzhanglinjuan csrioIn.fpu.frm <> exuBlocks(1).io.fuExtra.frm.get 354*4e12f40bSzhanglinjuan csrioIn.exception <> ctrlBlock.io.robio.exception 355*4e12f40bSzhanglinjuan csrioIn.isXRet <> ctrlBlock.io.robio.toCSR.isXRet 356*4e12f40bSzhanglinjuan csrioIn.trapTarget <> ctrlBlock.io.robio.toCSR.trapTarget 357*4e12f40bSzhanglinjuan csrioIn.interrupt <> ctrlBlock.io.robio.toCSR.intrBitSet 358*4e12f40bSzhanglinjuan csrioIn.wfi_event <> ctrlBlock.io.robio.toCSR.wfiEvent 359*4e12f40bSzhanglinjuan csrioIn.memExceptionVAddr <> mem.lsqio.exceptionAddr.vaddr 360*4e12f40bSzhanglinjuan 361*4e12f40bSzhanglinjuan csrioIn.externalInterrupt := io.externalInterrupt 362*4e12f40bSzhanglinjuan 363*4e12f40bSzhanglinjuan csrioIn.distributedUpdate := io.distributedUpdate 364*4e12f40bSzhanglinjuan 365*4e12f40bSzhanglinjuan mem.sfence <> fenceio.sfence 366*4e12f40bSzhanglinjuan mem.fenceToSbuffer <> fenceio.sbuffer 367*4e12f40bSzhanglinjuan 368*4e12f40bSzhanglinjuan mem.redirect <> ctrlBlock.io.redirect 369*4e12f40bSzhanglinjuan mem.rsfeedback <> exuBlocks(0).io.scheExtra.feedback.get 370*4e12f40bSzhanglinjuan mem.csrCtrl <> csrioIn.customCtrl 371*4e12f40bSzhanglinjuan mem.tlbCsr <> csrioIn.tlb 372*4e12f40bSzhanglinjuan mem.lsqio.rob <> ctrlBlock.io.robio.lsq 373*4e12f40bSzhanglinjuan mem.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.robio.exception.bits.uop.ctrl.commitType) 374*4e12f40bSzhanglinjuan mem.debug_ls <> ctrlBlock.io.robio.debug_ls 375*4e12f40bSzhanglinjuan mem.lsTopdownInfo <> ctrlBlock.io.robio.lsTopdownInfo 376*4e12f40bSzhanglinjuan 377*4e12f40bSzhanglinjuan // if l2 prefetcher use stream prefetch, it should be placed in XSCore 378*4e12f40bSzhanglinjuan io.l2_pf_enable := csrioIn.customCtrl.l2_pf_enable 379*4e12f40bSzhanglinjuan 380*4e12f40bSzhanglinjuan io.debugTopDown.fromRob := ctrlBlock.io.debugTopDown.fromRob 381*4e12f40bSzhanglinjuan ctrlBlock.io.debugTopDown.fromCore := io.debugTopDown.fromCore 382*4e12f40bSzhanglinjuan io.debugRolling := ctrlBlock.io.debugRolling 383*4e12f40bSzhanglinjuan 384*4e12f40bSzhanglinjuan val resetTree = ResetGenNode( 385*4e12f40bSzhanglinjuan exuBlocks.tail.map(m => ModuleNode(m)) 386*4e12f40bSzhanglinjuan :+ ModuleNode(wbArbiter) 387*4e12f40bSzhanglinjuan :+ ModuleNode(ctrlBlock) 388*4e12f40bSzhanglinjuan ) 389*4e12f40bSzhanglinjuan ResetGen(resetTree, reset, !p(DebugOptionsKey).FPGAPlatform) 390*4e12f40bSzhanglinjuan} 391