From 941dd7ee76cadacbdd10b3d10d267f5d58a7ed4e Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Tue, 8 Mar 2022 00:30:37 +0000 Subject: Add scanLeftOr and scanRightOr utilies (#2407) (#2437) Co-authored-by: Jiuyang Liu Co-authored-by: Megan Wachs Co-authored-by: Jack Koenig (cherry picked from commit 73d3c26029c07c17ce179dfead092eab4fb8ae2c) Co-authored-by: Liu Xiaoyi --- .../experimental/util/algorithm/Bitwise.scala | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala (limited to 'src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala') diff --git a/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala b/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala new file mode 100644 index 00000000..6b4bb8f0 --- /dev/null +++ b/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chisel3.util + +import chisel3._ + +/** Map each bit to the logical OR of itself and all bits with lower index + * + * Here `scanLeft` means "start from the left and iterate to the right, where left is the lowest index", a common operation on arrays and lists. + * @example {{{ + * scanLeftOr("b00001000".U(8.W)) // Returns "b11111000".U + * scanLeftOr("b00010100".U(8.W)) // Returns "b11111100".U + * scanLeftOr("b00000000".U(8.W)) // Returns "b00000000".U + * }}} + */ +object scanLeftOr { + def apply(data: UInt): UInt = { + val width = data.widthOption match { + case Some(w) => w + case None => throw new IllegalArgumentException("Cannot call scanLeftOr on data with unknown width.") + } + + def helper(s: Int, x: UInt): UInt = + if (s >= width) x else helper(s + s, x | (x << s)(width - 1, 0)) + helper(1, data)(width - 1, 0) + } +} + +/** Map each bit to the logical OR of itself and all bits with higher index + * + * Here `scanRight` means "start from the right and iterate to the left, where right is the highest index", a common operation on arrays and lists. + * @example {{{ + * scanRightOr("b00001000".U) // Returns "b00001111".U + * scanRightOr("b00010100".U) // Returns "b00011111".U + * scanRightOr("b00000000".U) // Returns "b00000000".U + * }}} + */ +object scanRightOr { + def apply(data: UInt): UInt = { + val width = data.widthOption match { + case Some(w) => w + case None => throw new IllegalArgumentException("Cannot call scanRightOr on data with unknown width.") + } + def helper(s: Int, x: UInt): UInt = + if (s >= width) x else helper(s + s, x | (x >> s)) + helper(1, data)(width - 1, 0) + } +} -- cgit v1.2.3