xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/RFReadArbiter.scala (revision bb2f3f51dd67f6e16e0cc1ffe43368c9fc7e4aef)
139c59369SXuan Hupackage xiangshan.backend.datapath
239c59369SXuan Hu
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
439c59369SXuan Huimport chisel3._
5ff3fcdf1Sxiaofeibao-xjtuimport chisel3.util.{Arbiter, DecoupledIO, RRArbiter, Valid, PopCount}
639c59369SXuan Huimport utils.SeqUtils.{MixedVec3, Seq3}
739c59369SXuan Huimport utils.{OptionWrapper, SeqUtils}
839c59369SXuan Huimport xiangshan.backend.BackendParams
9e4e52e7dSsinsanctionimport xiangshan.backend.datapath.DataConfig._
10e4e52e7dSsinsanctionimport xiangshan.backend.datapath.RdConfig._
1139c59369SXuan Huimport xiangshan.backend.regfile.PregParams
12*bb2f3f51STang Haojinimport utility._
1339c59369SXuan Hu
1439c59369SXuan Hucase class RFRdArbParams(
1539c59369SXuan Hu  inRdCfgs: Seq3[RdConfig],
1639c59369SXuan Hu  pregParams: PregParams,
1739c59369SXuan Hu) {
1839c59369SXuan Hu  require(inRdCfgs.nonEmpty)
1939c59369SXuan Hu
2039c59369SXuan Hu  def genInputBundle: MixedVec3[DecoupledIO[RFArbiterBundle]] = {
2139c59369SXuan Hu    val pregWidth = pregParams.addrWidth
2239c59369SXuan Hu    SeqUtils.mapToMixedVec3(this.inRdCfgs, (rd: RdConfig) => DecoupledIO(new RFArbiterBundle(rd, pregWidth)))
2339c59369SXuan Hu  }
2439c59369SXuan Hu
2539c59369SXuan Hu  def portMax: Int = inRdCfgs.flatten.flatten.map(_.port).max
2639c59369SXuan Hu}
2739c59369SXuan Hu
2839c59369SXuan Huclass RFArbiterBundle(var rdCfg: Option[RdConfig], pregWidth: Int) extends Bundle {
2939c59369SXuan Hu  val addr = UInt(pregWidth.W)
3039c59369SXuan Hu
3139c59369SXuan Hu  def this(rdCfg_ : RdConfig, pregWidth_ : Int) = this(Some(rdCfg_), pregWidth_)
3239c59369SXuan Hu
3339c59369SXuan Hu  def this(pregWidth_ :Int) = this(None, pregWidth_)
3439c59369SXuan Hu}
3539c59369SXuan Hu
3639c59369SXuan Huclass RFReadArbiterIO(params: RFRdArbParams)(implicit p: Parameters) extends Bundle {
3739c59369SXuan Hu  private val pregWidth = params.pregParams.addrWidth
3839c59369SXuan Hu  val in = Flipped(params.genInputBundle)
3939c59369SXuan Hu  val out = Vec(params.portMax + 1, Valid(new RFArbiterBundle(pregWidth)))
4039c59369SXuan Hu}
4139c59369SXuan Hu
4239c59369SXuan Huabstract class RFReadArbiterBase(val params: RFRdArbParams)(implicit p: Parameters) extends Module {
4339c59369SXuan Hu  protected def portRange: Range
4439c59369SXuan Hu
4539c59369SXuan Hu  val io = IO(new RFReadArbiterIO(params))
4639c59369SXuan Hu  dontTouch(io)
4739c59369SXuan Hu
4839c59369SXuan Hu  protected val pregParams = params.pregParams
4939c59369SXuan Hu  protected val pregWidth = pregParams.addrWidth
5039c59369SXuan Hu
5139c59369SXuan Hu  protected val inGroup: Map[Int, Seq[DecoupledIO[RFArbiterBundle]]] = io.in
5239c59369SXuan Hu    .flatten.flatten
5339c59369SXuan Hu    .groupBy(_.bits.rdCfg.get.port)
5483ba63b3SXuan Hu    .map(x => (x._1, x._2.sortBy(_.bits.rdCfg.get.priority).toSeq))
553ff8f291Sxiaofeibao-xjtu  protected val arbiters: Seq[Option[WBArbiter[RFArbiterBundle]]] = portRange.map { portIdx =>
56*bb2f3f51STang Haojin    Option.when(
57*bb2f3f51STang Haojin      inGroup.isDefinedAt(portIdx))(
583ff8f291Sxiaofeibao-xjtu      Module(new WBArbiter(
5939c59369SXuan Hu        new RFArbiterBundle(pregWidth),
6039c59369SXuan Hu        inGroup(portIdx).size
6139c59369SXuan Hu      ))
6239c59369SXuan Hu    )
6339c59369SXuan Hu  }
6439c59369SXuan Hu
6539c59369SXuan Hu  arbiters.zipWithIndex.foreach { case (arbiter, portIdx) =>
6639c59369SXuan Hu    if (arbiter.nonEmpty) {
6739c59369SXuan Hu      arbiter.get.io.in.zip(inGroup(portIdx)).foreach { case (arbiterIn, ioIn) =>
6839c59369SXuan Hu        arbiterIn <> ioIn
6939c59369SXuan Hu      }
7039c59369SXuan Hu    }
7139c59369SXuan Hu  }
7239c59369SXuan Hu
73c1e19666Sxiaofeibao-xjtu  if (params.pregParams.dataCfg.isInstanceOf[IntData]) {
74ff3fcdf1Sxiaofeibao-xjtu    val arbitersIn = arbiters.filter(_.nonEmpty).map(_.get.io.in)
75ff3fcdf1Sxiaofeibao-xjtu    val hasConflict = arbitersIn.map { case a =>
76ff3fcdf1Sxiaofeibao-xjtu      PopCount(a.map(_.valid)) > 1.U
77ff3fcdf1Sxiaofeibao-xjtu    }
78ff3fcdf1Sxiaofeibao-xjtu    for (i <- hasConflict.indices) {
79ff3fcdf1Sxiaofeibao-xjtu      XSPerfAccumulate(s"IntRFReadPort_${i}_Conflict", PopCount(hasConflict(i)))
80ff3fcdf1Sxiaofeibao-xjtu    }
81ff3fcdf1Sxiaofeibao-xjtu    val hasRead0 = arbitersIn.map { case a =>
82ff3fcdf1Sxiaofeibao-xjtu      a.map(x => x.valid && x.bits.addr === 0.U).reduce(_ || _)
83ff3fcdf1Sxiaofeibao-xjtu    }
84ff3fcdf1Sxiaofeibao-xjtu    val hasSameAddr = arbitersIn.map { case a =>
85ff3fcdf1Sxiaofeibao-xjtu      if (a.size == 2) a(0).valid && a(1).valid && a(0).bits.addr === a(1).bits.addr
86ff3fcdf1Sxiaofeibao-xjtu      else false.B
87ff3fcdf1Sxiaofeibao-xjtu    }
88ff3fcdf1Sxiaofeibao-xjtu    val hasRead0Conflict = hasConflict.zip(hasRead0).map(x => x._1 && x._2)
89ff3fcdf1Sxiaofeibao-xjtu    val hasReadSameAddrConflict = hasConflict.zip(hasSameAddr).map(x => x._1 && x._2)
90ff3fcdf1Sxiaofeibao-xjtu    XSPerfAccumulate("IntRFRead0_conflict_count", PopCount(hasRead0Conflict))
91ff3fcdf1Sxiaofeibao-xjtu    XSPerfAccumulate("IntRFReadSameAddr_conflict_count", PopCount(hasReadSameAddrConflict))
92ff3fcdf1Sxiaofeibao-xjtu  }
93ff3fcdf1Sxiaofeibao-xjtu
9439c59369SXuan Hu  // connection of NoRD
9539c59369SXuan Hu  io.in.map(_.map(_.map(x =>
9639c59369SXuan Hu    if (x.bits.rdCfg.get.isInstanceOf[NoRD]) {
9739c59369SXuan Hu      x.ready := true.B
9839c59369SXuan Hu    }
9939c59369SXuan Hu  )))
10039c59369SXuan Hu
10139c59369SXuan Hu  for (portIdx <- io.out.indices) {
10239c59369SXuan Hu    val arb = arbiters(portIdx)
10339c59369SXuan Hu    val out = io.out(portIdx)
10439c59369SXuan Hu    if (arb.nonEmpty) {
10539c59369SXuan Hu      val arbOut = arb.get.io.out
10639c59369SXuan Hu      arbOut.ready := true.B
10739c59369SXuan Hu      out.valid := arbOut.valid
10839c59369SXuan Hu      out.bits := arbOut.bits
10939c59369SXuan Hu    } else {
11039c59369SXuan Hu      out := 0.U.asTypeOf(out)
11139c59369SXuan Hu    }
11239c59369SXuan Hu  }
11339c59369SXuan Hu}
11439c59369SXuan Hu
11539c59369SXuan Huclass IntRFReadArbiter(
11639c59369SXuan Hu  backendParams: BackendParams
11739c59369SXuan Hu)(implicit
11839c59369SXuan Hu  p: Parameters
11939c59369SXuan Hu) extends RFReadArbiterBase(RFRdArbParams(backendParams.getRdCfgs[IntRD], backendParams.intPregParams)) {
12039c59369SXuan Hu  override protected def portRange: Range = 0 to backendParams.getRdPortIndices(IntData()).max
12139c59369SXuan Hu}
12239c59369SXuan Hu
12360f0c5aeSxiaofeibaoclass FpRFReadArbiter(
12460f0c5aeSxiaofeibao  backendParams: BackendParams
12560f0c5aeSxiaofeibao)(implicit
12660f0c5aeSxiaofeibao  p: Parameters
12760f0c5aeSxiaofeibao) extends RFReadArbiterBase(RFRdArbParams(backendParams.getRdCfgs[FpRD], backendParams.fpPregParams)) {
12860f0c5aeSxiaofeibao  override protected def portRange: Range = 0 to backendParams.getRdPortIndices(FpData()).max
12960f0c5aeSxiaofeibao}
13060f0c5aeSxiaofeibao
13139c59369SXuan Huclass VfRFReadArbiter(
13239c59369SXuan Hu  backendParams: BackendParams
13339c59369SXuan Hu)(implicit
13439c59369SXuan Hu  p: Parameters
13539c59369SXuan Hu) extends RFReadArbiterBase(RFRdArbParams(backendParams.getRdCfgs[VfRD], backendParams.vfPregParams)) {
13639c59369SXuan Hu  override protected def portRange: Range = 0 to backendParams.getRdPortIndices(VecData()).max
13739c59369SXuan Hu}
13839c59369SXuan Hu
139e4e52e7dSsinsanctionclass V0RFReadArbiter(
140e4e52e7dSsinsanction  backendParams: BackendParams
141e4e52e7dSsinsanction)(implicit
142e4e52e7dSsinsanction  p: Parameters
143e4e52e7dSsinsanction) extends RFReadArbiterBase(RFRdArbParams(backendParams.getRdCfgs[V0RD], backendParams.v0PregParams)) {
144e4e52e7dSsinsanction  override protected def portRange: Range = 0 to backendParams.getRdPortIndices(V0Data()).max
145e4e52e7dSsinsanction}
146e4e52e7dSsinsanction
147e4e52e7dSsinsanctionclass VlRFReadArbiter(
148e4e52e7dSsinsanction  backendParams: BackendParams
149e4e52e7dSsinsanction)(implicit
150e4e52e7dSsinsanction  p: Parameters
151e4e52e7dSsinsanction) extends RFReadArbiterBase(RFRdArbParams(backendParams.getRdCfgs[VlRD], backendParams.vlPregParams)) {
152e4e52e7dSsinsanction  override protected def portRange: Range = 0 to backendParams.getRdPortIndices(VlData()).max
153e4e52e7dSsinsanction}
154