xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/WbFuBusyTable.scala (revision 45d40ce719a8202e16a540541c72fd4de6dfde60)
1dd970561SzhanglyGitpackage xiangshan.backend.datapath
2dd970561SzhanglyGit
383ba63b3SXuan Huimport scala.collection.Seq
483ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
5dd970561SzhanglyGitimport chisel3._
6dd970561SzhanglyGitimport chisel3.util._
77f847969SzhanglyGitimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
87f847969SzhanglyGitimport utility._
9dd970561SzhanglyGitimport utils.OptionWrapper
10dd970561SzhanglyGitimport xiangshan._
11dd970561SzhanglyGitimport xiangshan.backend._
12dd970561SzhanglyGitimport xiangshan.backend.datapath.WbConfig._
13dd970561SzhanglyGitimport xiangshan.backend.exu.ExeUnitParams
1483ba63b3SXuan Huimport xiangshan.backend.implicitCast._
15dd970561SzhanglyGit
167f847969SzhanglyGitclass WbFuBusyTable(bp: BackendParams)(implicit  p: Parameters) extends LazyModule {
171ca4a39dSXuan Hu  override def shouldBeInlined: Boolean = false
187f847969SzhanglyGit  implicit val params: BackendParams = bp
197f847969SzhanglyGit  lazy val module = new WbFuBusyTableImp(this)
207f847969SzhanglyGit}
217f847969SzhanglyGit
227f847969SzhanglyGitclass WbFuBusyTableImp(override val wrapper: WbFuBusyTable)(implicit  p: Parameters, params: BackendParams) extends LazyModuleImp(wrapper) {
23dd970561SzhanglyGit  val io = IO(new WbFuBusyTableIO)
24dd970561SzhanglyGit
25dd970561SzhanglyGit  private val intSchdBusyTable = io.in.intSchdBusyTable
2660f0c5aeSxiaofeibao  private val fpSchdBusyTable = io.in.fpSchdBusyTable
27dd970561SzhanglyGit  private val vfSchdBusyTable = io.in.vfSchdBusyTable
28dd970561SzhanglyGit  private val memSchdBusyTable = io.in.memSchdBusyTable
29dd970561SzhanglyGit  private val intRespRead = io.out.intRespRead
3060f0c5aeSxiaofeibao  private val fpRespRead = io.out.fpRespRead
31dd970561SzhanglyGit  private val vfRespRead = io.out.vfRespRead
32dd970561SzhanglyGit  private val memRespRead = io.out.memRespRead
33dd970561SzhanglyGit  private val intAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.intConflict)
3460f0c5aeSxiaofeibao  private val fpAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.fpConflict)
35dd970561SzhanglyGit  private val vfAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.vfConflict)
36*45d40ce7Ssinsanction  private val v0AllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.v0Conflict)
37*45d40ce7Ssinsanction  private val vlAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.vlConflict)
38dd970561SzhanglyGit
3960f0c5aeSxiaofeibao  private val intAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intWbBusyTable)
4060f0c5aeSxiaofeibao  private val fpAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.fpWbBusyTable)
4160f0c5aeSxiaofeibao  private val vfAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfWbBusyTable)
42*45d40ce7Ssinsanction  private val v0AllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.v0WbBusyTable)
43*45d40ce7Ssinsanction  private val vlAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vlWbBusyTable)
44*45d40ce7Ssinsanction
4560f0c5aeSxiaofeibao  private val intAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intDeqRespSet)
4660f0c5aeSxiaofeibao  private val fpAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.fpDeqRespSet)
4760f0c5aeSxiaofeibao  private val vfAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfDeqRespSet)
48*45d40ce7Ssinsanction  private val v0AllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.v0DeqRespSet)
49*45d40ce7Ssinsanction  private val vlAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vlDeqRespSet)
50*45d40ce7Ssinsanction
5160f0c5aeSxiaofeibao  private val intAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.intWbBusyTable)
5260f0c5aeSxiaofeibao  private val fpAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.fpWbBusyTable)
5360f0c5aeSxiaofeibao  private val vfAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.vfWbBusyTable)
54*45d40ce7Ssinsanction  private val v0AllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.v0WbBusyTable)
55*45d40ce7Ssinsanction  private val vlAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.vlWbBusyTable)
56dd970561SzhanglyGit
57dd970561SzhanglyGit  private val allExuParams = params.allExuParams
5883ba63b3SXuan Hu  private val intAllBusyTableWithParms = intAllBusyTable.zip(allExuParams).toSeq
5960f0c5aeSxiaofeibao  private val fpAllBusyTableWithParms = fpAllBusyTable.zip(allExuParams).toSeq
6083ba63b3SXuan Hu  private val vfAllBusyTableWithParms = vfAllBusyTable.zip(allExuParams).toSeq
61*45d40ce7Ssinsanction  private val v0AllBusyTableWithParms = v0AllBusyTable.zip(allExuParams).toSeq
62*45d40ce7Ssinsanction  private val vlAllBusyTableWithParms = vlAllBusyTable.zip(allExuParams).toSeq
63*45d40ce7Ssinsanction
6483ba63b3SXuan Hu  private val intAllDeqRespSetWithParms = intAllDeqRespSet.zip(allExuParams).toSeq
6560f0c5aeSxiaofeibao  private val fpAllDeqRespSetWithParms = fpAllDeqRespSet.zip(allExuParams).toSeq
6683ba63b3SXuan Hu  private val vfAllDeqRespSetWithParms = vfAllDeqRespSet.zip(allExuParams).toSeq
67*45d40ce7Ssinsanction  private val v0AllDeqRespSetWithParms = v0AllDeqRespSet.zip(allExuParams).toSeq
68*45d40ce7Ssinsanction  private val vlAllDeqRespSetWithParms = vlAllDeqRespSet.zip(allExuParams).toSeq
69dd970561SzhanglyGit
70dd970561SzhanglyGit  private val intWbLatencyMax = params.getIntWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.intLatencyValMax).max, seq.forall(_.intLatencyCertain)) }
7160f0c5aeSxiaofeibao  private val fpWbLatencyMax = params.getFpWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.fpLatencyValMax).max, seq.forall(_.fpLatencyCertain)) }
72dd970561SzhanglyGit  private val vfWbLatencyMax = params.getVfWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.vfLatencyValMax).max, seq.forall(_.vfLatencyCertain)) }
73*45d40ce7Ssinsanction  private val v0WbLatencyMax = params.getV0WBExeGroup.map { case (portId, seq) => (portId, seq.map(_.v0LatencyValMax).max, seq.forall(_.v0LatencyCertain)) }
74*45d40ce7Ssinsanction  private val vlWbLatencyMax = params.getVlWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.vlLatencyValMax).max, seq.forall(_.vlLatencyCertain)) }
75*45d40ce7Ssinsanction
767f847969SzhanglyGit  private val intWbBusyTable: Map[Int, Option[UInt]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
7760f0c5aeSxiaofeibao  private val fpWbBusyTable = fpWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
787f847969SzhanglyGit  private val vfWbBusyTable = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
79*45d40ce7Ssinsanction  private val v0WbBusyTable = v0WbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
80*45d40ce7Ssinsanction  private val vlWbBusyTable = vlWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
81*45d40ce7Ssinsanction
827f847969SzhanglyGit  private val intConflict: Map[Int, Option[Bool]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
8360f0c5aeSxiaofeibao  private val fpConflict = fpWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
847f847969SzhanglyGit  private val vfConflict = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
85*45d40ce7Ssinsanction  private val v0Conflict = v0WbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
86*45d40ce7Ssinsanction  private val vlConflict = vlWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
87dd970561SzhanglyGit
8860f0c5aeSxiaofeibao  def hitWbPort[T <: Data](source: Option[T], p: ExeUnitParams, portId: Int, wbType: PregWB) = {
8960f0c5aeSxiaofeibao    wbType match {
9060f0c5aeSxiaofeibao      case IntWB(_, _) => p.wbPortConfigs.collectFirst { case x: IntWB => x.port }.getOrElse(-1) == portId && source.nonEmpty
9160f0c5aeSxiaofeibao      case FpWB(_, _) => p.wbPortConfigs.collectFirst { case x: FpWB => x.port }.getOrElse(-1) == portId && source.nonEmpty
9260f0c5aeSxiaofeibao      case VfWB(_, _) => p.wbPortConfigs.collectFirst { case x: VfWB => x.port }.getOrElse(-1) == portId && source.nonEmpty
93*45d40ce7Ssinsanction      case V0WB(_, _) => p.wbPortConfigs.collectFirst { case x: V0WB => x.port }.getOrElse(-1) == portId && source.nonEmpty
94*45d40ce7Ssinsanction      case VlWB(_, _) => p.wbPortConfigs.collectFirst { case x: VlWB => x.port }.getOrElse(-1) == portId && source.nonEmpty
95*45d40ce7Ssinsanction      case _ => throw new IllegalArgumentException(s"WbConfig ${wbType} is not permitted")
967f847969SzhanglyGit    }
97dd970561SzhanglyGit  }
98dd970561SzhanglyGit
9960f0c5aeSxiaofeibao  def writeBusyTable(wtBusyTable: Map[Int, Option[UInt]], busyTableWithParams: Seq[(Option[UInt], ExeUnitParams)], wbType: PregWB) = {
1007f847969SzhanglyGit    wtBusyTable.foreach { case (portId, busyTable) =>
101dd970561SzhanglyGit      if (busyTable.nonEmpty) {
10260f0c5aeSxiaofeibao        busyTable.get := busyTableWithParams.filter { case (busyTable, p) => hitWbPort(busyTable, p, portId, wbType) }.map(_._1.get).reduce(_ | _)
103dd970561SzhanglyGit      }
104dd970561SzhanglyGit    }
105dd970561SzhanglyGit  }
106dd970561SzhanglyGit
10760f0c5aeSxiaofeibao  def writeConflict(wtConflict: Map[Int, Option[Bool]], deqRespSetWithParams: Seq[(Option[UInt], ExeUnitParams)], wbType: PregWB) = {
1087f847969SzhanglyGit    wtConflict.foreach { case (portId, conflict) =>
1097f847969SzhanglyGit      if (conflict.nonEmpty) {
11060f0c5aeSxiaofeibao        val deqRespSel = deqRespSetWithParams.filter { case (deqRespSet, p) => hitWbPort(deqRespSet, p, portId, wbType) }.map(_._1.get)
1117f847969SzhanglyGit        val width = deqRespSel.map(x => x.getWidth).max
11283ba63b3SXuan Hu        val deqRespSelUnify = deqRespSel.map(x => x.asTypeOf(UInt(width.W))).toSeq
1137f847969SzhanglyGit        conflict.get := (0 until width).map { case i =>
1147f847969SzhanglyGit          OnesMoreThan(deqRespSelUnify.map(x => x(i)), 2)
1157f847969SzhanglyGit        }.reduce(_ | _)
1167f847969SzhanglyGit      }
1177f847969SzhanglyGit    }
1187f847969SzhanglyGit  }
1197f847969SzhanglyGit
12060f0c5aeSxiaofeibao  def readRes[T <: Data](sink: IndexedSeq[Option[T]], source: Map[Int, Option[T]], wbType: PregWB) = {
121dd970561SzhanglyGit    for (i <- 0 until sink.size) {
122dd970561SzhanglyGit      if (sink(i).nonEmpty) {
1237f847969SzhanglyGit        sink(i).get := source.map { case (portId, src) =>
12460f0c5aeSxiaofeibao          if (hitWbPort(src, allExuParams(i), portId, wbType)) {
125dd970561SzhanglyGit            src.get.asTypeOf(sink(i).get).asUInt
126dd970561SzhanglyGit          } else {
127dd970561SzhanglyGit            0.U.asTypeOf(sink(i).get).asUInt
128dd970561SzhanglyGit          }
1297f847969SzhanglyGit        }.reduce(_ | _)
130dd970561SzhanglyGit      }
131dd970561SzhanglyGit    }
132dd970561SzhanglyGit  }
133dd970561SzhanglyGit
1347f847969SzhanglyGit
1357f847969SzhanglyGit
1367f847969SzhanglyGit  //per wbPort fuBusyTable
13760f0c5aeSxiaofeibao  writeBusyTable(intWbBusyTable, intAllBusyTableWithParms, IntWB())
13860f0c5aeSxiaofeibao  writeBusyTable(fpWbBusyTable, fpAllBusyTableWithParms, FpWB())
13960f0c5aeSxiaofeibao  writeBusyTable(vfWbBusyTable, vfAllBusyTableWithParms, VfWB())
140*45d40ce7Ssinsanction  writeBusyTable(v0WbBusyTable, v0AllBusyTableWithParms, V0WB())
141*45d40ce7Ssinsanction  writeBusyTable(vlWbBusyTable, vlAllBusyTableWithParms, VlWB())
1427f847969SzhanglyGit  //per wbPort conflict
14360f0c5aeSxiaofeibao  writeConflict(intConflict, intAllDeqRespSetWithParms, IntWB())
14460f0c5aeSxiaofeibao  writeConflict(fpConflict, fpAllDeqRespSetWithParms, FpWB())
14560f0c5aeSxiaofeibao  writeConflict(vfConflict, vfAllDeqRespSetWithParms, VfWB())
146*45d40ce7Ssinsanction  writeConflict(v0Conflict, v0AllDeqRespSetWithParms, V0WB())
147*45d40ce7Ssinsanction  writeConflict(vlConflict, vlAllDeqRespSetWithParms, VlWB())
148dd970561SzhanglyGit  //read wbPort fuBusyTable to per exe
14960f0c5aeSxiaofeibao  readRes(intAllRespRead, intWbBusyTable, IntWB())
15060f0c5aeSxiaofeibao  readRes(fpAllRespRead, fpWbBusyTable, FpWB())
15160f0c5aeSxiaofeibao  readRes(vfAllRespRead, vfWbBusyTable, VfWB())
152*45d40ce7Ssinsanction  readRes(v0AllRespRead, v0WbBusyTable, V0WB())
153*45d40ce7Ssinsanction  readRes(vlAllRespRead, vlWbBusyTable, VlWB())
154dd970561SzhanglyGit  //read wbPort conflict to dataPath
15560f0c5aeSxiaofeibao  readRes(intAllWbConflictFlag, intConflict, IntWB())
15660f0c5aeSxiaofeibao  readRes(fpAllWbConflictFlag, fpConflict, FpWB())
15760f0c5aeSxiaofeibao  readRes(vfAllWbConflictFlag, vfConflict, VfWB())
158*45d40ce7Ssinsanction  readRes(v0AllWbConflictFlag, v0Conflict, V0WB())
159*45d40ce7Ssinsanction  readRes(vlAllWbConflictFlag, vlConflict, VlWB())
160dd970561SzhanglyGit}
161dd970561SzhanglyGit
162dd970561SzhanglyGitclass WbFuBusyTableIO(implicit p: Parameters, params: BackendParams) extends XSBundle {
163dd970561SzhanglyGit  val in = new Bundle {
164dd970561SzhanglyGit    val intSchdBusyTable = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
16560f0c5aeSxiaofeibao    val fpSchdBusyTable = MixedVec(params.fpSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
166dd970561SzhanglyGit    val vfSchdBusyTable = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
167dd970561SzhanglyGit    val memSchdBusyTable = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
168dd970561SzhanglyGit  }
169dd970561SzhanglyGit  val out = new Bundle {
170dd970561SzhanglyGit    val intRespRead = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
17160f0c5aeSxiaofeibao    val fpRespRead = MixedVec(params.fpSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
172dd970561SzhanglyGit    val vfRespRead = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
173dd970561SzhanglyGit    val memRespRead = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
174dd970561SzhanglyGit    val wbConflictRead = MixedVec(params.allSchdParams.map(x => MixedVec(x.issueBlockParams.map(x => Output(x.genWbConflictBundle())))))
175dd970561SzhanglyGit  }
176dd970561SzhanglyGit}