xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/RFWBConflictChecker.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._
6*39c59369SXuan Huimport utils.OptionWrapper
7*39c59369SXuan Huimport utils.SeqUtils.MixedVec2
8*39c59369SXuan Huimport xiangshan.backend.BackendParams
9*39c59369SXuan Huimport xiangshan.backend.datapath.DataConfig.{IntData, VecData}
10*39c59369SXuan Huimport xiangshan.backend.datapath.WbConfig.{NoWB, PregWB}
11*39c59369SXuan Huimport xiangshan.backend.regfile.PregParams
12*39c59369SXuan Hu
13*39c59369SXuan Hucase class RFWBCollideCheckerParams (
14*39c59369SXuan Hu  inWbCfgs: Seq[Seq[Set[PregWB]]],
15*39c59369SXuan Hu  pregParams: PregParams,
16*39c59369SXuan Hu) {
17*39c59369SXuan Hu  def genInputBundle: MixedVec2[DecoupledIO[RFWBCollideCheckerBundle]] = {
18*39c59369SXuan Hu    val pregWidth = pregParams.addrWidth
19*39c59369SXuan Hu    utils.SeqUtils.mapToMixedVec2(this.filteredCfgs, (wb: PregWB) => DecoupledIO(new RFWBCollideCheckerBundle(wb, pregWidth)))
20*39c59369SXuan Hu  }
21*39c59369SXuan Hu
22*39c59369SXuan Hu  def filteredCfgs: Seq[Seq[PregWB]] = inWbCfgs.map(_.map(x =>
23*39c59369SXuan Hu    if (x.map(_.dataCfg).contains(pregParams.dataCfg))
24*39c59369SXuan Hu      x.find(x => x.dataCfg == pregParams.dataCfg).get
25*39c59369SXuan Hu    else
26*39c59369SXuan Hu      NoWB()
27*39c59369SXuan Hu  ))
28*39c59369SXuan Hu
29*39c59369SXuan Hu  def portMax = filteredCfgs.flatten.map(_.port).max
30*39c59369SXuan Hu}
31*39c59369SXuan Hu
32*39c59369SXuan Huclass RFWBCollideCheckerBundle(var wbCfg: Option[PregWB], pregWidth: Int) extends Bundle {
33*39c59369SXuan Hu
34*39c59369SXuan Hu  def this(wbCfg_ : PregWB, pregWidth_ : Int) = this(Some(wbCfg_), pregWidth_)
35*39c59369SXuan Hu
36*39c59369SXuan Hu  def this(pregWidth_ : Int) = this(None, pregWidth_)
37*39c59369SXuan Hu}
38*39c59369SXuan Hu
39*39c59369SXuan Huclass RFWBCollideCheckerIO(val params: RFWBCollideCheckerParams)(implicit p: Parameters) extends Bundle {
40*39c59369SXuan Hu  private val pregWidth = params.pregParams.addrWidth
41*39c59369SXuan Hu  val in: MixedVec2[DecoupledIO[RFWBCollideCheckerBundle]] = Flipped(params.genInputBundle)
42*39c59369SXuan Hu  val out = Vec(params.portMax + 1, Valid(new RFWBCollideCheckerBundle(pregWidth)))
43*39c59369SXuan Hu}
44*39c59369SXuan Hu
45*39c59369SXuan Huabstract class RFWBCollideCheckerBase(params: RFWBCollideCheckerParams)(implicit p: Parameters) extends Module {
46*39c59369SXuan Hu  protected def portRange: Range
47*39c59369SXuan Hu
48*39c59369SXuan Hu  val io = IO(new RFWBCollideCheckerIO(params))
49*39c59369SXuan Hu  dontTouch(io)
50*39c59369SXuan Hu
51*39c59369SXuan Hu  protected val pregParams = params.pregParams
52*39c59369SXuan Hu  protected val pregWidth = pregParams.addrWidth
53*39c59369SXuan Hu
54*39c59369SXuan Hu  protected val inGroup = io.in
55*39c59369SXuan Hu    .flatten
56*39c59369SXuan Hu    .groupBy(_.bits.wbCfg.get.port)
57*39c59369SXuan Hu    .map(x => (x._1, x._2.sortBy(_.bits.wbCfg.get.priority)))
58*39c59369SXuan Hu
59*39c59369SXuan Hu  protected val arbiters: Seq[Option[Arbiter[RFWBCollideCheckerBundle]]] = portRange.map { portIdx =>
60*39c59369SXuan Hu    OptionWrapper(
61*39c59369SXuan Hu      inGroup.isDefinedAt(portIdx),
62*39c59369SXuan Hu      Module(new Arbiter(
63*39c59369SXuan Hu        new RFWBCollideCheckerBundle(pregWidth),
64*39c59369SXuan Hu        inGroup(portIdx).size
65*39c59369SXuan Hu      ))
66*39c59369SXuan Hu    )
67*39c59369SXuan Hu  }
68*39c59369SXuan Hu
69*39c59369SXuan Hu  // connection of IntWB or VfWB
70*39c59369SXuan Hu  arbiters.zipWithIndex.foreach { case (arb, portIdx) =>
71*39c59369SXuan Hu    if (arb.nonEmpty) {
72*39c59369SXuan Hu      arb.get.io.in.zip(inGroup(portIdx)).foreach { case (arbiterIn, ioIn) =>
73*39c59369SXuan Hu        arbiterIn <> ioIn
74*39c59369SXuan Hu      }
75*39c59369SXuan Hu    }
76*39c59369SXuan Hu  }
77*39c59369SXuan Hu
78*39c59369SXuan Hu  // connection of NoWB
79*39c59369SXuan Hu  io.in.map(_.map(x =>
80*39c59369SXuan Hu    if (x.bits.wbCfg.get.isInstanceOf[NoWB]) {
81*39c59369SXuan Hu      x.ready := true.B
82*39c59369SXuan Hu    }
83*39c59369SXuan Hu  ))
84*39c59369SXuan Hu
85*39c59369SXuan Hu  io.out.zip(arbiters).foreach { case (out, arb) =>
86*39c59369SXuan Hu    if (arb.nonEmpty) {
87*39c59369SXuan Hu      val arbOut = arb.get.io.out
88*39c59369SXuan Hu      arbOut.ready := true.B
89*39c59369SXuan Hu      out.valid := arbOut.valid
90*39c59369SXuan Hu      out.bits := arbOut.bits
91*39c59369SXuan Hu    } else {
92*39c59369SXuan Hu      out := 0.U.asTypeOf(out)
93*39c59369SXuan Hu    }
94*39c59369SXuan Hu  }
95*39c59369SXuan Hu}
96*39c59369SXuan Hu
97*39c59369SXuan Huclass IntRFWBCollideChecker(
98*39c59369SXuan Hu  backendParams: BackendParams
99*39c59369SXuan Hu)(implicit
100*39c59369SXuan Hu  p:Parameters
101*39c59369SXuan Hu) extends RFWBCollideCheckerBase(RFWBCollideCheckerParams(backendParams.getAllWbCfgs, backendParams.intPregParams)) {
102*39c59369SXuan Hu  override protected def portRange: Range = 0 to backendParams.getWbPortIndices(IntData()).max
103*39c59369SXuan Hu}
104*39c59369SXuan Hu
105*39c59369SXuan Huclass VfRFWBCollideChecker(
106*39c59369SXuan Hu  backendParams: BackendParams
107*39c59369SXuan Hu)(implicit
108*39c59369SXuan Hu  p:Parameters
109*39c59369SXuan Hu) extends RFWBCollideCheckerBase(RFWBCollideCheckerParams(backendParams.getAllWbCfgs, backendParams.vfPregParams)) {
110*39c59369SXuan Hu  override protected def portRange: Range = 0 to backendParams.getWbPortIndices(VecData()).max
111*39c59369SXuan Hu}
112