xref: /XiangShan/src/main/scala/xiangshan/backend/rename/CompressUnit.scala (revision 89cc69c119d86d0be7a9e6acf061e9ead2843ebb)
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