xref: /XiangShan/src/main/scala/xiangshan/backend/rename/CompressUnit.scala (revision 83ba63b34cf09b33c0a9e1b3203138e51af4491b)
189cc69c1STang Haojinpackage xiangshan.backend.rename
289cc69c1STang Haojin
3*83ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
489cc69c1STang Haojinimport chisel3.Bundle
589cc69c1STang Haojinimport xiangshan.backend.Bundles.DecodedInst
689cc69c1STang Haojinimport xiangshan.XSModule
789cc69c1STang Haojinimport chisel3._
889cc69c1STang Haojinimport chisel3.util._
989cc69c1STang Haojinimport freechips.rocketchip.rocket.DecodeLogic
1089cc69c1STang Haojinimport xiangshan._
1189cc69c1STang Haojin
1289cc69c1STang Haojinclass CompressUnit(implicit p: Parameters) extends XSModule{
1389cc69c1STang Haojin  val io = IO(new Bundle {
1489cc69c1STang Haojin    val in = Vec(RenameWidth, Flipped(Valid(new DecodedInst)))
1589cc69c1STang Haojin    val out = new Bundle {
1689cc69c1STang Haojin      val needRobFlags = Vec(RenameWidth, Output(Bool()))
1789cc69c1STang Haojin      val instrSizes = Vec(RenameWidth, Output(UInt(log2Ceil(RenameWidth + 1).W)))
1889cc69c1STang Haojin      val masks = Vec(RenameWidth, Output(UInt(RenameWidth.W)))
1989cc69c1STang Haojin    }
2089cc69c1STang Haojin  })
2189cc69c1STang Haojin
2289cc69c1STang Haojin  val noExc = io.in.map(!_.bits.exceptionVec.asUInt.orR)
2389cc69c1STang Haojin  val uopCanCompress = io.in.map(_.bits.canRobCompress)
2489cc69c1STang Haojin  val canCompress = io.in.zip(noExc).zip(uopCanCompress).map { case ((in, noExc), canComp) =>
2589cc69c1STang Haojin    in.valid && !CommitType.isFused(in.bits.commitType) && in.bits.lastUop && noExc && canComp
2689cc69c1STang Haojin  }
2789cc69c1STang Haojin
2889cc69c1STang Haojin  val compressTable = (0 until 1 << RenameWidth).map { case keyCandidate =>
2989cc69c1STang Haojin    // padding 0s at each side for convenience
3089cc69c1STang Haojin    val key = 0 +: (0 until RenameWidth).map(idx => (keyCandidate >> idx) & 1) :+ 0
3189cc69c1STang Haojin    // count 1s on the left side of key (including itself)
3289cc69c1STang Haojin    def cntL(idx: Int): Int = (if (key(idx - 1) == 1) cntL(idx - 1) else 0) + key(idx)
3389cc69c1STang Haojin    // count 1s on the right side of key (including itself)
3489cc69c1STang Haojin    def cntR(idx: Int): Int = (if (key(idx + 1) == 1) cntR(idx + 1) else 0) + key(idx)
3589cc69c1STang Haojin    // the last instruction among consecutive rob-compressed instructions is marked
3689cc69c1STang Haojin    val needRobs = (0 until RenameWidth).map(idx => ~(key.tail(idx) & key.tail(idx + 1)) & 1)
3789cc69c1STang Haojin    // how many instructions are rob-compressed with this instruction (including itself)
3889cc69c1STang Haojin    val uopSizes = (1 to RenameWidth).map(idx => if (key(idx) == 0) 1 else cntL(idx) + cntR(idx) - 1)
3989cc69c1STang Haojin    // which instructions are rob-compressed with this instruction
4089cc69c1STang Haojin    val masks = uopSizes.zip(1 to RenameWidth).map { case (size, idx) => // compress masks
4189cc69c1STang Haojin      if (key(idx) == 0) Seq.fill(RenameWidth)(0).updated(idx - 1, 1)
4289cc69c1STang Haojin      else Seq.fill(RenameWidth)(0).patch(idx - cntL(idx), Seq.fill(size)(1), size)
4389cc69c1STang Haojin    }
4489cc69c1STang Haojin
4589cc69c1STang Haojin    println("[Rename.Compress]" +
4689cc69c1STang Haojin      " i: "        + keyCandidate +
4789cc69c1STang Haojin      " key: "      + key.tail.dropRight(1) +
4889cc69c1STang Haojin      " needRobs: " + needRobs +
4989cc69c1STang Haojin      " uopSizes: " + uopSizes +
5089cc69c1STang Haojin      " masks: "    + masks.map(_.map(_.toBinaryString).reduce(_ + _))
5189cc69c1STang Haojin    )
5289cc69c1STang Haojin
5389cc69c1STang Haojin    val keyBitPat = BitPat(keyCandidate.U)
5489cc69c1STang Haojin    val needRobBitPats = needRobs.map(x => BitPat(x.U))
5589cc69c1STang Haojin    val uopSizeBitPats = uopSizes.map(x => BitPat(x.U))
5689cc69c1STang Haojin    val maskBitPats = masks.map(m => BitPat(m.foldRight(0)(_ | _ << 1).U))
5789cc69c1STang Haojin
5889cc69c1STang Haojin    (keyBitPat -> (needRobBitPats ++ uopSizeBitPats ++ maskBitPats))
5989cc69c1STang Haojin  }
6089cc69c1STang Haojin
6189cc69c1STang Haojin  val default = Seq.fill(3 * RenameWidth)(BitPat.N())
6289cc69c1STang Haojin  val decoder = DecodeLogic(VecInit(canCompress).asUInt, default, compressTable)
6389cc69c1STang Haojin  (io.out.needRobFlags ++ io.out.instrSizes ++ io.out.masks).zip(decoder).foreach {
6489cc69c1STang Haojin    case (sink, source) => sink := source
6589cc69c1STang Haojin  }
6689cc69c1STang Haojin}
67