xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/RFReadArbiter.scala (revision 39c59369af6e7d78fa72e13aae3735f1a6e98f5c)
1package xiangshan.backend.datapath
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import chisel3.util.{Arbiter, DecoupledIO, Valid}
6import utils.SeqUtils.{MixedVec3, Seq3}
7import utils.{OptionWrapper, SeqUtils}
8import xiangshan.backend.BackendParams
9import xiangshan.backend.datapath.DataConfig.{IntData, VecData}
10import xiangshan.backend.datapath.RdConfig.{IntRD, NoRD, RdConfig, VfRD}
11import xiangshan.backend.regfile.PregParams
12
13case class RFRdArbParams(
14  inRdCfgs: Seq3[RdConfig],
15  pregParams: PregParams,
16) {
17  require(inRdCfgs.nonEmpty)
18
19  def genInputBundle: MixedVec3[DecoupledIO[RFArbiterBundle]] = {
20    val pregWidth = pregParams.addrWidth
21    SeqUtils.mapToMixedVec3(this.inRdCfgs, (rd: RdConfig) => DecoupledIO(new RFArbiterBundle(rd, pregWidth)))
22  }
23
24  def portMax: Int = inRdCfgs.flatten.flatten.map(_.port).max
25}
26
27class RFArbiterBundle(var rdCfg: Option[RdConfig], pregWidth: Int) extends Bundle {
28  val addr = UInt(pregWidth.W)
29
30  def this(rdCfg_ : RdConfig, pregWidth_ : Int) = this(Some(rdCfg_), pregWidth_)
31
32  def this(pregWidth_ :Int) = this(None, pregWidth_)
33}
34
35class RFReadArbiterIO(params: RFRdArbParams)(implicit p: Parameters) extends Bundle {
36  private val pregWidth = params.pregParams.addrWidth
37  val in = Flipped(params.genInputBundle)
38  val out = Vec(params.portMax + 1, Valid(new RFArbiterBundle(pregWidth)))
39}
40
41abstract class RFReadArbiterBase(val params: RFRdArbParams)(implicit p: Parameters) extends Module {
42  protected def portRange: Range
43
44  val io = IO(new RFReadArbiterIO(params))
45  dontTouch(io)
46
47  protected val pregParams = params.pregParams
48  protected val pregWidth = pregParams.addrWidth
49
50  protected val inGroup: Map[Int, Seq[DecoupledIO[RFArbiterBundle]]] = io.in
51    .flatten.flatten
52    .groupBy(_.bits.rdCfg.get.port)
53    .map(x => (x._1, x._2.sortBy(_.bits.rdCfg.get.priority)))
54
55  protected val arbiters: Seq[Option[Arbiter[RFArbiterBundle]]] = portRange.map { portIdx =>
56    OptionWrapper(
57      inGroup.isDefinedAt(portIdx),
58      Module(new Arbiter(
59        new RFArbiterBundle(pregWidth),
60        inGroup(portIdx).size
61      ))
62    )
63  }
64
65  arbiters.zipWithIndex.foreach { case (arbiter, portIdx) =>
66    if (arbiter.nonEmpty) {
67      arbiter.get.io.in.zip(inGroup(portIdx)).foreach { case (arbiterIn, ioIn) =>
68        arbiterIn <> ioIn
69      }
70    }
71  }
72
73  // connection of NoRD
74  io.in.map(_.map(_.map(x =>
75    if (x.bits.rdCfg.get.isInstanceOf[NoRD]) {
76      x.ready := true.B
77    }
78  )))
79
80  for (portIdx <- io.out.indices) {
81    val arb = arbiters(portIdx)
82    val out = io.out(portIdx)
83    if (arb.nonEmpty) {
84      val arbOut = arb.get.io.out
85      arbOut.ready := true.B
86      out.valid := arbOut.valid
87      out.bits := arbOut.bits
88    } else {
89      out := 0.U.asTypeOf(out)
90    }
91  }
92}
93
94class IntRFReadArbiter(
95  backendParams: BackendParams
96)(implicit
97  p: Parameters
98) extends RFReadArbiterBase(RFRdArbParams(backendParams.getRdCfgs[IntRD], backendParams.intPregParams)) {
99  override protected def portRange: Range = 0 to backendParams.getRdPortIndices(IntData()).max
100}
101
102class VfRFReadArbiter(
103  backendParams: BackendParams
104)(implicit
105  p: Parameters
106) extends RFReadArbiterBase(RFRdArbParams(backendParams.getRdCfgs[VfRD], backendParams.vfPregParams)) {
107  override protected def portRange: Range = 0 to backendParams.getRdPortIndices(VecData()).max
108}
109
110