1*89cc69c1STang Haojinpackage xiangshan.backend.rename 2*89cc69c1STang Haojin 3*89cc69c1STang Haojinimport chipsalliance.rocketchip.config.Parameters 4*89cc69c1STang Haojinimport chisel3.Bundle 5*89cc69c1STang Haojinimport xiangshan.backend.Bundles.DecodedInst 6*89cc69c1STang Haojinimport xiangshan.XSModule 7*89cc69c1STang Haojinimport chisel3._ 8*89cc69c1STang Haojinimport chisel3.util._ 9*89cc69c1STang Haojinimport freechips.rocketchip.rocket.DecodeLogic 10*89cc69c1STang Haojinimport xiangshan._ 11*89cc69c1STang Haojin 12*89cc69c1STang Haojinclass CompressUnit(implicit p: Parameters) extends XSModule{ 13*89cc69c1STang Haojin val io = IO(new Bundle { 14*89cc69c1STang Haojin val in = Vec(RenameWidth, Flipped(Valid(new DecodedInst))) 15*89cc69c1STang Haojin val out = new Bundle { 16*89cc69c1STang Haojin val needRobFlags = Vec(RenameWidth, Output(Bool())) 17*89cc69c1STang Haojin val instrSizes = Vec(RenameWidth, Output(UInt(log2Ceil(RenameWidth + 1).W))) 18*89cc69c1STang Haojin val masks = Vec(RenameWidth, Output(UInt(RenameWidth.W))) 19*89cc69c1STang Haojin } 20*89cc69c1STang Haojin }) 21*89cc69c1STang Haojin 22*89cc69c1STang Haojin val noExc = io.in.map(!_.bits.exceptionVec.asUInt.orR) 23*89cc69c1STang Haojin val uopCanCompress = io.in.map(_.bits.canRobCompress) 24*89cc69c1STang Haojin val canCompress = io.in.zip(noExc).zip(uopCanCompress).map { case ((in, noExc), canComp) => 25*89cc69c1STang Haojin in.valid && !CommitType.isFused(in.bits.commitType) && in.bits.lastUop && noExc && canComp 26*89cc69c1STang Haojin } 27*89cc69c1STang Haojin 28*89cc69c1STang Haojin val compressTable = (0 until 1 << RenameWidth).map { case keyCandidate => 29*89cc69c1STang Haojin // padding 0s at each side for convenience 30*89cc69c1STang Haojin val key = 0 +: (0 until RenameWidth).map(idx => (keyCandidate >> idx) & 1) :+ 0 31*89cc69c1STang Haojin // count 1s on the left side of key (including itself) 32*89cc69c1STang Haojin def cntL(idx: Int): Int = (if (key(idx - 1) == 1) cntL(idx - 1) else 0) + key(idx) 33*89cc69c1STang Haojin // count 1s on the right side of key (including itself) 34*89cc69c1STang Haojin def cntR(idx: Int): Int = (if (key(idx + 1) == 1) cntR(idx + 1) else 0) + key(idx) 35*89cc69c1STang Haojin // the last instruction among consecutive rob-compressed instructions is marked 36*89cc69c1STang Haojin val needRobs = (0 until RenameWidth).map(idx => ~(key.tail(idx) & key.tail(idx + 1)) & 1) 37*89cc69c1STang Haojin // how many instructions are rob-compressed with this instruction (including itself) 38*89cc69c1STang Haojin val uopSizes = (1 to RenameWidth).map(idx => if (key(idx) == 0) 1 else cntL(idx) + cntR(idx) - 1) 39*89cc69c1STang Haojin // which instructions are rob-compressed with this instruction 40*89cc69c1STang Haojin val masks = uopSizes.zip(1 to RenameWidth).map { case (size, idx) => // compress masks 41*89cc69c1STang Haojin if (key(idx) == 0) Seq.fill(RenameWidth)(0).updated(idx - 1, 1) 42*89cc69c1STang Haojin else Seq.fill(RenameWidth)(0).patch(idx - cntL(idx), Seq.fill(size)(1), size) 43*89cc69c1STang Haojin } 44*89cc69c1STang Haojin 45*89cc69c1STang Haojin println("[Rename.Compress]" + 46*89cc69c1STang Haojin " i: " + keyCandidate + 47*89cc69c1STang Haojin " key: " + key.tail.dropRight(1) + 48*89cc69c1STang Haojin " needRobs: " + needRobs + 49*89cc69c1STang Haojin " uopSizes: " + uopSizes + 50*89cc69c1STang Haojin " masks: " + masks.map(_.map(_.toBinaryString).reduce(_ + _)) 51*89cc69c1STang Haojin ) 52*89cc69c1STang Haojin 53*89cc69c1STang Haojin val keyBitPat = BitPat(keyCandidate.U) 54*89cc69c1STang Haojin val needRobBitPats = needRobs.map(x => BitPat(x.U)) 55*89cc69c1STang Haojin val uopSizeBitPats = uopSizes.map(x => BitPat(x.U)) 56*89cc69c1STang Haojin val maskBitPats = masks.map(m => BitPat(m.foldRight(0)(_ | _ << 1).U)) 57*89cc69c1STang Haojin 58*89cc69c1STang Haojin (keyBitPat -> (needRobBitPats ++ uopSizeBitPats ++ maskBitPats)) 59*89cc69c1STang Haojin } 60*89cc69c1STang Haojin 61*89cc69c1STang Haojin val default = Seq.fill(3 * RenameWidth)(BitPat.N()) 62*89cc69c1STang Haojin val decoder = DecodeLogic(VecInit(canCompress).asUInt, default, compressTable) 63*89cc69c1STang Haojin (io.out.needRobFlags ++ io.out.instrSizes ++ io.out.masks).zip(decoder).foreach { 64*89cc69c1STang Haojin case (sink, source) => sink := source 65*89cc69c1STang Haojin } 66*89cc69c1STang Haojin} 67