xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/WbFuBusyTable.scala (revision 4daa5bf3c3f27e7fd090866d52405b21e107eb8d)
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
37  private val intAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intWbBusyTable)
38  private val fpAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.fpWbBusyTable)
39  private val vfAllBusyTable = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfWbBusyTable)
40  private val intAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intDeqRespSet)
41  private val fpAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.fpDeqRespSet)
42  private val vfAllDeqRespSet = (intSchdBusyTable ++ fpSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfDeqRespSet)
43  private val intAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.intWbBusyTable)
44  private val fpAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.fpWbBusyTable)
45  private val vfAllRespRead = (intRespRead ++ fpRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.vfWbBusyTable)
46
47  private val allExuParams = params.allExuParams
48  private val intAllBusyTableWithParms = intAllBusyTable.zip(allExuParams).toSeq
49  private val fpAllBusyTableWithParms = fpAllBusyTable.zip(allExuParams).toSeq
50  private val vfAllBusyTableWithParms = vfAllBusyTable.zip(allExuParams).toSeq
51  private val intAllDeqRespSetWithParms = intAllDeqRespSet.zip(allExuParams).toSeq
52  private val fpAllDeqRespSetWithParms = fpAllDeqRespSet.zip(allExuParams).toSeq
53  private val vfAllDeqRespSetWithParms = vfAllDeqRespSet.zip(allExuParams).toSeq
54
55  private val intWbLatencyMax = params.getIntWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.intLatencyValMax).max, seq.forall(_.intLatencyCertain)) }
56  private val fpWbLatencyMax = params.getFpWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.fpLatencyValMax).max, seq.forall(_.fpLatencyCertain)) }
57  private val vfWbLatencyMax = params.getVfWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.vfLatencyValMax).max, seq.forall(_.vfLatencyCertain)) }
58  private val intWbBusyTable: Map[Int, Option[UInt]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
59  private val fpWbBusyTable = fpWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
60  private val vfWbBusyTable = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap
61  private val intConflict: Map[Int, Option[Bool]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
62  private val fpConflict = fpWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
63  private val vfConflict = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap
64
65  def hitWbPort[T <: Data](source: Option[T], p: ExeUnitParams, portId: Int, wbType: PregWB) = {
66    wbType match {
67      case IntWB(_, _) => p.wbPortConfigs.collectFirst { case x: IntWB => x.port }.getOrElse(-1) == portId && source.nonEmpty
68      case FpWB(_, _) => p.wbPortConfigs.collectFirst { case x: FpWB => x.port }.getOrElse(-1) == portId && source.nonEmpty
69      case VfWB(_, _) => p.wbPortConfigs.collectFirst { case x: VfWB => x.port }.getOrElse(-1) == portId && source.nonEmpty
70    }
71  }
72
73  def writeBusyTable(wtBusyTable: Map[Int, Option[UInt]], busyTableWithParams: Seq[(Option[UInt], ExeUnitParams)], wbType: PregWB) = {
74    wtBusyTable.foreach { case (portId, busyTable) =>
75      if (busyTable.nonEmpty) {
76        busyTable.get := busyTableWithParams.filter { case (busyTable, p) => hitWbPort(busyTable, p, portId, wbType) }.map(_._1.get).reduce(_ | _)
77      }
78    }
79  }
80
81  def writeConflict(wtConflict: Map[Int, Option[Bool]], deqRespSetWithParams: Seq[(Option[UInt], ExeUnitParams)], wbType: PregWB) = {
82    wtConflict.foreach { case (portId, conflict) =>
83      if (conflict.nonEmpty) {
84        val deqRespSel = deqRespSetWithParams.filter { case (deqRespSet, p) => hitWbPort(deqRespSet, p, portId, wbType) }.map(_._1.get)
85        val width = deqRespSel.map(x => x.getWidth).max
86        val deqRespSelUnify = deqRespSel.map(x => x.asTypeOf(UInt(width.W))).toSeq
87        conflict.get := (0 until width).map { case i =>
88          OnesMoreThan(deqRespSelUnify.map(x => x(i)), 2)
89        }.reduce(_ | _)
90      }
91    }
92  }
93
94  def readRes[T <: Data](sink: IndexedSeq[Option[T]], source: Map[Int, Option[T]], wbType: PregWB) = {
95    for (i <- 0 until sink.size) {
96      if (sink(i).nonEmpty) {
97        sink(i).get := source.map { case (portId, src) =>
98          if (hitWbPort(src, allExuParams(i), portId, wbType)) {
99            src.get.asTypeOf(sink(i).get).asUInt
100          } else {
101            0.U.asTypeOf(sink(i).get).asUInt
102          }
103        }.reduce(_ | _)
104      }
105    }
106  }
107
108
109
110  //per wbPort fuBusyTable
111  writeBusyTable(intWbBusyTable, intAllBusyTableWithParms, IntWB())
112  writeBusyTable(fpWbBusyTable, fpAllBusyTableWithParms, FpWB())
113  writeBusyTable(vfWbBusyTable, vfAllBusyTableWithParms, VfWB())
114  //per wbPort conflict
115  writeConflict(intConflict, intAllDeqRespSetWithParms, IntWB())
116  writeConflict(fpConflict, fpAllDeqRespSetWithParms, FpWB())
117  writeConflict(vfConflict, vfAllDeqRespSetWithParms, VfWB())
118  //read wbPort fuBusyTable to per exe
119  readRes(intAllRespRead, intWbBusyTable, IntWB())
120  readRes(fpAllRespRead, fpWbBusyTable, FpWB())
121  readRes(vfAllRespRead, vfWbBusyTable, VfWB())
122  //read wbPort conflict to dataPath
123  readRes(intAllWbConflictFlag, intConflict, IntWB())
124  readRes(fpAllWbConflictFlag, fpConflict, FpWB())
125  readRes(vfAllWbConflictFlag, vfConflict, VfWB())
126
127}
128
129class WbFuBusyTableIO(implicit p: Parameters, params: BackendParams) extends XSBundle {
130  val in = new Bundle {
131    val intSchdBusyTable = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
132    val fpSchdBusyTable = MixedVec(params.fpSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
133    val vfSchdBusyTable = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
134    val memSchdBusyTable = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
135  }
136  val out = new Bundle {
137    val intRespRead = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
138    val fpRespRead = MixedVec(params.fpSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
139    val vfRespRead = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
140    val memRespRead = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
141    val wbConflictRead = MixedVec(params.allSchdParams.map(x => MixedVec(x.issueBlockParams.map(x => Output(x.genWbConflictBundle())))))
142  }
143}