From ebe21a33645e7fdf10b8c65a638d02b13e0dc8e9 Mon Sep 17 00:00:00 2001 From: Liu Xiaoyi Date: Mon, 7 Mar 2022 21:19:26 +0800 Subject: [PATCH] Rename scanLeft/RightOr, switch to impl from rocket-chip and more documentation --- .../util/experimental/algorithm/Bitwise.scala | 45 +++++-------------- .../experimental/util/algorithm/Bitwise.scala | 41 ++++++++--------- 2 files changed, 31 insertions(+), 55 deletions(-) diff --git a/integration-tests/src/test/scala/chiselTests/util/experimental/algorithm/Bitwise.scala b/integration-tests/src/test/scala/chiselTests/util/experimental/algorithm/Bitwise.scala index 5b83508a7d0..8bf79d795b8 100644 --- a/integration-tests/src/test/scala/chiselTests/util/experimental/algorithm/Bitwise.scala +++ b/integration-tests/src/test/scala/chiselTests/util/experimental/algorithm/Bitwise.scala @@ -8,28 +8,7 @@ import chiseltest.formal._ import org.scalatest.flatspec.AnyFlatSpec import scala.math.min -// Copied from rocket-core -object RocketImpl { - // Fill 1s from low bits to high bits - def leftOR(x: UInt): UInt = leftOR(x, x.getWidth, x.getWidth) - def leftOR(x: UInt, width: Integer, cap: Integer = 999999): UInt = { - val stop = min(width, cap) - def helper(s: Int, x: UInt): UInt = - if (s >= stop) x else helper(s+s, x | (x << s)(width-1,0)) - helper(1, x)(width-1, 0) - } - - // Fill 1s form high bits to low bits - def rightOR(x: UInt): UInt = rightOR(x, x.getWidth, x.getWidth) - def rightOR(x: UInt, width: Integer, cap: Integer = 999999): UInt = { - val stop = min(width, cap) - def helper(s: Int, x: UInt): UInt = - if (s >= stop) x else helper(s+s, x | (x >> s)) - helper(1, x)(width-1, 0) - } -} - -class LSBOrTestModule(width: Int) extends Module { +class scanLeftOrTestModule(width: Int) extends Module { val input = IO(Input(UInt(width.W))) var lsb = false.B @@ -39,35 +18,31 @@ class LSBOrTestModule(width: Int) extends Module { cur } val ref = VecInit(vec).asUInt - val rocketRef = RocketImpl.leftOR(input) - val testee = LSBOr(input) + val testee = scanLeftOr(input) assert(testee === ref) - assert(testee === rocketRef) } -class MSBOrTestModule(width: Int) extends Module { +class scanRightOrTestModule(width: Int) extends Module { val input = IO(Input(UInt(width.W))) - val ref = Reverse(LSBOr(Reverse(input))) - val rocketRef = RocketImpl.rightOR(input) - val testee = MSBOr(input) + val ref = Reverse(scanLeftOr(Reverse(input))) + val testee = scanRightOr(input) assert(testee === ref) - assert(testee === rocketRef) } -class LSBMSBOrTest extends AnyFlatSpec with ChiselScalatestTester with Formal { - "LSBOr" should "correctly computes" in { +class scanOrTest extends AnyFlatSpec with ChiselScalatestTester with Formal { + "scanLeftOr" should "correctly computes" in { for(i <- 1 to 16) { - verify(new LSBOrTestModule(i), Seq(BoundedCheck(1))) + verify(new scanLeftOrTestModule(i), Seq(BoundedCheck(1))) } } - "MSBOr" should "correctly computes" in { + "scanRightOr" should "correctly computes" in { for(i <- 1 to 16) { - verify(new MSBOrTestModule(i), Seq(BoundedCheck(1))) + verify(new scanRightOrTestModule(i), Seq(BoundedCheck(1))) } } } \ No newline at end of file diff --git a/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala b/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala index 6e1b158addb..c7ce4b05f0c 100644 --- a/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala +++ b/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala @@ -4,42 +4,43 @@ package chisel3.experimental.util.algorithm import chisel3._ -/** Map each bits to logical or of itself and all bits less siginificant than it. +/** Map each bits to logical or of itself and all bits with lower index. + * Here 'left' means 'with lower index', as in arrays and lists, not to be confused with the 'left' as in 'shift left' * @example {{{ - * LSBOr("b00001000".U) // Returns "b11111000".U - * LSBOr("b00010100".U) // Returns "b11111100".U - * LSBOr("b00000000".U) // Returns "b00000000".U + * scanLeftOr("b00001000".U) // Returns "b11111000".U + * scanLeftOr("b00010100".U) // Returns "b11111100".U + * scanLeftOr("b00000000".U) // Returns "b00000000".U * }}} - * This circuit seems to be high fan out, but synthesis tool should handle this. */ -object LSBOr { +object scanLeftOr { def apply(data: UInt): UInt = { val width = data.widthOption match { case Some(w) => w - case None => throw new IllegalArgumentException("Cannot call LSBOr on data with unknown width.") + case None => throw new IllegalArgumentException("Cannot call scanLeftOr on data with unknown width.") } - VecInit(Seq.tabulate(width) { i: Int => - VecInit(data.asBools().dropRight(width - i - 1)).asUInt().orR() - }).asUInt() + + def helper(s: Int, x: UInt): UInt = + if (s >= width) x else helper(s+s, x | (x << s)(width-1,0)) + helper(1, x)(width-1, 0) } } -/** Map each bits to logical or of itself and all bits more siginificant than it. - * @example {{{ - * MSBOr("b00001000".U) // Returns "b00001111".U - * MSBOr("b00010100".U) // Returns "b00011111".U - * MSBOr("b00000000".U) // Returns "b00000000".U +/** Map each bits to logical or of itself and all bits with higher index. + * Here 'right' means 'with higher index', as in arrays and lists, not to be confused with the 'right' as in 'shift right' + * scanRightOr("b00001000".U) // Returns "b00001111".U + * scanRightOr("b00010100".U) // Returns "b00011111".U + * scanRightOr("b00000000".U) // Returns "b00000000".U * }}} * This circuit seems to be high fan out, but synthesis tool should handle this. */ -object MSBOr { +object scanRightOr { def apply(data: UInt): UInt = { val width = data.widthOption match { case Some(w) => w - case None => throw new IllegalArgumentException("Cannot call MSBOr on data with unknown width.") + case None => throw new IllegalArgumentException("Cannot call scanRightOr on data with unknown width.") } - VecInit(Seq.tabulate(width) { i: Int => - VecInit(data.asBools().drop(i)).asUInt().orR() - }).asUInt() + def helper(s: Int, x: UInt): UInt = + if (s >= width) x else helper(s+s, x | (x >> s)) + helper(1, x)(width-1, 0) } }