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