Implement RFC 17: Remove log2_int.

Reexports of `amaranth.utils` functions are removed from
`amaranth._utils` to avoid a circular import issue (for `deprecated`).
Since this is a private module, this should not be a problem.
This commit is contained in:
Wanda 2024-01-10 05:16:10 +01:00 committed by Catherine
parent ea258fad71
commit 7f76914b74
8 changed files with 142 additions and 20 deletions

View file

@ -6,11 +6,9 @@ import re
from collections import OrderedDict
from collections.abc import Iterable
from .utils import *
__all__ = ["flatten", "union" , "log2_int", "bits_for", "memoize", "final", "deprecated",
"get_linter_options", "get_linter_option"]
__all__ = ["flatten", "union", "memoize", "final", "deprecated", "get_linter_options",
"get_linter_option"]
def flatten(i):

View file

@ -4,7 +4,8 @@ from contextlib import contextmanager
import warnings
import re
from .._utils import bits_for, flatten
from .._utils import flatten
from ..utils import bits_for
from ..hdl import ast, ir, mem, xfrm, _repr
from ..lib import wiring

View file

@ -10,6 +10,7 @@ from itertools import chain
from ._repr import *
from .. import tracer
from ..utils import *
from .._utils import *
from .._utils import _ignore_deprecated
from .._unused import *

View file

@ -5,7 +5,8 @@ from enum import Enum
import warnings
import sys
from .._utils import flatten, bits_for
from .._utils import flatten
from ..utils import bits_for
from .. import tracer
from .ast import *
from .ir import *

View file

@ -4,7 +4,7 @@ import warnings
from .. import *
from ..asserts import *
from .._utils import log2_int
from ..utils import ceil_log2
from .coding import GrayEncoder, GrayDecoder
from .cdc import FFSynchronizer, AsyncFFSynchronizer
@ -353,13 +353,12 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
def __init__(self, *, width, depth, r_domain="read", w_domain="write", exact_depth=False):
if depth != 0:
try:
depth_bits = log2_int(depth, need_pow2=exact_depth)
depth = 1 << depth_bits
except ValueError:
depth_bits = ceil_log2(depth)
if exact_depth and depth != 1 << depth_bits:
raise ValueError("AsyncFIFO only supports depths that are powers of 2; requested "
"exact depth {} is not"
.format(depth)) from None
depth = 1 << depth_bits
else:
depth_bits = 0
super().__init__(width=width, depth=depth)
@ -530,13 +529,12 @@ class AsyncFIFOBuffered(Elaboratable, FIFOInterface):
def __init__(self, *, width, depth, r_domain="read", w_domain="write", exact_depth=False):
if depth != 0:
try:
depth_bits = log2_int(max(0, depth - 1), need_pow2=exact_depth)
depth = (1 << depth_bits) + 1
except ValueError:
depth_bits = ceil_log2(max(0, depth - 1))
if exact_depth and depth != (1 << depth_bits) + 1:
raise ValueError("AsyncFIFOBuffered only supports depths that are one higher "
"than powers of 2; requested exact depth {} is not"
.format(depth)) from None
depth = (1 << depth_bits) + 1
super().__init__(width=width, depth=depth)
self.r_rst = Signal()

View file

@ -1,7 +1,35 @@
__all__ = ["log2_int", "bits_for"]
import operator
from ._utils import deprecated
__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()
@deprecated("instead of `log2_int(n, True)`, use `exact_log2(n)`; instead of `log2_int(n, False)` use `ceil_log2(n)`")
def log2_int(n, need_pow2=True):
n = operator.index(n)
if n == 0:
return 0
r = (n - 1).bit_length()
@ -11,11 +39,12 @@ def log2_int(n, need_pow2=True):
def bits_for(n, require_sign_bit=False):
n = operator.index(n)
if n > 0:
r = log2_int(n + 1, False)
r = ceil_log2(n + 1)
else:
require_sign_bit = True
r = log2_int(-n, False)
r = ceil_log2(-n)
if require_sign_bit:
r += 1
return r