xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/WbFuBusyTable.scala (revision dd9705615c0460cbe2cb82682b4c4296d66daf2c)
1package xiangshan.backend.datapath
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import chisel3.util._
6import utils.OptionWrapper
7import xiangshan._
8import xiangshan.backend._
9import xiangshan.backend.datapath.WbConfig._
10import xiangshan.backend.exu.ExeUnitParams
11
12class WbFuBusyTable(implicit  p: Parameters, params: BackendParams) extends XSModule {
13  val io = IO(new WbFuBusyTableIO)
14
15  private val intSchdBusyTable = io.in.intSchdBusyTable
16  private val vfSchdBusyTable = io.in.vfSchdBusyTable
17  private val memSchdBusyTable = io.in.memSchdBusyTable
18  private val intRespRead = io.out.intRespRead
19  private val vfRespRead = io.out.vfRespRead
20  private val memRespRead = io.out.memRespRead
21  private val intAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.intConflict)
22  private val vfAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.vfConflict)
23
24  private val intAllBusyTable = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intWbBusyTable)
25  private val vfAllBusyTable = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfWbBusyTable)
26  private val intAllDeqRespSet = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intDeqRespSet)
27  private val vfAllDeqRespSet = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfDeqRespSet)
28  private val intAllRespRead = (intRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.intWbBusyTable)
29  private val vfAllRespRead = (intRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.vfWbBusyTable)
30
31  private val allExuParams = params.allExuParams
32  private val intAllBusyTableWithParms = intAllBusyTable.zip(allExuParams)
33  private val vfAllBusyTableWithParms = vfAllBusyTable.zip(allExuParams)
34  private val intAllDeqRespSetWithParms = intAllDeqRespSet.zip(allExuParams)
35  private val vfAllDeqRespSetWithParms = vfAllDeqRespSet.zip(allExuParams)
36
37  private val intWbLatencyMax = params.getIntWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.intLatencyValMax).max, seq.forall(_.intLatencyCertain)) }
38  private val vfWbLatencyMax = params.getVfWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.vfLatencyValMax).max, seq.forall(_.vfLatencyCertain)) }
39  private val intWbBundle = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W))), OptionWrapper(latCertain, Reg(Bool()))) }.toSeq
40  private val vfWbBundle = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W))), OptionWrapper(latCertain, Reg(Bool()))) }.toSeq
41
42  def hitWbPort(source: Option[UInt], p: ExeUnitParams, portId: Int) = {
43    p.wbPortConfigs.collectFirst { case x => x.port }.getOrElse(-1) == portId && source.nonEmpty
44  }
45
46  def writeWbBundle(wbBundle: Seq[(Int, Option[UInt], Option[Bool])], busyTableWithParams: IndexedSeq[(Option[UInt], ExeUnitParams)], deqRespSetWithParams: IndexedSeq[(Option[UInt], ExeUnitParams)]) = {
47    wbBundle.map { case (portId, busyTable, conflict) =>
48      if (busyTable.nonEmpty) {
49        busyTable.get := busyTableWithParams.filter { case (busyTable, p) => hitWbPort(busyTable, p, portId) }.map(_._1.get).reduce(_ | _)
50        conflict.get := deqRespSetWithParams.filter { case (deqRespSet, p) => hitWbPort(deqRespSet, p, portId) }.map(_._1.get).reduce(_ & _).orR
51      }
52    }
53  }
54
55  def readWbBundle[T <: Data](sink: IndexedSeq[Option[T]], wbBundle: Seq[(Int, Option[UInt], Option[Bool])]) = {
56    for (i <- 0 until sink.size) {
57      if(sink(i).nonEmpty) {
58        sink(i).get := wbBundle.map { case (portId, busyTable, conflictFlag) =>
59          val src = if (sink(i).get.isInstanceOf[UInt]) busyTable else conflictFlag
60          if (hitWbPort(src, allExuParams(i), portId)) {
61            src.get.asTypeOf(sink(i).get).asUInt
62          } else {
63            0.U.asTypeOf(sink(i).get).asUInt
64          }
65        }.reduce(_.asUInt | _.asUInt)
66      }
67    }
68  }
69
70  //per wbPort fuBusyTable and conflict gen
71  writeWbBundle(intWbBundle, intAllBusyTableWithParms, intAllDeqRespSetWithParms)
72  writeWbBundle(vfWbBundle, vfAllBusyTableWithParms, vfAllDeqRespSetWithParms)
73  //read wbPort fuBusyTable to per exe
74  readWbBundle(intAllRespRead, intWbBundle)
75  readWbBundle(vfAllRespRead, vfWbBundle)
76  //read wbPort conflict to dataPath
77  readWbBundle(intAllWbConflictFlag, intWbBundle)
78  readWbBundle(vfAllWbConflictFlag, vfWbBundle)
79
80}
81
82class WbFuBusyTableIO(implicit p: Parameters, params: BackendParams) extends XSBundle {
83  val in = new Bundle {
84    val intSchdBusyTable = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
85    val vfSchdBusyTable = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
86    val memSchdBusyTable = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle)))
87  }
88  val out = new Bundle {
89    val intRespRead = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
90    val vfRespRead = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
91    val memRespRead = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle)))
92    val wbConflictRead = MixedVec(params.allSchdParams.map(x => MixedVec(x.issueBlockParams.map(x => Output(x.genWbConflictBundle())))))
93  }
94}