1package xiangshan.backend.datapath 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.ZeroExt 7import xiangshan.XSBundle 8import xiangshan.backend.BackendParams 9import xiangshan.backend.Bundles.{ExuBypassBundle, ExuInput, ExuVec, ExuOutput} 10import xiangshan.backend.issue.{IntScheduler, MemScheduler, VfScheduler} 11import xiangshan.backend.datapath.DataConfig.RegDataMaxWidth 12 13class BypassNetworkIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 14 // params 15 private val intSchdParams = params.schdParams(IntScheduler()) 16 private val vfSchdParams = params.schdParams(VfScheduler()) 17 private val memSchdParams = params.schdParams(MemScheduler()) 18 19 val fromDataPath = new FromDataPath 20 val toExus = new ToExus 21 val fromExus = new FromExus 22 23 class FromDataPath extends Bundle { 24 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(intSchdParams.genExuInputBundle) 25 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(vfSchdParams.genExuInputBundle) 26 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(memSchdParams.genExuInputBundle) 27 } 28 29 class ToExus extends Bundle { 30 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = intSchdParams.genExuInputBundle 31 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = vfSchdParams.genExuInputBundle 32 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = memSchdParams.genExuInputBundle 33 } 34 35 class FromExus extends Bundle { 36 val int: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(intSchdParams.genExuBypassValidBundle) 37 val vf : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(vfSchdParams.genExuBypassValidBundle) 38 val mem: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(memSchdParams.genExuBypassValidBundle) 39 40 def connectExuOutput( 41 getSinkVecN: FromExus => MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] 42 )( 43 sourceVecN: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] 44 ): Unit = { 45 getSinkVecN(this).zip(sourceVecN).foreach { case (sinkVec, sourcesVec) => 46 sinkVec.zip(sourcesVec).foreach { case (sink, source) => 47 sink.valid := source.valid 48 sink.bits.pdest := source.bits.pdest 49 sink.bits.data := source.bits.data 50 } 51 } 52 } 53 } 54} 55 56class BypassNetwork()(implicit p: Parameters, params: BackendParams) extends Module { 57 val io: BypassNetworkIO = IO(new BypassNetworkIO) 58 59 private val fromDPs: Seq[DecoupledIO[ExuInput]] = (io.fromDataPath.int ++ io.fromDataPath.vf ++ io.fromDataPath.mem).flatten.toSeq 60 private val fromExus: Seq[ValidIO[ExuBypassBundle]] = (io.fromExus.int ++ io.fromExus.vf ++ io.fromExus.mem).flatten.toSeq 61 private val toExus: Seq[DecoupledIO[ExuInput]] = (io.toExus.int ++ io.toExus.vf ++ io.toExus.mem).flatten.toSeq 62 63 // (exuIdx, srcIdx, bypassExuIdx) 64 private val forwardOrBypassValidVec3: MixedVec[Vec[Vec[Bool]]] = MixedVecInit( 65 fromDPs.map(x => x.bits.l1ExuVec) 66 ) 67 68 private val forwardDataVec: Vec[UInt] = VecInit( 69 fromExus.map(x => ZeroExt(x.bits.data, RegDataMaxWidth)) 70 ) 71 72 private val bypassDataVec = VecInit( 73 fromExus.map(x => ZeroExt(RegEnable(x.bits.data, x.valid), RegDataMaxWidth)) 74 ) 75 76 toExus.zip(fromDPs).foreach { case (sink, source) => 77 sink <> source 78 } 79 80 toExus.zipWithIndex.foreach { case (exuInput, exuIdx) => 81 exuInput.bits.src.zipWithIndex.foreach { case (src, srcIdx) => 82 when (exuInput.bits.dataSources(srcIdx).readForward) { 83 src := Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), forwardDataVec) 84 }.elsewhen (exuInput.bits.dataSources(srcIdx).readBypass) { 85 src := Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), bypassDataVec) 86 }.otherwise { 87 src := fromDPs(exuIdx).bits.src(srcIdx) 88 } 89 } 90 } 91} 92