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