1package xiangshan.backend.fu.vector.utils 2 3import chisel3._ 4import chisel3.util._ 5import chiseltest._ 6import org.scalatest.flatspec.AnyFlatSpec 7import org.scalatest.matchers.must.Matchers 8import xiangshan.backend.fu.vector.Utils.{NOnes, NZeros} 9 10class UIntToContLow0s(uintWidth: Int) extends Module { 11 private val outWidth = (1 << uintWidth) - 1 // 2^n - 1 12 13 val io = IO(new Bundle { 14 val dataIn = Input(UInt(uintWidth.W)) 15 val dataOut = Output(UInt(outWidth.W)) 16 }) 17 18 io.dataOut := helper(io.dataIn) 19 20 private def helper(data: UInt): UInt = data.getWidth match { 21 case 1 => Mux(data(0), 0.U(1.W), 1.U(1.W)) 22 case w => Mux( 23 data(w - 1), 24 Cat(helper(data(w - 2, 0)), NZeros(1 << (w - 1))), 25 Cat(NOnes(1 << (w - 1)), helper(data(w - 2, 0))) 26 ) 27 } 28} 29 30object UIntToContLow0s { 31 def apply(uint: UInt): UInt = apply(uint, uint.getWidth) 32 33 def apply(uint: UInt, width: Int): UInt = { 34 val uintToContTail0sMod = Module(new UIntToContLow0s(uint.getWidth)).suggestName(s"uintToContTail0sMod${width}Bits") 35 uintToContTail0sMod.io.dataIn := uint 36 val dataOutWidth = uintToContTail0sMod.io.dataOut.getWidth 37 if (width <= dataOutWidth) { 38 uintToContTail0sMod.io.dataOut(width - 1, 0) 39 } else { 40 Cat(0.U((width - dataOutWidth).W), uintToContTail0sMod.io.dataOut) 41 } 42 } 43} 44 45object UIntToContHigh0s { 46 def apply(uint: UInt): UInt = Reverse(UIntToContLow0s(uint)) 47 def apply(uint: UInt, width: Int): UInt = Reverse(UIntToContLow0s(uint, width)) 48} 49 50class UIntToContLow0sTest extends AnyFlatSpec with ChiselScalatestTester with Matchers { 51 52 private val uintWidth = 3 53 private val outWidth = (1 << uintWidth) - 1 54 55 private val testSeq = Seq( 56 0.U -> "b1111111".U, 57 1.U -> "b1111110".U, 58 2.U -> "b1111100".U, 59 3.U -> "b1111000".U, 60 4.U -> "b1110000".U, 61 5.U -> "b1100000".U, 62 6.U -> "b1000000".U, 63 7.U -> "b0000000".U, 64 ) 65 66 behavior of "UIntToContLow0s" 67 it should "run" in { 68 test(new UIntToContLow0s(uintWidth)) { 69 m: UIntToContLow0s => 70 for (((uint, res), i) <- testSeq.zipWithIndex) { 71 m.io.dataIn.poke(uint) 72 73 val message = "i: " + i + 74 " uint: " + uint.litValue.toInt.toBinaryString + 75 " right result: " + res.litValue.toInt.toBinaryString 76 77 m.io.dataOut.expect(res, message) 78 } 79 } 80 } 81 println("test done") 82}