1package xiangshan.backend.datapath 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.{GatedValidRegNext, SignExt, ZeroExt} 7import xiangshan.{XSBundle, XSModule} 8import xiangshan.backend.BackendParams 9import xiangshan.backend.Bundles.{ExuBypassBundle, ExuInput, ExuOutput, ExuVec, ImmInfo} 10import xiangshan.backend.issue.{FpScheduler, ImmExtractor, IntScheduler, MemScheduler, VfScheduler} 11import xiangshan.backend.datapath.DataConfig.RegDataMaxWidth 12import xiangshan.backend.decode.ImmUnion 13import xiangshan.backend.regcache._ 14 15class BypassNetworkIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 16 // params 17 private val intSchdParams = params.schdParams(IntScheduler()) 18 private val fpSchdParams = params.schdParams(FpScheduler()) 19 private val vfSchdParams = params.schdParams(VfScheduler()) 20 private val memSchdParams = params.schdParams(MemScheduler()) 21 22 val fromDataPath = new FromDataPath 23 val toExus = new ToExus 24 val fromExus = new FromExus 25 26 class FromDataPath extends Bundle { 27 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(intSchdParams.genExuInputBundle) 28 val fp : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(fpSchdParams.genExuInputBundle) 29 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(vfSchdParams.genExuInputBundle) 30 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(memSchdParams.genExuInputBundle) 31 val immInfo: Vec[ImmInfo] = Input(Vec(params.allExuParams.size, new ImmInfo)) 32 val rcData: MixedVec[MixedVec[Vec[UInt]]] = MixedVec( 33 Seq(intSchdParams, fpSchdParams, vfSchdParams, memSchdParams).map(schd => schd.issueBlockParams.map(iq => 34 MixedVec(iq.exuBlockParams.map(exu => Input(Vec(exu.numRegSrc, UInt(exu.srcDataBitsMax.W))))) 35 )).flatten 36 ) 37 } 38 39 class ToExus extends Bundle { 40 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = intSchdParams.genExuInputBundle 41 val fp : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = fpSchdParams.genExuInputBundle 42 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = vfSchdParams.genExuInputBundle 43 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = memSchdParams.genExuInputBundle 44 } 45 46 class FromExus extends Bundle { 47 val int: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(intSchdParams.genExuBypassValidBundle) 48 val fp : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(fpSchdParams.genExuBypassValidBundle) 49 val vf : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(vfSchdParams.genExuBypassValidBundle) 50 val mem: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(memSchdParams.genExuBypassValidBundle) 51 52 def connectExuOutput( 53 getSinkVecN: FromExus => MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] 54 )( 55 sourceVecN: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] 56 ): Unit = { 57 getSinkVecN(this).zip(sourceVecN).foreach { case (sinkVec, sourcesVec) => 58 sinkVec.zip(sourcesVec).foreach { case (sink, source) => 59 sink.valid := source.valid 60 sink.bits.intWen := source.bits.intWen.getOrElse(false.B) 61 sink.bits.pdest := source.bits.pdest 62 sink.bits.data := source.bits.data(0) 63 } 64 } 65 } 66 } 67 68 val toDataPath: Vec[RCWritePort] = Vec(params.getIntExuRCWriteSize + params.getMemExuRCWriteSize, 69 Flipped(new RCWritePort(params.intSchdParams.get.rfDataWidth, RegCacheIdxWidth, params.intSchdParams.get.pregIdxWidth, params.debugEn))) 70} 71 72class BypassNetwork()(implicit p: Parameters, params: BackendParams) extends XSModule { 73 val io: BypassNetworkIO = IO(new BypassNetworkIO) 74 75 private val fromDPs: Seq[DecoupledIO[ExuInput]] = (io.fromDataPath.int ++ io.fromDataPath.fp ++ io.fromDataPath.vf ++ io.fromDataPath.mem).flatten.toSeq 76 private val fromExus: Seq[ValidIO[ExuBypassBundle]] = (io.fromExus.int ++ io.fromExus.fp ++ io.fromExus.vf ++ io.fromExus.mem).flatten.toSeq 77 private val toExus: Seq[DecoupledIO[ExuInput]] = (io.toExus.int ++ io.toExus.fp ++ io.toExus.vf ++ io.toExus.mem).flatten.toSeq 78 private val fromDPsRCData: Seq[Vec[UInt]] = io.fromDataPath.rcData.flatten.toSeq 79 private val immInfo = io.fromDataPath.immInfo 80 81 println(s"[BypassNetwork] RCData num: ${fromDPsRCData.size}") 82 83 // (exuIdx, srcIdx, bypassExuIdx) 84 private val forwardOrBypassValidVec3: MixedVec[Vec[Vec[Bool]]] = MixedVecInit( 85 fromDPs.map { (x: DecoupledIO[ExuInput]) => 86 println(s"[BypassNetwork] ${x.bits.params.name} numRegSrc: ${x.bits.params.numRegSrc}") 87 VecInit(x.bits.exuSources.map(_.map(_.toExuOH(x.bits.params))).getOrElse( 88 // TODO: remove tmp max 1 for fake HYU1 89 VecInit(Seq.fill(x.bits.params.numRegSrc max 1)(VecInit(0.U(params.numExu.W).asBools))) 90 )) 91 } 92 ) 93 94 private val forwardDataVec: Vec[UInt] = VecInit( 95 fromExus.map(x => ZeroExt(x.bits.data, RegDataMaxWidth)) 96 ) 97 98 private val bypassDataVec = VecInit( 99 fromExus.map(x => ZeroExt(RegEnable(x.bits.data, x.valid), RegDataMaxWidth)) 100 ) 101 102 private val intExuNum = params.intSchdParams.get.numExu 103 private val fpExuNum = params.fpSchdParams.get.numExu 104 private val vfExuNum = params.vfSchdParams.get.numExu 105 private val memExuNum = params.memSchdParams.get.numExu 106 107 println(s"[BypassNetwork] allExuNum: ${toExus.size} intExuNum: ${intExuNum} fpExuNum: ${fpExuNum} vfExuNum: ${vfExuNum} memExuNum: ${memExuNum}") 108 109 private val fromDPsHasBypass2Source = fromDPs.filter(x => x.bits.params.isIQWakeUpSource && x.bits.params.writeVfRf && (x.bits.params.isVfExeUnit || x.bits.params.hasLoadExu)).map(_.bits.params.exuIdx) 110 private val fromDPsHasBypass2Sink = fromDPs.filter(x => x.bits.params.isIQWakeUpSink && x.bits.params.readVfRf && (x.bits.params.isVfExeUnit || x.bits.params.isMemExeUnit)).map(_.bits.params.exuIdx) 111 112 private val bypass2ValidVec3 = MixedVecInit( 113 fromDPsHasBypass2Sink.map(forwardOrBypassValidVec3(_)).map(exu => VecInit(exu.map(exuOH => 114 VecInit(fromDPsHasBypass2Source.map(exuOH(_))).asUInt 115 ))) 116 ) 117 if(params.debugEn){ 118 dontTouch(bypass2ValidVec3) 119 } 120 private val bypass2DateEn = VecInit( 121 fromExus.map(x => GatedValidRegNext(x.valid)) 122 ).asUInt 123 private val bypass2DataVec = if (fromDPsHasBypass2Source.length == 0) VecInit(Seq(0.U)) else VecInit( 124 fromDPsHasBypass2Source.map(x => RegEnable(bypassDataVec(x), bypass2DateEn(x).asBool)) 125 ) 126 127 println(s"[BypassNetwork] HasBypass2SourceExuNum: ${fromDPsHasBypass2Source.size} HasBypass2SinkExuNum: ${fromDPsHasBypass2Sink.size} bypass2DataVecSize: ${bypass2DataVec.length}") 128 println(s"[BypassNetwork] HasBypass2SourceExu: ${fromDPsHasBypass2Source}") 129 println(s"[BypassNetwork] HasBypass2SinkExu: ${fromDPsHasBypass2Sink}") 130 131 toExus.zip(fromDPs).foreach { case (sink, source) => 132 sink <> source 133 } 134 135 toExus.zipWithIndex.foreach { case (exuInput, exuIdx) => 136 exuInput.bits.src.zipWithIndex.foreach { case (src, srcIdx) => 137 val imm = ImmExtractor( 138 immInfo(exuIdx).imm, 139 immInfo(exuIdx).immType, 140 exuInput.bits.params.destDataBitsMax, 141 exuInput.bits.params.immType.map(_.litValue) 142 ) 143 val immLoadSrc0 = SignExt(ImmUnion.U.toImm32(immInfo(exuIdx).imm(immInfo(exuIdx).imm.getWidth - 1, ImmUnion.I.len)), XLEN) 144 val exuParm = exuInput.bits.params 145 val isIntScheduler = exuParm.isIntExeUnit 146 val isReadVfRf= exuParm.readVfRf 147 val dataSource = exuInput.bits.dataSources(srcIdx) 148 val isWakeUpSink = params.allIssueParams.filter(_.exuBlockParams.contains(exuParm)).head.exuBlockParams.map(_.isIQWakeUpSink).reduce(_ || _) 149 val readForward = if (isWakeUpSink) dataSource.readForward else false.B 150 val readBypass = if (isWakeUpSink) dataSource.readBypass else false.B 151 val readZero = if (isIntScheduler) dataSource.readZero else false.B 152 val readV0 = if (srcIdx < 3 && isReadVfRf) dataSource.readV0 else false.B 153 val readRegOH = exuInput.bits.dataSources(srcIdx).readRegOH 154 val readRegCache = if (exuParm.needReadRegCache) exuInput.bits.dataSources(srcIdx).readRegCache else false.B 155 val readImm = if (exuParm.immType.nonEmpty || exuParm.hasLoadExu) exuInput.bits.dataSources(srcIdx).readImm else false.B 156 val bypass2ExuIdx = fromDPsHasBypass2Sink.indexOf(exuIdx) 157 println(s"${exuParm.name}: bypass2ExuIdx is ${bypass2ExuIdx}") 158 val readBypass2 = if (bypass2ExuIdx >= 0) dataSource.readBypass2 else false.B 159 src := Mux1H( 160 Seq( 161 readForward -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), forwardDataVec), 162 readBypass -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), bypassDataVec), 163 readBypass2 -> (if (bypass2ExuIdx >= 0) Mux1H(bypass2ValidVec3(bypass2ExuIdx)(srcIdx), bypass2DataVec) else 0.U), 164 readZero -> 0.U, 165 readV0 -> (if (srcIdx < 3 && isReadVfRf) exuInput.bits.src(3) else 0.U), 166 readRegOH -> fromDPs(exuIdx).bits.src(srcIdx), 167 readRegCache -> fromDPsRCData(exuIdx)(srcIdx), 168 readImm -> (if (exuParm.hasLoadExu && srcIdx == 0) immLoadSrc0 else imm) 169 ) 170 ) 171 } 172 } 173 174 // to reg cache 175 private val forwardIntWenVec = VecInit( 176 fromExus.filter(_.bits.params.needWriteRegCache).map(x => x.valid && x.bits.intWen) 177 ) 178 private val forwardTagVec = VecInit( 179 fromExus.filter(_.bits.params.needWriteRegCache).map(x => x.bits.pdest) 180 ) 181 182 private val bypassIntWenVec = VecInit( 183 forwardIntWenVec.map(x => GatedValidRegNext(x)) 184 ) 185 private val bypassTagVec = VecInit( 186 forwardTagVec.zip(forwardIntWenVec).map(x => RegEnable(x._1, x._2)) 187 ) 188 private val bypassRCDataVec = VecInit( 189 fromExus.zip(bypassDataVec).filter(_._1.bits.params.needWriteRegCache).map(_._2) 190 ) 191 192 println(s"[BypassNetwork] WriteRegCacheExuNum: ${forwardIntWenVec.size}") 193 194 io.toDataPath.zipWithIndex.foreach{ case (x, i) => 195 x.wen := bypassIntWenVec(i) 196 x.addr := DontCare 197 x.data := bypassRCDataVec(i) 198 x.tag.foreach(_ := bypassTagVec(i)) 199 } 200} 201