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