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 implicit val params: BackendParams = bp 18 lazy val module = new WbFuBusyTableImp(this) 19} 20 21class WbFuBusyTableImp(override val wrapper: WbFuBusyTable)(implicit p: Parameters, params: BackendParams) extends LazyModuleImp(wrapper) { 22 val io = IO(new WbFuBusyTableIO) 23 24 private val intSchdBusyTable = io.in.intSchdBusyTable 25 private val vfSchdBusyTable = io.in.vfSchdBusyTable 26 private val memSchdBusyTable = io.in.memSchdBusyTable 27 private val intRespRead = io.out.intRespRead 28 private val vfRespRead = io.out.vfRespRead 29 private val memRespRead = io.out.memRespRead 30 private val intAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.intConflict) 31 private val vfAllWbConflictFlag = io.out.wbConflictRead.flatten.flatten.map(_.vfConflict) 32 33 private val intAllBusyTable = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intWbBusyTable) 34 private val vfAllBusyTable = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfWbBusyTable) 35 private val intAllDeqRespSet = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.intDeqRespSet) 36 private val vfAllDeqRespSet = (intSchdBusyTable ++ vfSchdBusyTable ++ memSchdBusyTable).flatten.map(_.vfDeqRespSet) 37 private val intAllRespRead = (intRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.intWbBusyTable) 38 private val vfAllRespRead = (intRespRead ++ vfRespRead ++ memRespRead).flatten.map(_.vfWbBusyTable) 39 40 private val allExuParams = params.allExuParams 41 private val intAllBusyTableWithParms = intAllBusyTable.zip(allExuParams).toSeq 42 private val vfAllBusyTableWithParms = vfAllBusyTable.zip(allExuParams).toSeq 43 private val intAllDeqRespSetWithParms = intAllDeqRespSet.zip(allExuParams).toSeq 44 private val vfAllDeqRespSetWithParms = vfAllDeqRespSet.zip(allExuParams).toSeq 45 46 private val intWbLatencyMax = params.getIntWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.intLatencyValMax).max, seq.forall(_.intLatencyCertain)) } 47 private val vfWbLatencyMax = params.getVfWBExeGroup.map { case (portId, seq) => (portId, seq.map(_.vfLatencyValMax).max, seq.forall(_.vfLatencyCertain)) } 48 private val intWbBusyTable: Map[Int, Option[UInt]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap 49 private val vfWbBusyTable = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Wire(UInt((latMax + 1).W)))) }.toMap 50 private val intConflict: Map[Int, Option[Bool]] = intWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap 51 private val vfConflict = vfWbLatencyMax.map { case (portId, latMax, latCertain) => (portId, OptionWrapper(latCertain, Reg(Bool()))) }.toMap 52 53 def hitWbPort[T <: Data](source: Option[T], p: ExeUnitParams, portId: Int, isInt: Boolean) = { 54 if(isInt){ 55 p.wbPortConfigs.collectFirst { case x : IntWB => x.port }.getOrElse(-1) == portId && source.nonEmpty 56 } else { 57 p.wbPortConfigs.collectFirst { case x : VfWB => x.port }.getOrElse(-1) == portId && source.nonEmpty 58 } 59 } 60 61 def writeBusyTable(wtBusyTable: Map[Int, Option[UInt]], busyTableWithParams: Seq[(Option[UInt], ExeUnitParams)], isInt: Boolean) = { 62 wtBusyTable.foreach { case (portId, busyTable) => 63 if (busyTable.nonEmpty) { 64 busyTable.get := busyTableWithParams.filter { case (busyTable, p) => hitWbPort(busyTable, p, portId, isInt) }.map(_._1.get).reduce(_ | _) 65 } 66 } 67 } 68 69 def writeConflict(wtConflict: Map[Int, Option[Bool]], deqRespSetWithParams: Seq[(Option[UInt], ExeUnitParams)], isInt: Boolean) = { 70 wtConflict.foreach { case (portId, conflict) => 71 if (conflict.nonEmpty) { 72 val deqRespSel = deqRespSetWithParams.filter { case (deqRespSet, p) => hitWbPort(deqRespSet, p, portId, isInt) }.map(_._1.get) 73 val width = deqRespSel.map(x => x.getWidth).max 74 val deqRespSelUnify = deqRespSel.map(x => x.asTypeOf(UInt(width.W))).toSeq 75 conflict.get := (0 until width).map{ case i => 76 OnesMoreThan(deqRespSelUnify.map(x => x(i)), 2) 77 }.reduce(_ | _) 78 } 79 } 80 } 81 82 def readRes[T <: Data](sink: IndexedSeq[Option[T]], source: Map[Int, Option[T]], isInt: Boolean) = { 83 for(i <- 0 until sink.size) { 84 if(sink(i).nonEmpty) { 85 sink(i).get := source.map { case (portId, src) => 86 if(hitWbPort(src, allExuParams(i), portId, isInt)) { 87 src.get.asTypeOf(sink(i).get).asUInt 88 } else { 89 0.U.asTypeOf(sink(i).get).asUInt 90 } 91 }.reduce(_ | _) 92 } 93 } 94 } 95 96 97 98 //per wbPort fuBusyTable 99 writeBusyTable(intWbBusyTable, intAllBusyTableWithParms, true) 100 writeBusyTable(vfWbBusyTable, vfAllBusyTableWithParms, false) 101 //per wbPort conflict 102 writeConflict(intConflict, intAllDeqRespSetWithParms, true) 103 writeConflict(vfConflict, vfAllDeqRespSetWithParms, false) 104 //read wbPort fuBusyTable to per exe 105 readRes(intAllRespRead, intWbBusyTable, true) 106 readRes(vfAllRespRead, vfWbBusyTable, false) 107 //read wbPort conflict to dataPath 108 readRes(intAllWbConflictFlag, intConflict, true) 109 readRes(vfAllWbConflictFlag, vfConflict, false) 110 111} 112 113class WbFuBusyTableIO(implicit p: Parameters, params: BackendParams) extends XSBundle { 114 val in = new Bundle { 115 val intSchdBusyTable = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle))) 116 val vfSchdBusyTable = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle))) 117 val memSchdBusyTable = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Input(x.genWbFuBusyTableWriteBundle))) 118 } 119 val out = new Bundle { 120 val intRespRead = MixedVec(params.intSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle))) 121 val vfRespRead = MixedVec(params.vfSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle))) 122 val memRespRead = MixedVec(params.memSchdParams.get.issueBlockParams.map(x => Output(x.genWbFuBusyTableReadBundle))) 123 val wbConflictRead = MixedVec(params.allSchdParams.map(x => MixedVec(x.issueBlockParams.map(x => Output(x.genWbConflictBundle()))))) 124 } 125}