1package xiangshan.backend.datapath 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.{SignExt, ZeroExt} 7import xiangshan.{XSBundle, XSModule} 8import xiangshan.backend.BackendParams 9import xiangshan.backend.Bundles.{ExuBypassBundle, ExuInput, ExuOH, ExuOutput, ImmInfo} 10import xiangshan.backend.issue.{ImmExtractor, IntScheduler, MemScheduler, VfScheduler, FpScheduler} 11import xiangshan.backend.datapath.DataConfig.RegDataMaxWidth 12import xiangshan.backend.decode.ImmUnion 13 14class BypassNetworkIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 15 // params 16 private val intSchdParams = params.schdParams(IntScheduler()) 17 private val fpSchdParams = params.schdParams(FpScheduler()) 18 private val vfSchdParams = params.schdParams(VfScheduler()) 19 private val memSchdParams = params.schdParams(MemScheduler()) 20 21 val fromDataPath = new FromDataPath 22 val toExus = new ToExus 23 val fromExus = new FromExus 24 25 class FromDataPath extends Bundle { 26 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(intSchdParams.genExuInputBundle) 27 val fp : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(fpSchdParams.genExuInputBundle) 28 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(vfSchdParams.genExuInputBundle) 29 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(memSchdParams.genExuInputBundle) 30 val immInfo: Vec[ImmInfo] = Input(Vec(params.allExuParams.size, new ImmInfo)) 31 } 32 33 class ToExus extends Bundle { 34 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = intSchdParams.genExuInputBundle 35 val fp : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = fpSchdParams.genExuInputBundle 36 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = vfSchdParams.genExuInputBundle 37 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = memSchdParams.genExuInputBundle 38 } 39 40 class FromExus extends Bundle { 41 val int: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(intSchdParams.genExuBypassValidBundle) 42 val fp : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(fpSchdParams.genExuBypassValidBundle) 43 val vf : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(vfSchdParams.genExuBypassValidBundle) 44 val mem: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(memSchdParams.genExuBypassValidBundle) 45 46 def connectExuOutput( 47 getSinkVecN: FromExus => MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] 48 )( 49 sourceVecN: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] 50 ): Unit = { 51 getSinkVecN(this).zip(sourceVecN).foreach { case (sinkVec, sourcesVec) => 52 sinkVec.zip(sourcesVec).foreach { case (sink, source) => 53 sink.valid := source.valid 54 sink.bits.pdest := source.bits.pdest 55 sink.bits.data := source.bits.data 56 } 57 } 58 } 59 } 60} 61 62class BypassNetwork()(implicit p: Parameters, params: BackendParams) extends XSModule { 63 val io: BypassNetworkIO = IO(new BypassNetworkIO) 64 65 private val fromDPs: Seq[DecoupledIO[ExuInput]] = (io.fromDataPath.int ++ io.fromDataPath.fp ++ io.fromDataPath.vf ++ io.fromDataPath.mem).flatten.toSeq 66 private val fromExus: Seq[ValidIO[ExuBypassBundle]] = (io.fromExus.int ++ io.fromExus.fp ++ io.fromExus.vf ++ io.fromExus.mem).flatten.toSeq 67 private val toExus: Seq[DecoupledIO[ExuInput]] = (io.toExus.int ++ io.toExus.fp ++ io.toExus.vf ++ io.toExus.mem).flatten.toSeq 68 private val immInfo = io.fromDataPath.immInfo 69 70 // (exuIdx, srcIdx, bypassExuIdx) 71 private val forwardOrBypassValidVec3: MixedVec[Vec[UInt]] = MixedVecInit( 72 fromDPs.map { (x: DecoupledIO[ExuInput]) => 73 println(s"[BypassNetwork] ${x.bits.params.name} numRegSrc: ${x.bits.params.numRegSrc}") 74 x.bits.l1ExuOH.getOrElse( 75 // TODO: remove tmp max 1 for fake HYU1 76 VecInit(Seq.fill(x.bits.params.numRegSrc max 1)(0.U(ExuOH.width.W))) 77 ) 78 } 79 ) 80 81 private val forwardDataVec: Vec[UInt] = VecInit( 82 fromExus.map(x => ZeroExt(x.bits.data, RegDataMaxWidth)) 83 ) 84 85 private val bypassDataVec = VecInit( 86 fromExus.map(x => ZeroExt(RegEnable(x.bits.data, x.valid), RegDataMaxWidth)) 87 ) 88 89 private val intExuNum = params.intSchdParams.get.numExu 90 private val fpExuNum = params.fpSchdParams.get.numExu 91 private val vfExuNum = params.vfSchdParams.get.numExu 92 private val memExuNum = params.memSchdParams.get.numExu 93 94 println(s"[BypassNetwork] allExuNum: ${toExus.size} intExuNum: ${intExuNum} fpExuNum: ${fpExuNum} vfExuNum: ${vfExuNum} memExuNum: ${memExuNum}") 95 96 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) 97 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) 98 99 private val bypass2ValidVec3 = MixedVecInit( 100 fromDPsHasBypass2Sink.map(forwardOrBypassValidVec3(_)).map(exu => VecInit(exu.map(l1ExuOH => 101 VecInit(fromDPsHasBypass2Source.map(l1ExuOH(_))).asUInt 102 ))) 103 ) 104 if(params.debugEn){ 105 dontTouch(bypass2ValidVec3) 106 } 107 private val bypass2DataVec = VecInit( 108 fromDPsHasBypass2Source.map(x => RegNext(bypassDataVec(x))) 109 ) 110 111 println(s"[BypassNetwork] HasBypass2SourceExuNum: ${fromDPsHasBypass2Source.size} HasBypass2SinkExuNum: ${fromDPsHasBypass2Sink.size} bypass2DataVecSize: ${bypass2DataVec.length}") 112 println(s"[BypassNetwork] HasBypass2SourceExu: ${fromDPsHasBypass2Source}") 113 println(s"[BypassNetwork] HasBypass2SinkExu: ${fromDPsHasBypass2Sink}") 114 115 toExus.zip(fromDPs).foreach { case (sink, source) => 116 sink <> source 117 } 118 119 toExus.zipWithIndex.foreach { case (exuInput, exuIdx) => 120 exuInput.bits.src.zipWithIndex.foreach { case (src, srcIdx) => 121 val imm = ImmExtractor( 122 immInfo(exuIdx).imm, 123 immInfo(exuIdx).immType, 124 exuInput.bits.params.dataBitsMax, 125 exuInput.bits.params.immType.map(_.litValue) 126 ) 127 val immLoadSrc0 = SignExt(ImmUnion.U.toImm32(immInfo(exuIdx).imm(immInfo(exuIdx).imm.getWidth - 1, ImmUnion.I.len)), XLEN) 128 val exuParm = exuInput.bits.params 129 val isIntScheduler = exuParm.isIntExeUnit 130 val dataSource = exuInput.bits.dataSources(srcIdx) 131 val isWakeUpSink = params.allIssueParams.filter(_.exuBlockParams.contains(exuParm)).head.exuBlockParams.map(_.isIQWakeUpSink).reduce(_ || _) 132 val readForward = if (isWakeUpSink) dataSource.readForward else false.B 133 val readBypass = if (isWakeUpSink) dataSource.readBypass else false.B 134 val readZero = if (isIntScheduler) dataSource.readZero else false.B 135 val readAnotherReg = if (isIntScheduler && exuParm.numRegSrc == 2 && srcIdx==1) dataSource.readAnotherReg else false.B 136 val readRegOH = exuInput.bits.dataSources(srcIdx).readRegOH 137 val readImm = if (exuParm.immType.nonEmpty || exuParm.hasLoadExu) exuInput.bits.dataSources(srcIdx).readImm else false.B 138 val bypass2ExuIdx = fromDPsHasBypass2Sink.indexOf(exuIdx) 139 println(s"${exuParm.name}: bypass2ExuIdx is ${bypass2ExuIdx}") 140 val readBypass2 = if (bypass2ExuIdx >= 0) dataSource.readBypass2 else false.B 141 src := Mux1H( 142 Seq( 143 readForward -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), forwardDataVec), 144 readBypass -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), bypassDataVec), 145 readBypass2 -> (if (bypass2ExuIdx >= 0) Mux1H(bypass2ValidVec3(bypass2ExuIdx)(srcIdx), bypass2DataVec) else 0.U), 146 readZero -> 0.U, 147// readAnotherReg -> fromDPs(exuIdx).bits.src(0), 148 readRegOH -> fromDPs(exuIdx).bits.src(srcIdx), 149 readImm -> (if (exuParm.hasLoadExu && srcIdx == 0) immLoadSrc0 else imm) 150 ) 151 ) 152 } 153 } 154} 155