1package xiangshan.backend.datapath 2 3import scala.collection.Seq 4import org.chipsalliance.cde.config.Parameters 5import chisel3._ 6import chisel3.util._ 7import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 8import utility._ 9import utils.OptionWrapper 10import xiangshan._ 11import xiangshan.backend._ 12import xiangshan.backend.datapath.WbConfig._ 13import xiangshan.backend.exu.ExeUnitParams 14import xiangshan.backend.implicitCast._ 15 16class WbFuBusyTable(bp: BackendParams)(implicit p: Parameters) extends LazyModule { 17 override def shouldBeInlined: Boolean = false 18 implicit val params: BackendParams = bp 19 lazy val module = new WbFuBusyTableImp(this) 20} 21 22class WbFuBusyTableImp(override val wrapper: WbFuBusyTable)(implicit p: Parameters, params: BackendParams) extends LazyModuleImp(wrapper) { 23 val io = IO(new WbFuBusyTableIO) 24 25 private val intSchdBusyTable = io.in.intSchdBusyTable 26 private val fpSchdBusyTable = io.in.fpSchdBusyTable 27 private val vfSchdBusyTable = io.in.vfSchdBusyTable 28 private val memSchdBusyTable = io.in.memSchdBusyTable 29 private val intRespRead = io.out.intRespRead 30 private val fpRespRead = io.out.fpRespRead 31 private val vfRespRead = io.out.vfRespRead 32 private val memRespRead = io.out.memRespRead 33 private val intAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.intConflict) 34 private val fpAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.fpConflict) 35 private val vfAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.vfConflict) 36 private val v0AllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.v0Conflict) 37 private val vlAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.vlConflict) 38 39 private val intAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intWbBusyTable) 40 private val fpAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.fpWbBusyTable) 41 private val vfAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfWbBusyTable) 42 private val v0AllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.v0WbBusyTable) 43 private val vlAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vlWbBusyTable) 44 45 private val intAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intDeqRespSet) 46 private val fpAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.fpDeqRespSet) 47 private val vfAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfDeqRespSet) 48 private val v0AllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.v0DeqRespSet) 49 private val vlAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vlDeqRespSet) 50 51 private val intAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.intWbBusyTable) 52 private val fpAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.fpWbBusyTable) 53 private val vfAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.vfWbBusyTable) 54 private val v0AllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.v0WbBusyTable) 55 private val vlAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.vlWbBusyTable) 56 57 private val allExuParams = params.allExuParams 58 private val intAllBusyTableWithParms = intAllBusyTable.zip(allExuParams).toSeq 59 private val fpAllBusyTableWithParms = fpAllBusyTable.zip(allExuParams).toSeq 60 private val vfAllBusyTableWithParms = vfAllBusyTable.zip(allExuParams).toSeq 61 private val v0AllBusyTableWithParms = v0AllBusyTable.zip(allExuParams).toSeq 62 private val vlAllBusyTableWithParms = vlAllBusyTable.zip(allExuParams).toSeq 63 64 private val intAllDeqRespSetWithParms = intAllDeqRespSet.zip(allExuParams).toSeq 65 private val fpAllDeqRespSetWithParms = fpAllDeqRespSet.zip(allExuParams).toSeq 66 private val vfAllDeqRespSetWithParms = vfAllDeqRespSet.zip(allExuParams).toSeq 67 private val v0AllDeqRespSetWithParms = v0AllDeqRespSet.zip(allExuParams).toSeq 68 private val vlAllDeqRespSetWithParms = vlAllDeqRespSet.zip(allExuParams).toSeq 69 70 private val intWbLatencyMax = params.getIntWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.intLatencyValMax).max, seq.forall(_.intLatencyCertain)) } 71 private val fpWbLatencyMax = params.getFpWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.fpLatencyValMax).max, seq.forall(_.fpLatencyCertain)) } 72 private val vfWbLatencyMax = params.getVfWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.vfLatencyValMax).max, seq.forall(_.vfLatencyCertain)) } 73 private val v0WbLatencyMax = params.getV0WBExeGroup.map { case (portId, seq) => (portId, seq.map(_.v0LatencyValMax).max, seq.forall(_.v0LatencyCertain)) } 74 private val vlWbLatencyMax = params.getVlWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.vlLatencyValMax).max, seq.forall(_.vlLatencyCertain)) } 75 76 private val intWbBusyTable: Map[Int, Option[UInt]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap 77 private val fpWbBusyTable = fpWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap 78 private val vfWbBusyTable = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap 79 private val v0WbBusyTable = v0WbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap 80 private val vlWbBusyTable = vlWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap 81 82 private val intConflict: Map[Int, Option[Bool]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap 83 private val fpConflict = fpWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap 84 private val vfConflict = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap 85 private val v0Conflict = v0WbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap 86 private val vlConflict = vlWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap 87 88 def hitWbPort[T <: Data](source: Option[T], p: ExeUnitParams, portId: Int, wbType: PregWB) = { 89 wbType match { 90 case IntWB(_, _) => p.wbPortConfigs.collectFirst { case x: IntWB => x.port }.getOrElse(-1) == portId && source.nonEmpty 91 case FpWB(_, _) => p.wbPortConfigs.collectFirst { case x: FpWB => x.port }.getOrElse(-1) == portId && source.nonEmpty 92 case VfWB(_, _) => p.wbPortConfigs.collectFirst { case x: VfWB => x.port }.getOrElse(-1) == portId && source.nonEmpty 93 case V0WB(_, _) => p.wbPortConfigs.collectFirst { case x: V0WB => x.port }.getOrElse(-1) == portId && source.nonEmpty 94 case VlWB(_, _) => p.wbPortConfigs.collectFirst { case x: VlWB => x.port }.getOrElse(-1) == portId && source.nonEmpty 95 case _ => throw new IllegalArgumentException(s"WbConfig ${wbType} is not permitted") 96 } 97 } 98 99 def writeBusyTable(wtBusyTable: Map[Int, Option[UInt]], busyTableWithParams: Seq[(Option[UInt], ExeUnitParams)], wbType: PregWB) = { 100 wtBusyTable.foreach { case (portId, busyTable) => 101 if (busyTable.nonEmpty) { 102 busyTable.get := busyTableWithParams.filter { case (busyTable, p) => hitWbPort(busyTable, p, portId, wbType) }.map(_._1.get).reduce(_ | _) 103 } 104 } 105 } 106 107 def writeConflict(wtConflict: Map[Int, Option[Bool]], deqRespSetWithParams: Seq[(Option[UInt], ExeUnitParams)], wbType: PregWB) = { 108 wtConflict.foreach { case (portId, conflict) => 109 if (conflict.nonEmpty) { 110 val deqRespSel = deqRespSetWithParams.filter { case (deqRespSet, p) => hitWbPort(deqRespSet, p, portId, wbType) }.map(_._1.get) 111 val width = deqRespSel.map(x => x.getWidth).max 112 val deqRespSelUnify = deqRespSel.map(x => x.asTypeOf(UInt(width.W))).toSeq 113 conflict.get := (0 until width).map { case i => 114 OnesMoreThan(deqRespSelUnify.map(x => x(i)), 2) 115 }.reduce(_ | _) 116 } 117 } 118 } 119 120 def readRes[T <: Data](sink: IndexedSeq[Option[T]], source: Map[Int, Option[T]], wbType: PregWB) = { 121 for (i <- 0 until sink.size) { 122 if (sink(i).nonEmpty) { 123 sink(i).get := source.map { case (portId, src) => 124 if (hitWbPort(src, allExuParams(i), portId, wbType)) { 125 src.get.asTypeOf(sink(i).get).asUInt 126 } else { 127 0.U.asTypeOf(sink(i).get).asUInt 128 } 129 }.reduce(_ | _) 130 } 131 } 132 } 133 134 135 136 //per wbPort fuBusyTable 137 writeBusyTable(intWbBusyTable, intAllBusyTableWithParms, IntWB()) 138 writeBusyTable(fpWbBusyTable, fpAllBusyTableWithParms, FpWB()) 139 writeBusyTable(vfWbBusyTable, vfAllBusyTableWithParms, VfWB()) 140 writeBusyTable(v0WbBusyTable, v0AllBusyTableWithParms, V0WB()) 141 writeBusyTable(vlWbBusyTable, vlAllBusyTableWithParms, VlWB()) 142 //per wbPort conflict 143 writeConflict(intConflict, intAllDeqRespSetWithParms, IntWB()) 144 writeConflict(fpConflict, fpAllDeqRespSetWithParms, FpWB()) 145 writeConflict(vfConflict, vfAllDeqRespSetWithParms, VfWB()) 146 writeConflict(v0Conflict, v0AllDeqRespSetWithParms, V0WB()) 147 writeConflict(vlConflict, vlAllDeqRespSetWithParms, VlWB()) 148 //read wbPort fuBusyTable to per exe 149 readRes(intAllRespRead, intWbBusyTable, IntWB()) 150 readRes(fpAllRespRead, fpWbBusyTable, FpWB()) 151 readRes(vfAllRespRead, vfWbBusyTable, VfWB()) 152 readRes(v0AllRespRead, v0WbBusyTable, V0WB()) 153 readRes(vlAllRespRead, vlWbBusyTable, VlWB()) 154 //read wbPort conflict to dataPath 155 readRes(intAllWbConflictFlag, intConflict, IntWB()) 156 readRes(fpAllWbConflictFlag, fpConflict, FpWB()) 157 readRes(vfAllWbConflictFlag, vfConflict, VfWB()) 158 readRes(v0AllWbConflictFlag, v0Conflict, V0WB()) 159 readRes(vlAllWbConflictFlag, vlConflict, VlWB()) 160} 161 162class WbFuBusyTableIO(implicit p: Parameters, params: BackendParams) extends XSBundle { 163 val in = new Bundle { 164 val intSchdBusyTable = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle))) 165 val fpSchdBusyTable = MixedVec(params.fpSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle))) 166 val vfSchdBusyTable = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle))) 167 val memSchdBusyTable = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle))) 168 } 169 val out = new Bundle { 170 val intRespRead = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle))) 171 val fpRespRead = MixedVec(params.fpSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle))) 172 val vfRespRead = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle))) 173 val memRespRead = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle))) 174 val wbConflictRead = MixedVec(params.allSchdParams.map(x => MixedVec(x.issueBlockParams.map(x => Output(x.genWbConflictBundle()))))) 175 } 176}