xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/BypassNetwork.scala (revision 0ed0e482b4d85da1fe7dcd24705d25559036f63f)
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