15b70e4b0SXuan Hupackage xiangshan.backend 25b70e4b0SXuan Hu 35b70e4b0SXuan Huimport chisel3._ 45b70e4b0SXuan Huimport chisel3.util._ 55b70e4b0SXuan Hu 65b70e4b0SXuan Huclass PipeGroupConnect[T <: Data](n: Int, gen: => T) extends Module { 75b70e4b0SXuan Hu val io = IO(new Bundle { 85b70e4b0SXuan Hu val in = Vec(n, Flipped(DecoupledIO(gen))) 95b70e4b0SXuan Hu val out = Vec(n, DecoupledIO(gen)) 105b70e4b0SXuan Hu val flush = Input(Bool()) 11f5c17053Sxiaofeibao-xjtu val outAllFire = Input(Bool()) 125b70e4b0SXuan Hu }) 135b70e4b0SXuan Hu 145b70e4b0SXuan Hu // Input Alias 155b70e4b0SXuan Hu // Use private[this] to limit the wrong usage for not IO hardware in object with the same name. 165b70e4b0SXuan Hu private[this] val flush = io.flush 175b70e4b0SXuan Hu private[this] val inValidSeq = io.in.map(_.valid) 185b70e4b0SXuan Hu private[this] val inDataSeq = io.in.map(_.bits) 195b70e4b0SXuan Hu private[this] val outReadySeq = io.out.map(_.ready) 205b70e4b0SXuan Hu 215b70e4b0SXuan Hu // Regs 225b70e4b0SXuan Hu private[this] val validVec = RegInit(VecInit.fill(n)(false.B)) 235b70e4b0SXuan Hu private[this] val dataVec = Reg(Vec(n, gen)) 245b70e4b0SXuan Hu 255b70e4b0SXuan Hu // Logic 265b70e4b0SXuan Hu private[this] val valids = Cat(validVec.reverse) 275b70e4b0SXuan Hu private[this] val inValids = Cat(inValidSeq.reverse) 285b70e4b0SXuan Hu private[this] val outReadys = Cat(outReadySeq.reverse) 295b70e4b0SXuan Hu 305b70e4b0SXuan Hu // Todo: canAccVec for each elem 315b70e4b0SXuan Hu // Todo: no outReadys version for better timing and lower performance 32*1c6572a6Sxiaofeibao private[this] val canAcc = io.outAllFire || !valids.orR 335b70e4b0SXuan Hu 345b70e4b0SXuan Hu (validVec zip inValids.asBools zip outReadys.asBools).foreach { case ((valid, inValid), outReady) => 355b70e4b0SXuan Hu valid := MuxCase( 365b70e4b0SXuan Hu default = valid /*keep*/, 375b70e4b0SXuan Hu Seq( 385b70e4b0SXuan Hu flush -> false.B, 395b70e4b0SXuan Hu (inValid && canAcc) -> true.B, 405b70e4b0SXuan Hu outReady -> false.B 415b70e4b0SXuan Hu ) 425b70e4b0SXuan Hu ) 435b70e4b0SXuan Hu } 445b70e4b0SXuan Hu 455b70e4b0SXuan Hu (dataVec zip inValids.asBools zip inDataSeq).foreach { case ((data, inValid), inData) => 465b70e4b0SXuan Hu when (inValid && canAcc) { 475b70e4b0SXuan Hu data := inData 485b70e4b0SXuan Hu } 495b70e4b0SXuan Hu } 505b70e4b0SXuan Hu 515b70e4b0SXuan Hu // Output connections 525b70e4b0SXuan Hu for (i <- 0 until n) { 535b70e4b0SXuan Hu io.in(i).ready := canAcc 545b70e4b0SXuan Hu io.out(i).valid := validVec(i) 555b70e4b0SXuan Hu io.out(i).bits := dataVec(i) 565b70e4b0SXuan Hu } 575b70e4b0SXuan Hu} 585b70e4b0SXuan Hu 595b70e4b0SXuan Huobject PipeGroupConnect { 605b70e4b0SXuan Hu def apply[T <: Data]( 615b70e4b0SXuan Hu // Left can be not Vec, but right must be Vec 625b70e4b0SXuan Hu left: Seq[DecoupledIO[T]], 635b70e4b0SXuan Hu right: Vec[DecoupledIO[T]], 645b70e4b0SXuan Hu flush: Bool, 65f5c17053Sxiaofeibao-xjtu rightAllFire: Bool, 665b70e4b0SXuan Hu suggestName: String = null, 675b70e4b0SXuan Hu ): Unit = { 685b70e4b0SXuan Hu require(left.size == right.size, "The sizes of left and right Vec Bundle should be equal in PipeGroupConnect") 695b70e4b0SXuan Hu require(left.size > 0, "The size of Vec Bundle in PipeGroupConnect should be more than 0") 705b70e4b0SXuan Hu val mod = Module(new PipeGroupConnect(left.size, chiselTypeOf(left.head.bits))) 715b70e4b0SXuan Hu mod.io.flush := flush 725b70e4b0SXuan Hu mod.io.in.zipWithIndex.foreach { case (in, i) => 735b70e4b0SXuan Hu in.valid := left(i).valid 745b70e4b0SXuan Hu in.bits := left(i).bits 755b70e4b0SXuan Hu left(i).ready := in.ready 765b70e4b0SXuan Hu } 77f5c17053Sxiaofeibao-xjtu mod.io.outAllFire := rightAllFire 785b70e4b0SXuan Hu right <> mod.io.out 795b70e4b0SXuan Hu 805b70e4b0SXuan Hu if (suggestName != null) 815b70e4b0SXuan Hu mod.suggestName(suggestName) 825b70e4b0SXuan Hu } 835b70e4b0SXuan Hu} 84