xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/BypassNetwork.scala (revision c4fc226ad7a2197009ce1afff94b3636f87bb475)
1package xiangshan.backend.datapath
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import chisel3.util._
6import utility.ZeroExt
7import xiangshan.XSBundle
8import xiangshan.backend.BackendParams
9import xiangshan.backend.Bundles.{ExuBypassBundle, ExuInput, ExuOH, ExuOutput}
10import xiangshan.backend.issue.{IntScheduler, MemScheduler, VfScheduler}
11import xiangshan.backend.datapath.DataConfig.RegDataMaxWidth
12
13class BypassNetworkIO()(implicit p: Parameters, params: BackendParams) extends XSBundle {
14  // params
15  private val intSchdParams = params.schdParams(IntScheduler())
16  private val vfSchdParams = params.schdParams(VfScheduler())
17  private val memSchdParams = params.schdParams(MemScheduler())
18
19  val fromDataPath = new FromDataPath
20  val toExus = new ToExus
21  val fromExus = new FromExus
22
23  class FromDataPath extends Bundle {
24    val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(intSchdParams.genExuInputBundle)
25    val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(vfSchdParams.genExuInputBundle)
26    val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(memSchdParams.genExuInputBundle)
27  }
28
29  class ToExus extends Bundle {
30    val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = intSchdParams.genExuInputBundle
31    val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = vfSchdParams.genExuInputBundle
32    val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = memSchdParams.genExuInputBundle
33  }
34
35  class FromExus extends Bundle {
36    val int: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(intSchdParams.genExuBypassValidBundle)
37    val vf : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(vfSchdParams.genExuBypassValidBundle)
38    val mem: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(memSchdParams.genExuBypassValidBundle)
39
40    def connectExuOutput(
41      getSinkVecN: FromExus => MixedVec[MixedVec[ValidIO[ExuBypassBundle]]]
42    )(
43      sourceVecN: MixedVec[MixedVec[DecoupledIO[ExuOutput]]]
44    ): Unit = {
45      getSinkVecN(this).zip(sourceVecN).foreach { case (sinkVec, sourcesVec) =>
46        sinkVec.zip(sourcesVec).foreach { case (sink, source) =>
47          sink.valid := source.valid
48          sink.bits.pdest := source.bits.pdest
49          sink.bits.data := source.bits.data
50        }
51      }
52    }
53  }
54}
55
56class BypassNetwork()(implicit p: Parameters, params: BackendParams) extends Module {
57  val io: BypassNetworkIO = IO(new BypassNetworkIO)
58
59  private val fromDPs: Seq[DecoupledIO[ExuInput]] = (io.fromDataPath.int ++ io.fromDataPath.vf ++ io.fromDataPath.mem).flatten.toSeq
60  private val fromExus: Seq[ValidIO[ExuBypassBundle]] = (io.fromExus.int ++ io.fromExus.vf ++ io.fromExus.mem).flatten.toSeq
61  private val toExus: Seq[DecoupledIO[ExuInput]] = (io.toExus.int ++ io.toExus.vf ++ io.toExus.mem).flatten.toSeq
62
63  // (exuIdx, srcIdx, bypassExuIdx)
64  private val forwardOrBypassValidVec3: MixedVec[Vec[UInt]] = MixedVecInit(
65    fromDPs.map { (x: DecoupledIO[ExuInput]) =>
66      println(s"[tmp-BypassNetwork] ${x.bits.params.name} numRegSrc: ${x.bits.params.numRegSrc}")
67      x.bits.l1ExuOH.getOrElse(
68        // TODO: remove tmp max 1 for fake HYU1
69        VecInit(Seq.fill(x.bits.params.numRegSrc max 1)(0.U(ExuOH.width.W)))
70      )
71    }
72  )
73
74  private val forwardDataVec: Vec[UInt] = VecInit(
75    fromExus.map(x => ZeroExt(x.bits.data, RegDataMaxWidth))
76  )
77
78  private val bypassDataVec = VecInit(
79    fromExus.map(x => ZeroExt(RegEnable(x.bits.data, x.valid), RegDataMaxWidth))
80  )
81
82  toExus.zip(fromDPs).foreach { case (sink, source) =>
83    sink <> source
84  }
85
86  toExus.zipWithIndex.foreach { case (exuInput, exuIdx) =>
87    exuInput.bits.src.zipWithIndex.foreach { case (src, srcIdx) =>
88      when (exuInput.bits.dataSources(srcIdx).readForward) {
89        src := Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), forwardDataVec)
90      }.elsewhen (exuInput.bits.dataSources(srcIdx).readBypass) {
91        src := Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), bypassDataVec)
92      }.elsewhen(exuInput.bits.dataSources(srcIdx).readZero) {
93        src := 0.U
94      }.elsewhen(exuInput.bits.dataSources(srcIdx).readAnotherReg) {
95        src := fromDPs(exuIdx).bits.src(0)
96      }.otherwise {
97        src := fromDPs(exuIdx).bits.src(srcIdx)
98      }
99    }
100  }
101}
102