From d562d0ea60808d58fccc5584241554132492ec76 Mon Sep 17 00:00:00 2001 From: Wanda Date: Fri, 16 Feb 2024 12:29:31 +0100 Subject: [PATCH] utils: backport `ceil_log2` and `exact_log2`. --- amaranth/utils.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/amaranth/utils.py b/amaranth/utils.py index cf98f3d1c..4f25af68b 100644 --- a/amaranth/utils.py +++ b/amaranth/utils.py @@ -1,5 +1,28 @@ -__all__ = ["log2_int", "bits_for"] +import operator +__all__ = ["ceil_log2", "exact_log2", "log2_int", "bits_for"] + + +def ceil_log2(n): + """Returns the integer log2 of the smallest power-of-2 greater than or equal to `n`. + + Raises a `ValueError` for negative inputs.""" + n = operator.index(n) + if n < 0: + raise ValueError("{n} is negative") + if n == 0: + return 0 + return (n - 1).bit_length() + + +def exact_log2(n): + """Returns the integer log2 of `n`, which must be an exact power of two. + + Raises a `ValueError` if `n` is not a power of two.""" + n = operator.index(n) + if n <= 0 or (n & (n - 1)): + raise ValueError("{n} is not a power of 2") + return (n - 1).bit_length() def log2_int(n, need_pow2=True): if n == 0: