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:
parent
ea258fad71
commit
7f76914b74
8 changed files with 142 additions and 20 deletions
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue