xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/WbFuBusyTable.scala (revision 45d40ce719a8202e16a540541c72fd4de6dfde60)
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}