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} 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 vfSchdParams = params.schdParams(VfScheduler()) 18 private val memSchdParams = params.schdParams(MemScheduler()) 19 20 val fromDataPath = new FromDataPath 21 val toExus = new ToExus 22 val fromExus = new FromExus 23 24 class FromDataPath extends Bundle { 25 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(intSchdParams.genExuInputBundle) 26 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(vfSchdParams.genExuInputBundle) 27 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = Flipped(memSchdParams.genExuInputBundle) 28 val immInfo: Vec[ImmInfo] = Input(Vec(params.allExuParams.size, new ImmInfo)) 29 } 30 31 class ToExus extends Bundle { 32 val int: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = intSchdParams.genExuInputBundle 33 val vf : MixedVec[MixedVec[DecoupledIO[ExuInput]]] = vfSchdParams.genExuInputBundle 34 val mem: MixedVec[MixedVec[DecoupledIO[ExuInput]]] = memSchdParams.genExuInputBundle 35 } 36 37 class FromExus extends Bundle { 38 val int: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(intSchdParams.genExuBypassValidBundle) 39 val vf : MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(vfSchdParams.genExuBypassValidBundle) 40 val mem: MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] = Flipped(memSchdParams.genExuBypassValidBundle) 41 42 def connectExuOutput( 43 getSinkVecN: FromExus => MixedVec[MixedVec[ValidIO[ExuBypassBundle]]] 44 )( 45 sourceVecN: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] 46 ): Unit = { 47 getSinkVecN(this).zip(sourceVecN).foreach { case (sinkVec, sourcesVec) => 48 sinkVec.zip(sourcesVec).foreach { case (sink, source) => 49 sink.valid := source.valid 50 sink.bits.pdest := source.bits.pdest 51 sink.bits.data := source.bits.data 52 } 53 } 54 } 55 } 56} 57 58class BypassNetwork()(implicit p: Parameters, params: BackendParams) extends XSModule { 59 val io: BypassNetworkIO = IO(new BypassNetworkIO) 60 61 private val fromDPs: Seq[DecoupledIO[ExuInput]] = (io.fromDataPath.int ++ io.fromDataPath.vf ++ io.fromDataPath.mem).flatten.toSeq 62 private val fromExus: Seq[ValidIO[ExuBypassBundle]] = (io.fromExus.int ++ io.fromExus.vf ++ io.fromExus.mem).flatten.toSeq 63 private val toExus: Seq[DecoupledIO[ExuInput]] = (io.toExus.int ++ io.toExus.vf ++ io.toExus.mem).flatten.toSeq 64 private val immInfo = io.fromDataPath.immInfo 65 66 // (exuIdx, srcIdx, bypassExuIdx) 67 private val forwardOrBypassValidVec3: MixedVec[Vec[UInt]] = MixedVecInit( 68 fromDPs.map { (x: DecoupledIO[ExuInput]) => 69 println(s"[tmp-BypassNetwork] ${x.bits.params.name} numRegSrc: ${x.bits.params.numRegSrc}") 70 x.bits.l1ExuOH.getOrElse( 71 // TODO: remove tmp max 1 for fake HYU1 72 VecInit(Seq.fill(x.bits.params.numRegSrc max 1)(0.U(ExuOH.width.W))) 73 ) 74 } 75 ) 76 77 private val forwardDataVec: Vec[UInt] = VecInit( 78 fromExus.map(x => ZeroExt(x.bits.data, RegDataMaxWidth)) 79 ) 80 81 private val bypassDataVec = VecInit( 82 fromExus.map(x => ZeroExt(RegEnable(x.bits.data, x.valid), RegDataMaxWidth)) 83 ) 84 85 toExus.zip(fromDPs).foreach { case (sink, source) => 86 sink <> source 87 } 88 89 toExus.zipWithIndex.foreach { case (exuInput, exuIdx) => 90 exuInput.bits.src.zipWithIndex.foreach { case (src, srcIdx) => 91 val imm = ImmExtractor( 92 immInfo(exuIdx).imm, 93 immInfo(exuIdx).immType, 94 exuInput.bits.params.dataBitsMax, 95 exuInput.bits.params.immType.map(_.litValue) 96 ) 97 val immLoadSrc0 = SignExt(ImmUnion.U.toImm32(immInfo(exuIdx).imm(immInfo(exuIdx).imm.getWidth - 1, ImmUnion.I.len)), XLEN) 98 val exuParm = exuInput.bits.params 99 val isIntScheduler = exuParm.schdType.isInstanceOf[IntScheduler] 100 val dataSource = exuInput.bits.dataSources(srcIdx) 101 val isWakeUpSink = params.allIssueParams.filter(_.exuBlockParams.contains(exuParm)).head.exuBlockParams.map(_.isIQWakeUpSink).reduce(_ || _) 102 val readForward = if (isWakeUpSink) dataSource.readForward else false.B 103 val readBypass = if (isWakeUpSink) dataSource.readBypass else false.B 104 val readZero = if (isIntScheduler) dataSource.readZero else false.B 105 val readAnotherReg = if (isIntScheduler && exuParm.numRegSrc == 2 && srcIdx==1) dataSource.readAnotherReg else false.B 106 val readRegOH = exuInput.bits.dataSources(srcIdx).readRegOH 107 val readImm = if (exuParm.immType.nonEmpty || exuParm.hasLoadFu || exuParm.hasHyldaFu) exuInput.bits.dataSources(srcIdx).readImm else false.B 108 src := Mux1H( 109 Seq( 110 readForward -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), forwardDataVec), 111 readBypass -> Mux1H(forwardOrBypassValidVec3(exuIdx)(srcIdx), bypassDataVec), 112 readZero -> 0.U, 113// readAnotherReg -> fromDPs(exuIdx).bits.src(0), 114 readRegOH -> fromDPs(exuIdx).bits.src(srcIdx), 115 readImm -> (if (exuInput.bits.params.hasLoadExu && srcIdx == 0) immLoadSrc0 else imm) 116 ) 117 ) 118 } 119 } 120} 121