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}