1c49ebec8SHaoyuan Feng/*************************************************************************************** 2c49ebec8SHaoyuan Feng* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3c49ebec8SHaoyuan Feng* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 4c49ebec8SHaoyuan Feng* Copyright (c) 2020-2021 Peng Cheng Laboratory 5c49ebec8SHaoyuan Feng* 6c49ebec8SHaoyuan Feng* XiangShan is licensed under Mulan PSL v2. 7c49ebec8SHaoyuan Feng* You can use this software according to the terms and conditions of the Mulan PSL v2. 8c49ebec8SHaoyuan Feng* You may obtain a copy of Mulan PSL v2 at: 9c49ebec8SHaoyuan Feng* http://license.coscl.org.cn/MulanPSL2 10c49ebec8SHaoyuan Feng* 11c49ebec8SHaoyuan Feng* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 12c49ebec8SHaoyuan Feng* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 13c49ebec8SHaoyuan Feng* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 14c49ebec8SHaoyuan Feng* 15c49ebec8SHaoyuan Feng* See the Mulan PSL v2 for more details. 16c49ebec8SHaoyuan Feng* 17c49ebec8SHaoyuan Feng* 18c49ebec8SHaoyuan Feng* Acknowledgement 19c49ebec8SHaoyuan Feng* 20c49ebec8SHaoyuan Feng* This implementation is inspired by several key papers: 21c49ebec8SHaoyuan Feng* [1] Fernando Latorre, Grigorios Magklis, Jose González, Pedro Chaparro, and Antonio González. "[Crob: implementing a 22c49ebec8SHaoyuan Feng* large instruction window through compression.](https://doi.org/10.1007/978-3-642-19448-1_7)" Transactions on 23c49ebec8SHaoyuan Feng* High-Performance Embedded Architectures and Compilers III: 115-134. Berlin, Heidelberg: Springer Berlin Heidelberg. 24c49ebec8SHaoyuan Feng* 2011. 25c49ebec8SHaoyuan Feng***************************************************************************************/ 26c49ebec8SHaoyuan Feng 2789cc69c1STang Haojinpackage xiangshan.backend.rename 2889cc69c1STang Haojin 2983ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters 3089cc69c1STang Haojinimport chisel3.Bundle 3189cc69c1STang Haojinimport xiangshan.backend.Bundles.DecodedInst 3289cc69c1STang Haojinimport xiangshan.XSModule 3389cc69c1STang Haojinimport chisel3._ 3489cc69c1STang Haojinimport chisel3.util._ 3589cc69c1STang Haojinimport freechips.rocketchip.rocket.DecodeLogic 3689cc69c1STang Haojinimport xiangshan._ 3789cc69c1STang Haojin 3889cc69c1STang Haojinclass CompressUnit(implicit p: Parameters) extends XSModule{ 3989cc69c1STang Haojin val io = IO(new Bundle { 4089cc69c1STang Haojin val in = Vec(RenameWidth, Flipped(Valid(new DecodedInst))) 4189cc69c1STang Haojin val out = new Bundle { 4289cc69c1STang Haojin val needRobFlags = Vec(RenameWidth, Output(Bool())) 4389cc69c1STang Haojin val instrSizes = Vec(RenameWidth, Output(UInt(log2Ceil(RenameWidth + 1).W))) 4489cc69c1STang Haojin val masks = Vec(RenameWidth, Output(UInt(RenameWidth.W))) 45*b720b0cdSchengguanghui val canCompressVec = Vec(RenameWidth, Output(Bool())) 4689cc69c1STang Haojin } 4789cc69c1STang Haojin }) 4889cc69c1STang Haojin 497e0f64b0SGuanghui Cheng val noExc = io.in.map(in => !in.bits.exceptionVec.asUInt.orR && !TriggerAction.isDmode(in.bits.trigger)) 5089cc69c1STang Haojin val uopCanCompress = io.in.map(_.bits.canRobCompress) 5189cc69c1STang Haojin val canCompress = io.in.zip(noExc).zip(uopCanCompress).map { case ((in, noExc), canComp) => 5289cc69c1STang Haojin in.valid && !CommitType.isFused(in.bits.commitType) && in.bits.lastUop && noExc && canComp 5389cc69c1STang Haojin } 5489cc69c1STang Haojin 5589cc69c1STang Haojin val compressTable = (0 until 1 << RenameWidth).map { case keyCandidate => 5689cc69c1STang Haojin // padding 0s at each side for convenience 5789cc69c1STang Haojin val key = 0 +: (0 until RenameWidth).map(idx => (keyCandidate >> idx) & 1) :+ 0 5889cc69c1STang Haojin // count 1s on the left side of key (including itself) 5989cc69c1STang Haojin def cntL(idx: Int): Int = (if (key(idx - 1) == 1) cntL(idx - 1) else 0) + key(idx) 6089cc69c1STang Haojin // count 1s on the right side of key (including itself) 6189cc69c1STang Haojin def cntR(idx: Int): Int = (if (key(idx + 1) == 1) cntR(idx + 1) else 0) + key(idx) 6289cc69c1STang Haojin // the last instruction among consecutive rob-compressed instructions is marked 6389cc69c1STang Haojin val needRobs = (0 until RenameWidth).map(idx => ~(key.tail(idx) & key.tail(idx + 1)) & 1) 6489cc69c1STang Haojin // how many instructions are rob-compressed with this instruction (including itself) 6589cc69c1STang Haojin val uopSizes = (1 to RenameWidth).map(idx => if (key(idx) == 0) 1 else cntL(idx) + cntR(idx) - 1) 6689cc69c1STang Haojin // which instructions are rob-compressed with this instruction 6789cc69c1STang Haojin val masks = uopSizes.zip(1 to RenameWidth).map { case (size, idx) => // compress masks 6889cc69c1STang Haojin if (key(idx) == 0) Seq.fill(RenameWidth)(0).updated(idx - 1, 1) 6989cc69c1STang Haojin else Seq.fill(RenameWidth)(0).patch(idx - cntL(idx), Seq.fill(size)(1), size) 7089cc69c1STang Haojin } 7189cc69c1STang Haojin 7289cc69c1STang Haojin println("[Rename.Compress]" + 7389cc69c1STang Haojin " i: " + keyCandidate + 7489cc69c1STang Haojin " key: " + key.tail.dropRight(1) + 7589cc69c1STang Haojin " needRobs: " + needRobs + 7689cc69c1STang Haojin " uopSizes: " + uopSizes + 7789cc69c1STang Haojin " masks: " + masks.map(_.map(_.toBinaryString).reduce(_ + _)) 7889cc69c1STang Haojin ) 7989cc69c1STang Haojin 8089cc69c1STang Haojin val keyBitPat = BitPat(keyCandidate.U) 8189cc69c1STang Haojin val needRobBitPats = needRobs.map(x => BitPat(x.U)) 8289cc69c1STang Haojin val uopSizeBitPats = uopSizes.map(x => BitPat(x.U)) 8389cc69c1STang Haojin val maskBitPats = masks.map(m => BitPat(m.foldRight(0)(_ | _ << 1).U)) 8489cc69c1STang Haojin 8589cc69c1STang Haojin (keyBitPat -> (needRobBitPats ++ uopSizeBitPats ++ maskBitPats)) 8689cc69c1STang Haojin } 8789cc69c1STang Haojin 8889cc69c1STang Haojin val default = Seq.fill(3 * RenameWidth)(BitPat.N()) 8989cc69c1STang Haojin val decoder = DecodeLogic(VecInit(canCompress).asUInt, default, compressTable) 9089cc69c1STang Haojin (io.out.needRobFlags ++ io.out.instrSizes ++ io.out.masks).zip(decoder).foreach { 9189cc69c1STang Haojin case (sink, source) => sink := source 9289cc69c1STang Haojin } 93*b720b0cdSchengguanghui io.out.canCompressVec := VecInit(canCompress) 9489cc69c1STang Haojin} 95