15d2b9cadSXuan Hupackage xiangshan.backend.datapath 25d2b9cadSXuan Hu 383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters 45d2b9cadSXuan Huimport chisel3._ 55d2b9cadSXuan Huimport chisel3.util._ 69c1b710eSZhaoyang Youimport utility.{GatedValidRegNext, SignExt, ZeroExt} 7a2fa0ad9Sxiaofeibaoimport xiangshan.{JumpOpType, SelImm, XSBundle, XSModule} 85d2b9cadSXuan Huimport xiangshan.backend.BackendParams 9f57d73d6Ssinsanctionimport xiangshan.backend.Bundles.{ExuBypassBundle, ExuInput, ExuOutput, ExuVec, ImmInfo} 10864480f4Sxiaofeibao-xjtuimport xiangshan.backend.issue.{FpScheduler, ImmExtractor, IntScheduler, MemScheduler, VfScheduler} 115d2b9cadSXuan Huimport xiangshan.backend.datapath.DataConfig.RegDataMaxWidth 12712a039eSxiaofeibao-xjtuimport xiangshan.backend.decode.ImmUnion 13f8b278aaSsinsanctionimport xiangshan.backend.regcache._ 14*0ed0e482SGuanghui Chengimport xiangshan.backend.Bundles._ 15a2fa0ad9Sxiaofeibaoimport xiangshan.backend.fu.FuType 165d2b9cadSXuan Hu 175d2b9cadSXuan Huclass BypassNetworkIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 185d2b9cadSXuan Hu // params 195d2b9cadSXuan Hu private val intSchdParams = params.schdParams(IntScheduler()) 2060f0c5aeSxiaofeibao private val fpSchdParams = params.schdParams(FpScheduler()) 215d2b9cadSXuan Hu private val vfSchdParams = params.schdParams(VfScheduler()) 225d2b9cadSXuan Hu private val memSchdParams = params.schdParams(MemScheduler()) 235d2b9cadSXuan Hu 245d2b9cadSXuan Hu val fromDataPath = new FromDataPath 255d2b9cadSXuan Hu val toExus = new ToExus 265d2b9cadSXuan Hu val fromExus = new FromExus 275d2b9cadSXuan Hu 285d2b9cadSXuan Hu class FromDataPath extends Bundle { 295d2b9cadSXuan Hu val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(intSchdParams.genExuInputBundle) 3060f0c5aeSxiaofeibao val fp : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(fpSchdParams.genExuInputBundle) 315d2b9cadSXuan Hu val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(vfSchdParams.genExuInputBundle) 325d2b9cadSXuan Hu val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(memSchdParams.genExuInputBundle) 33712a039eSxiaofeibao-xjtu val immInfo: Vec[ImmInfo] = Input(Vec(params.allExuParams.size, new ImmInfo)) 34102ba843Ssinsanction val rcData: MixedVec[MixedVec[Vec[UInt]]] = MixedVec( 35102ba843Ssinsanction Seq(intSchdParams, fpSchdParams, vfSchdParams, memSchdParams).map(schd => schd.issueBlockParams.map(iq => 36102ba843Ssinsanction MixedVec(iq.exuBlockParams.map(exu => Input(Vec(exu.numRegSrc, UInt(exu.srcDataBitsMax.W))))) 37102ba843Ssinsanction )).flatten 38102ba843Ssinsanction ) 395d2b9cadSXuan Hu } 405d2b9cadSXuan Hu 415d2b9cadSXuan Hu class ToExus extends Bundle { 42*0ed0e482SGuanghui Cheng val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = intSchdParams.genExuInputCopySrcBundle 43*0ed0e482SGuanghui Cheng val fp : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = fpSchdParams.genExuInputCopySrcBundle 44*0ed0e482SGuanghui Cheng val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = vfSchdParams.genExuInputCopySrcBundle 45*0ed0e482SGuanghui Cheng val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = memSchdParams.genExuInputCopySrcBundle 465d2b9cadSXuan Hu } 475d2b9cadSXuan Hu 485d2b9cadSXuan Hu class FromExus extends Bundle { 495d2b9cadSXuan Hu val int: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(intSchdParams.genExuBypassValidBundle) 5060f0c5aeSxiaofeibao val fp : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(fpSchdParams.genExuBypassValidBundle) 515d2b9cadSXuan Hu val vf : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(vfSchdParams.genExuBypassValidBundle) 525d2b9cadSXuan Hu val mem: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(memSchdParams.genExuBypassValidBundle) 535d2b9cadSXuan Hu 545d2b9cadSXuan Hu def connectExuOutput( 555d2b9cadSXuan Hu getSinkVecN: FromExus => MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] 565d2b9cadSXuan Hu )( 575d2b9cadSXuan Hu sourceVecN: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] 585d2b9cadSXuan Hu ): Unit = { 595d2b9cadSXuan Hu getSinkVecN(this).zip(sourceVecN).foreach { case (sinkVec, sourcesVec) => 605d2b9cadSXuan Hu sinkVec.zip(sourcesVec).foreach { case (sink, source) => 615d2b9cadSXuan Hu sink.valid := source.valid 62f8b278aaSsinsanction sink.bits.intWen := source.bits.intWen.getOrElse(false.B) 635d2b9cadSXuan Hu sink.bits.pdest := source.bits.pdest 64618b89e6Slewislzh sink.bits.data := source.bits.data(0) 655d2b9cadSXuan Hu } 665d2b9cadSXuan Hu } 675d2b9cadSXuan Hu } 685d2b9cadSXuan Hu } 69f8b278aaSsinsanction 70f8b278aaSsinsanction val toDataPath: Vec[RCWritePort] = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize, 71f8b278aaSsinsanction Flipped(new RCWritePort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth, params.intSchdParams.get.pregIdxWidth, params.debugEn))) 725d2b9cadSXuan Hu} 735d2b9cadSXuan Hu 74712a039eSxiaofeibao-xjtuclass BypassNetwork()(implicit p: Parameters, params: BackendParams) extends XSModule { 755d2b9cadSXuan Hu val io: BypassNetworkIO = IO(new BypassNetworkIO) 765d2b9cadSXuan Hu 7760f0c5aeSxiaofeibao private val fromDPs: Seq[DecoupledIO[ExuInput]] = (io.fromDataPath.int ++ io.fromDataPath.fp ++ io.fromDataPath.vf ++ io.fromDataPath.mem).flatten.toSeq 7860f0c5aeSxiaofeibao private val fromExus: Seq[ValidIO[ExuBypassBundle]] = (io.fromExus.int ++ io.fromExus.fp ++ io.fromExus.vf ++ io.fromExus.mem).flatten.toSeq 7960f0c5aeSxiaofeibao private val toExus: Seq[DecoupledIO[ExuInput]] = (io.toExus.int ++ io.toExus.fp ++ io.toExus.vf ++ io.toExus.mem).flatten.toSeq 80102ba843Ssinsanction private val fromDPsRCData: Seq[Vec[UInt]] = io.fromDataPath.rcData.flatten.toSeq 81712a039eSxiaofeibao-xjtu private val immInfo = io.fromDataPath.immInfo 825d2b9cadSXuan Hu 83102ba843Ssinsanction println(s"[BypassNetwork] RCData num: ${fromDPsRCData.size}") 84102ba843Ssinsanction 855d2b9cadSXuan Hu // (exuIdx, srcIdx, bypassExuIdx) 86864480f4Sxiaofeibao-xjtu private val forwardOrBypassValidVec3: MixedVec[Vec[Vec[Bool]]] = MixedVecInit( 870030d978SzhanglyGit fromDPs.map { (x: DecoupledIO[ExuInput]) => 884fa640e4Ssinsanction println(s"[BypassNetwork] ${x.bits.params.name} numRegSrc: ${x.bits.params.numRegSrc}") 89f57d73d6Ssinsanction VecInit(x.bits.exuSources.map(_.map(_.toExuOH(x.bits.params))).getOrElse( 900030d978SzhanglyGit // TODO: remove tmp max 1 for fake HYU1 91f57d73d6Ssinsanction VecInit(Seq.fill(x.bits.params.numRegSrc max 1)(VecInit(0.U(params.numExu.W).asBools))) 92f57d73d6Ssinsanction )) 930030d978SzhanglyGit } 945d2b9cadSXuan Hu ) 955d2b9cadSXuan Hu 96c0be7f33SXuan Hu private val forwardDataVec: Vec[UInt] = VecInit( 975d2b9cadSXuan Hu fromExus.map(x => ZeroExt(x.bits.data, RegDataMaxWidth)) 985d2b9cadSXuan Hu ) 995d2b9cadSXuan Hu 100c0be7f33SXuan Hu private val bypassDataVec = VecInit( 101c0be7f33SXuan Hu fromExus.map(x => ZeroExt(RegEnable(x.bits.data, x.valid), RegDataMaxWidth)) 102c0be7f33SXuan Hu ) 103c0be7f33SXuan Hu 1044fa640e4Ssinsanction private val intExuNum = params.intSchdParams.get.numExu 10560f0c5aeSxiaofeibao private val fpExuNum = params.fpSchdParams.get.numExu 1064fa640e4Ssinsanction private val vfExuNum = params.vfSchdParams.get.numExu 1074fa640e4Ssinsanction private val memExuNum = params.memSchdParams.get.numExu 1084fa640e4Ssinsanction 10960f0c5aeSxiaofeibao println(s"[BypassNetwork] allExuNum: ${toExus.size} intExuNum: ${intExuNum} fpExuNum: ${fpExuNum} vfExuNum: ${vfExuNum} memExuNum: ${memExuNum}") 1104fa640e4Ssinsanction 111de111a36Ssinsanction private val fromDPsHasBypass2Source = fromDPs.filter(x => x.bits.params.isIQWakeUpSource && x.bits.params.writeVfRf && (x.bits.params.isVfExeUnit || x.bits.params.hasLoadExu)).map(_.bits.params.exuIdx) 112c11e9406Sxiao feibao private val fromDPsHasBypass2Sink = fromDPs.filter(x => x.bits.params.isIQWakeUpSink && x.bits.params.readVfRf && (x.bits.params.isVfExeUnit || x.bits.params.isMemExeUnit)).map(_.bits.params.exuIdx) 1134fa640e4Ssinsanction 1144fa640e4Ssinsanction private val bypass2ValidVec3 = MixedVecInit( 115f57d73d6Ssinsanction fromDPsHasBypass2Sink.map(forwardOrBypassValidVec3(_)).map(exu => VecInit(exu.map(exuOH => 116f57d73d6Ssinsanction VecInit(fromDPsHasBypass2Source.map(exuOH(_))).asUInt 1174fa640e4Ssinsanction ))) 1184fa640e4Ssinsanction ) 119c11e9406Sxiao feibao if(params.debugEn){ 120c11e9406Sxiao feibao dontTouch(bypass2ValidVec3) 121c11e9406Sxiao feibao } 1229c1b710eSZhaoyang You private val bypass2DateEn = VecInit( 1239c1b710eSZhaoyang You fromExus.map(x => GatedValidRegNext(x.valid)) 1249c1b710eSZhaoyang You ).asUInt 1250a5fdf2dSxiaofeibao-xjtu private val bypass2DataVec = if (fromDPsHasBypass2Source.length == 0) VecInit(Seq(0.U)) else VecInit( 1269c1b710eSZhaoyang You fromDPsHasBypass2Source.map(x => RegEnable(bypassDataVec(x), bypass2DateEn(x).asBool)) 1274fa640e4Ssinsanction ) 1284fa640e4Ssinsanction 1294fa640e4Ssinsanction println(s"[BypassNetwork] HasBypass2SourceExuNum: ${fromDPsHasBypass2Source.size} HasBypass2SinkExuNum: ${fromDPsHasBypass2Sink.size} bypass2DataVecSize: ${bypass2DataVec.length}") 1304fa640e4Ssinsanction println(s"[BypassNetwork] HasBypass2SourceExu: ${fromDPsHasBypass2Source}") 1314fa640e4Ssinsanction println(s"[BypassNetwork] HasBypass2SinkExu: ${fromDPsHasBypass2Sink}") 1324fa640e4Ssinsanction 1335d2b9cadSXuan Hu toExus.zip(fromDPs).foreach { case (sink, source) => 134*0ed0e482SGuanghui Cheng connectSamePort(sink.bits, source.bits) 135*0ed0e482SGuanghui Cheng sink.valid := source.valid 136*0ed0e482SGuanghui Cheng source.ready := sink.ready 1375d2b9cadSXuan Hu } 1385d2b9cadSXuan Hu 1395d2b9cadSXuan Hu toExus.zipWithIndex.foreach { case (exuInput, exuIdx) => 1405d2b9cadSXuan Hu exuInput.bits.src.zipWithIndex.foreach { case (src, srcIdx) => 141712a039eSxiaofeibao-xjtu val imm = ImmExtractor( 142712a039eSxiaofeibao-xjtu immInfo(exuIdx).imm, 143712a039eSxiaofeibao-xjtu immInfo(exuIdx).immType, 1442d12882cSxiaofeibao exuInput.bits.params.destDataBitsMax, 145712a039eSxiaofeibao-xjtu exuInput.bits.params.immType.map(_.litValue) 146712a039eSxiaofeibao-xjtu ) 147712a039eSxiaofeibao-xjtu val immLoadSrc0 = SignExt(ImmUnion.U.toImm32(immInfo(exuIdx).imm(immInfo(exuIdx).imm.getWidth - 1, ImmUnion.I.len)), XLEN) 148712a039eSxiaofeibao-xjtu val exuParm = exuInput.bits.params 1494fa640e4Ssinsanction val isIntScheduler = exuParm.isIntExeUnit 150f8e432b7Sxiaofeibao val isReadVfRf= exuParm.readVfRf 151712a039eSxiaofeibao-xjtu val dataSource = exuInput.bits.dataSources(srcIdx) 152712a039eSxiaofeibao-xjtu val isWakeUpSink = params.allIssueParams.filter(_.exuBlockParams.contains(exuParm)).head.exuBlockParams.map(_.isIQWakeUpSink).reduce(_ || _) 153712a039eSxiaofeibao-xjtu val readForward = if (isWakeUpSink) dataSource.readForward else false.B 154712a039eSxiaofeibao-xjtu val readBypass = if (isWakeUpSink) dataSource.readBypass else false.B 155712a039eSxiaofeibao-xjtu val readZero = if (isIntScheduler) dataSource.readZero else false.B 156f8e432b7Sxiaofeibao val readV0 = if (srcIdx < 3 && isReadVfRf) dataSource.readV0 else false.B 157712a039eSxiaofeibao-xjtu val readRegOH = exuInput.bits.dataSources(srcIdx).readRegOH 158102ba843Ssinsanction val readRegCache = if (exuParm.needReadRegCache) exuInput.bits.dataSources(srcIdx).readRegCache else false.B 1594fa640e4Ssinsanction val readImm = if (exuParm.immType.nonEmpty || exuParm.hasLoadExu) exuInput.bits.dataSources(srcIdx).readImm else false.B 1604fa640e4Ssinsanction val bypass2ExuIdx = fromDPsHasBypass2Sink.indexOf(exuIdx) 161c11e9406Sxiao feibao println(s"${exuParm.name}: bypass2ExuIdx is ${bypass2ExuIdx}") 1624fa640e4Ssinsanction val readBypass2 = if (bypass2ExuIdx >= 0) dataSource.readBypass2 else false.B 163712a039eSxiaofeibao-xjtu src := Mux1H( 164712a039eSxiaofeibao-xjtu Seq( 165712a039eSxiaofeibao-xjtu readForward -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), forwardDataVec), 166712a039eSxiaofeibao-xjtu readBypass -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), bypassDataVec), 1674fa640e4Ssinsanction readBypass2 -> (if (bypass2ExuIdx >= 0) Mux1H(bypass2ValidVec3(bypass2ExuIdx)(srcIdx), bypass2DataVec) else 0.U), 168712a039eSxiaofeibao-xjtu readZero -> 0.U, 169db7becb6Sxiaofeibao readV0 -> (if (srcIdx < 3 && isReadVfRf) exuInput.bits.src(3) else 0.U), 170712a039eSxiaofeibao-xjtu readRegOH -> fromDPs(exuIdx).bits.src(srcIdx), 171102ba843Ssinsanction readRegCache -> fromDPsRCData(exuIdx)(srcIdx), 1724fa640e4Ssinsanction readImm -> (if (exuParm.hasLoadExu && srcIdx == 0) immLoadSrc0 else imm) 173712a039eSxiaofeibao-xjtu ) 174712a039eSxiaofeibao-xjtu ) 175da3b3c92SXuan Hu } 176a2fa0ad9Sxiaofeibao if (exuInput.bits.params.hasBrhFu) { 177a2fa0ad9Sxiaofeibao val immWidth = exuInput.bits.params.immType.map(x => SelImm.getImmUnion(x).len).max 178a2fa0ad9Sxiaofeibao val nextPcOffset = exuInput.bits.ftqOffset.get +& Mux(exuInput.bits.preDecode.get.isRVC, 1.U, 2.U) 179a2fa0ad9Sxiaofeibao val imm = ImmExtractor( 180a2fa0ad9Sxiaofeibao immInfo(exuIdx).imm, 181a2fa0ad9Sxiaofeibao immInfo(exuIdx).immType, 182a2fa0ad9Sxiaofeibao exuInput.bits.params.destDataBitsMax, 183a2fa0ad9Sxiaofeibao exuInput.bits.params.immType.map(_.litValue) 184a2fa0ad9Sxiaofeibao ) 185a2fa0ad9Sxiaofeibao val isJALR = FuType.isJump(exuInput.bits.fuType) && JumpOpType.jumpOpisJalr(exuInput.bits.fuOpType) 186a2fa0ad9Sxiaofeibao val immBJU = imm + Mux(isJALR, 0.U, (exuInput.bits.ftqOffset.getOrElse(0.U) << instOffsetBits).asUInt) 187a2fa0ad9Sxiaofeibao exuInput.bits.imm := immBJU 188a2fa0ad9Sxiaofeibao exuInput.bits.nextPcOffset.get := nextPcOffset 189a2fa0ad9Sxiaofeibao } 190*0ed0e482SGuanghui Cheng exuInput.bits.copySrc.get.map( copysrc => 191*0ed0e482SGuanghui Cheng copysrc.zip(exuInput.bits.src).foreach{ case(copy, src) => copy := src} 192*0ed0e482SGuanghui Cheng ) 1935d2b9cadSXuan Hu } 194f8b278aaSsinsanction 195f8b278aaSsinsanction // to reg cache 196f8b278aaSsinsanction private val forwardIntWenVec = VecInit( 197f8b278aaSsinsanction fromExus.filter(_.bits.params.needWriteRegCache).map(x => x.valid && x.bits.intWen) 198f8b278aaSsinsanction ) 199f8b278aaSsinsanction private val forwardTagVec = VecInit( 200f8b278aaSsinsanction fromExus.filter(_.bits.params.needWriteRegCache).map(x => x.bits.pdest) 201f8b278aaSsinsanction ) 202f8b278aaSsinsanction 203f8b278aaSsinsanction private val bypassIntWenVec = VecInit( 204f8b278aaSsinsanction forwardIntWenVec.map(x => GatedValidRegNext(x)) 205f8b278aaSsinsanction ) 206f8b278aaSsinsanction private val bypassTagVec = VecInit( 207f8b278aaSsinsanction forwardTagVec.zip(forwardIntWenVec).map(x => RegEnable(x._1, x._2)) 208f8b278aaSsinsanction ) 209f8b278aaSsinsanction private val bypassRCDataVec = VecInit( 210f8b278aaSsinsanction fromExus.zip(bypassDataVec).filter(_._1.bits.params.needWriteRegCache).map(_._2) 211f8b278aaSsinsanction ) 212f8b278aaSsinsanction 213f8b278aaSsinsanction println(s"[BypassNetwork] WriteRegCacheExuNum: ${forwardIntWenVec.size}") 214f8b278aaSsinsanction 215f8b278aaSsinsanction io.toDataPath.zipWithIndex.foreach{ case (x, i) => 216f8b278aaSsinsanction x.wen := bypassIntWenVec(i) 217f8b278aaSsinsanction x.addr := DontCare 218f8b278aaSsinsanction x.data := bypassRCDataVec(i) 219f8b278aaSsinsanction x.tag.foreach(_ := bypassTagVec(i)) 220f8b278aaSsinsanction } 2215d2b9cadSXuan Hu} 222