From 5a79c351e30b5741fbc07c7dbb44cdfecc7e5a44 Mon Sep 17 00:00:00 2001 From: Catherine Date: Tue, 31 Jan 2023 21:38:27 +0000 Subject: [PATCH] Remove features deprecated in version 0.3. --- amaranth/back/pysim.py | 11 ---- amaranth/back/rtlil.py | 12 +--- amaranth/back/verilog.py | 7 +-- amaranth/hdl/ast.py | 51 +--------------- amaranth/hdl/xfrm.py | 3 - amaranth/sim/core.py | 5 -- amaranth/test/__init__.py | 1 - amaranth/test/utils.py | 84 --------------------------- amaranth/vendor/lattice_machxo2.py | 11 ---- amaranth/vendor/xilinx_7series.py | 15 ----- amaranth/vendor/xilinx_spartan_3_6.py | 16 ----- amaranth/vendor/xilinx_ultrascale.py | 15 ----- docs/changes.rst | 23 +++++--- tests/test_hdl_ast.py | 33 ----------- tests/test_hdl_xfrm.py | 53 ----------------- 15 files changed, 21 insertions(+), 319 deletions(-) delete mode 100644 amaranth/back/pysim.py delete mode 100644 amaranth/test/__init__.py delete mode 100644 amaranth/test/utils.py delete mode 100644 amaranth/vendor/lattice_machxo2.py delete mode 100644 amaranth/vendor/xilinx_7series.py delete mode 100644 amaranth/vendor/xilinx_spartan_3_6.py delete mode 100644 amaranth/vendor/xilinx_ultrascale.py diff --git a/amaranth/back/pysim.py b/amaranth/back/pysim.py deleted file mode 100644 index 91f52ea..0000000 --- a/amaranth/back/pysim.py +++ /dev/null @@ -1,11 +0,0 @@ -import warnings - -from ..sim import * - - -__all__ = ["Settle", "Delay", "Tick", "Passive", "Active", "Simulator"] - - -# TODO(amaranth-0.4): remove -warnings.warn("instead of amaranth.back.pysim.*, use amaranth.sim.*", - DeprecationWarning, stacklevel=2) diff --git a/amaranth/back/rtlil.py b/amaranth/back/rtlil.py index ca0d0f6..8d18f6c 100644 --- a/amaranth/back/rtlil.py +++ b/amaranth/back/rtlil.py @@ -411,11 +411,7 @@ class _ValueCompiler(xfrm.ValueVisitor): if value.start == 0 and value.stop == len(value.value): return self(value.value) - if isinstance(value.value, ast.UserValue): - sigspec = self._prepare_value_for_Slice(value.value._lazy_lower()) - else: - sigspec = self._prepare_value_for_Slice(value.value) - + sigspec = self._prepare_value_for_Slice(value.value) if value.start == value.stop: return "{}" elif value.start + 1 == value.stop: @@ -1041,11 +1037,7 @@ def convert_fragment(fragment, name="top", *, emit_src=True): return str(builder), name_map -def convert(elaboratable, name="top", platform=None, ports=None, *, emit_src=True, **kwargs): - # TODO(amaranth-0.4): remove - if ports is None: - warnings.warn("Implicit port determination is deprecated, specify ports explicitly", - DeprecationWarning, stacklevel=2) +def convert(elaboratable, name="top", platform=None, *, ports, emit_src=True, **kwargs): fragment = ir.Fragment.get(elaboratable, platform).prepare(ports=ports, **kwargs) il_text, name_map = convert_fragment(fragment, name, emit_src=emit_src) return il_text diff --git a/amaranth/back/verilog.py b/amaranth/back/verilog.py index 894878d..d8fe952 100644 --- a/amaranth/back/verilog.py +++ b/amaranth/back/verilog.py @@ -42,11 +42,8 @@ def convert_fragment(*args, strip_internal_attrs=False, **kwargs): return _convert_rtlil_text(rtlil_text, strip_internal_attrs=strip_internal_attrs), name_map -def convert(elaboratable, name="top", platform=None, ports=None, *, emit_src=True, strip_internal_attrs=False, **kwargs): - # TODO(amaranth-0.4): remove - if ports is None: - warnings.warn("Implicit port determination is deprecated, specify ports explicitly", - DeprecationWarning, stacklevel=2) +def convert(elaboratable, name="top", platform=None, *, ports, emit_src=True, + strip_internal_attrs=False, **kwargs): fragment = ir.Fragment.get(elaboratable, platform).prepare(ports=ports, **kwargs) verilog_text, name_map = convert_fragment(fragment, name, emit_src=emit_src, strip_internal_attrs=strip_internal_attrs) return verilog_text diff --git a/amaranth/hdl/ast.py b/amaranth/hdl/ast.py index c3468f8..f636114 100644 --- a/amaranth/hdl/ast.py +++ b/amaranth/hdl/ast.py @@ -16,7 +16,7 @@ __all__ = [ "Value", "Const", "C", "AnyConst", "AnySeq", "Operator", "Mux", "Part", "Slice", "Cat", "Repl", "Array", "ArrayProxy", "Signal", "ClockSignal", "ResetSignal", - "UserValue", "ValueCastable", + "ValueCastable", "Sample", "Past", "Stable", "Rose", "Fell", "Initial", "Statement", "Switch", "Property", "Assign", "Assert", "Assume", "Cover", @@ -1243,55 +1243,6 @@ class ArrayProxy(Value): return "(proxy (array [{}]) {!r})".format(", ".join(map(repr, self.elems)), self.index) -# TODO(amaranth-0.4): remove -class UserValue(Value): - """Value with custom lowering. - - A ``UserValue`` is a value whose precise representation does not have to be immediately known, - which is useful in certain metaprogramming scenarios. Instead of providing fixed semantics - upfront, it is kept abstract for as long as possible, only being lowered to a concrete Amaranth - value when required. - - Note that the ``lower`` method will only be called once; this is necessary to ensure that - Amaranth's view of representation of all values stays internally consistent. If the class - deriving from ``UserValue`` is mutable, then it must ensure that after ``lower`` is called, - it is not mutated in a way that changes its representation. - - The following is an incomplete list of actions that, when applied to an ``UserValue`` directly - or indirectly, will cause it to be lowered, provided as an illustrative reference: - * Querying the shape using ``.shape()`` or ``len()``; - * Creating a similarly shaped signal using ``Signal.like``; - * Indexing or iterating through individual bits; - * Adding an assignment to the value to a ``Module`` using ``m.d. +=``. - """ - @deprecated("instead of `UserValue`, use `ValueCastable`", stacklevel=3) - def __init__(self, *, src_loc_at=0): - super().__init__(src_loc_at=1 + src_loc_at) - self.__lowered = None - - @abstractmethod - def lower(self): - """Conversion to a concrete representation.""" - pass # :nocov: - - def _lazy_lower(self): - if self.__lowered is None: - lowered = self.lower() - if isinstance(lowered, UserValue): - lowered = lowered._lazy_lower() - self.__lowered = Value.cast(lowered) - return self.__lowered - - def shape(self): - return self._lazy_lower().shape() - - def _lhs_signals(self): - return self._lazy_lower()._lhs_signals() - - def _rhs_signals(self): - return self._lazy_lower()._rhs_signals() - - class ValueCastable: """Interface of user-defined objects that can be cast to :class:`Value` s. diff --git a/amaranth/hdl/xfrm.py b/amaranth/hdl/xfrm.py index 924cb77..8e6fab8 100644 --- a/amaranth/hdl/xfrm.py +++ b/amaranth/hdl/xfrm.py @@ -114,9 +114,6 @@ class ValueVisitor(metaclass=ABCMeta): new_value = self.on_Sample(value) elif type(value) is Initial: new_value = self.on_Initial(value) - elif isinstance(value, UserValue): - # Uses `isinstance()` and not `type() is` to allow inheriting. - new_value = self.on_value(value._lazy_lower()) else: new_value = self.on_unknown_value(value) if isinstance(new_value, Value) and self.replace_value_src_loc(value, new_value): diff --git a/amaranth/sim/core.py b/amaranth/sim/core.py index f8a86bb..67ba66b 100644 --- a/amaranth/sim/core.py +++ b/amaranth/sim/core.py @@ -151,11 +151,6 @@ class Simulator: """ self._engine.reset() - # TODO(amaranth-0.4): replace with _real_step - @deprecated("instead of `sim.step()`, use `sim.advance()`") - def step(self): - return self.advance() - def advance(self): """Advance the simulation. diff --git a/amaranth/test/__init__.py b/amaranth/test/__init__.py deleted file mode 100644 index c09c28b..0000000 --- a/amaranth/test/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# TODO(amaranth-0.4): remove the entire package diff --git a/amaranth/test/utils.py b/amaranth/test/utils.py deleted file mode 100644 index 30661b1..0000000 --- a/amaranth/test/utils.py +++ /dev/null @@ -1,84 +0,0 @@ -import os -import re -import shutil -import subprocess -import textwrap -import traceback -import unittest -import warnings - -from ..hdl.ast import * -from ..hdl.ir import * -from ..back import rtlil -from .._toolchain import require_tool - - -warnings.warn("amaranth.test.utils is an internal utility module that has several design flaws " - "and was never intended as a public API; it will be removed in amaranth 0.4. " - "if you are using FHDLTestCase, include its implementation in your codebase. " - "see also amaranth-lang/amaranth#487", - DeprecationWarning, stacklevel=2) - - -__all__ = ["FHDLTestCase"] - - -class FHDLTestCase(unittest.TestCase): - def assertRepr(self, obj, repr_str): - if isinstance(obj, list): - obj = Statement.cast(obj) - def prepare_repr(repr_str): - repr_str = re.sub(r"\s+", " ", repr_str) - repr_str = re.sub(r"\( (?=\()", "(", repr_str) - repr_str = re.sub(r"\) (?=\))", ")", repr_str) - return repr_str.strip() - self.assertEqual(prepare_repr(repr(obj)), prepare_repr(repr_str)) - - def assertFormal(self, spec, mode="bmc", depth=1): - caller, *_ = traceback.extract_stack(limit=2) - spec_root, _ = os.path.splitext(caller.filename) - spec_dir = os.path.dirname(spec_root) - spec_name = "{}_{}".format( - os.path.basename(spec_root).replace("test_", "spec_"), - caller.name.replace("test_", "") - ) - - # The sby -f switch seems not fully functional when sby is reading from stdin. - if os.path.exists(os.path.join(spec_dir, spec_name)): - shutil.rmtree(os.path.join(spec_dir, spec_name)) - - if mode == "hybrid": - # A mix of BMC and k-induction, as per personal communication with Claire Wolf. - script = "setattr -unset init w:* a:amaranth.sample_reg %d" - mode = "bmc" - else: - script = "" - - config = textwrap.dedent("""\ - [options] - mode {mode} - depth {depth} - wait on - - [engines] - smtbmc - - [script] - read_ilang top.il - prep - {script} - - [file top.il] - {rtlil} - """).format( - mode=mode, - depth=depth, - script=script, - rtlil=rtlil.convert(Fragment.get(spec, platform="formal")) - ) - with subprocess.Popen([require_tool("sby"), "-f", "-d", spec_name], cwd=spec_dir, - universal_newlines=True, - stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc: - stdout, stderr = proc.communicate(config) - if proc.returncode != 0: - self.fail("Formal verification failed:\n" + stdout) diff --git a/amaranth/vendor/lattice_machxo2.py b/amaranth/vendor/lattice_machxo2.py deleted file mode 100644 index ff593ba..0000000 --- a/amaranth/vendor/lattice_machxo2.py +++ /dev/null @@ -1,11 +0,0 @@ -import warnings - -from .lattice_machxo_2_3l import LatticeMachXO2Platform - - -__all__ = ["LatticeMachXO2Platform"] - - -# TODO(amaranth-0.4): remove -warnings.warn("instead of amaranth.vendor.lattice_machxo2, use amaranth.vendor.lattice_machxo_2_3l", - DeprecationWarning, stacklevel=2) diff --git a/amaranth/vendor/xilinx_7series.py b/amaranth/vendor/xilinx_7series.py deleted file mode 100644 index 59ee182..0000000 --- a/amaranth/vendor/xilinx_7series.py +++ /dev/null @@ -1,15 +0,0 @@ -import warnings - -from .xilinx import XilinxPlatform - - -__all__ = ["Xilinx7SeriesPlatform"] - - -Xilinx7SeriesPlatform = XilinxPlatform - - -# TODO(amaranth-0.4): remove -warnings.warn("instead of amaranth.vendor.xilinx_7series.Xilinx7SeriesPlatform, " - "use amaranth.vendor.xilinx.XilinxPlatform", - DeprecationWarning, stacklevel=2) diff --git a/amaranth/vendor/xilinx_spartan_3_6.py b/amaranth/vendor/xilinx_spartan_3_6.py deleted file mode 100644 index fbed4a1..0000000 --- a/amaranth/vendor/xilinx_spartan_3_6.py +++ /dev/null @@ -1,16 +0,0 @@ -import warnings - -from .xilinx import XilinxPlatform - - -__all__ = ["XilinxSpartan3APlatform", "XilinxSpartan6Platform"] - - -XilinxSpartan3APlatform = XilinxPlatform -XilinxSpartan6Platform = XilinxPlatform - - -# TODO(amaranth-0.4): remove -warnings.warn("instead of amaranth.vendor.xilinx_spartan_3_6.XilinxSpartan3APlatform and " - ".XilinxSpartan6Platform, use amaranth.vendor.xilinx.XilinxPlatform", - DeprecationWarning, stacklevel=2) diff --git a/amaranth/vendor/xilinx_ultrascale.py b/amaranth/vendor/xilinx_ultrascale.py deleted file mode 100644 index 43fb2f2..0000000 --- a/amaranth/vendor/xilinx_ultrascale.py +++ /dev/null @@ -1,15 +0,0 @@ -import warnings - -from .xilinx import XilinxPlatform - - -__all__ = ["XilinxUltraScalePlatform"] - - -XilinxUltraScalePlatform = XilinxPlatform - - -# TODO(amaranth-0.4): remove -warnings.warn("instead of amaranth.vendor.xilinx_ultrascale.XilinxUltraScalePlatform, " - "use amaranth.vendor.xilinx.XilinxPlatform", - DeprecationWarning, stacklevel=2) diff --git a/docs/changes.rst b/docs/changes.rst index 12907cc..3f0f825 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -4,10 +4,10 @@ Changelog This document describes changes to the public interfaces in the Amaranth language and standard library. It does not include most bug fixes or implementation changes. -Next version -============ +Version 0.4 (unreleased) +======================== -Support for Python 3.6 has been dropped, and support for Python 3.11 has been added. +Support for Python 3.6 has been removed, and support for Python 3.11 has been added. Features deprecated in version 0.3 have been removed. In particular, the ``nmigen.*`` namespace is not provided, ``# nmigen:`` annotations are not recognized, and ``NMIGEN_*`` envronment variables are not used. @@ -15,12 +15,12 @@ Features deprecated in version 0.3 have been removed. In particular, the ``nmige Migrating from version 0.3 -------------------------- -Apply the following changes to code written against Amaranth 0.2 to migrate it to version 0.3: +Apply the following changes to code written against Amaranth 0.3 to migrate it to version 0.4: * Update shell environment to use ``AMARANTH_*`` environment variables instead of ``NMIGEN_*`` environment variables. -* Update shell environment to use ``AMARANTH_ENV_`` (with all-uppercase ````name) environment variable names instead of ``AMARANTH_ENV_`` or ``NMIGEN_ENV_`` (with mixed-case ```` name). +* Update shell environment to use ``AMARANTH_ENV_`` (with all-uppercase ```` name) environment variable names instead of ``AMARANTH_ENV_`` or ``NMIGEN_ENV_`` (with mixed-case ```` name). -While code that uses the features listed as deprecated below will work in Amaranth 0.3, they will be removed in the next version. +While code that uses the features listed as deprecated below will work in Amaranth 0.4, they will be removed in the next version. Language changes @@ -28,12 +28,14 @@ Language changes .. currentmodule:: amaranth.hdl -* Removed: casting of :class:`Shape` to and from a ``(width, signed)`` tuple. * Added: :class:`ShapeCastable`, similar to :class:`ValueCastable`. * Added: :meth:`Value.as_signed` and :meth:`Value.as_unsigned` can be used on left-hand side of assignment (with no difference in behavior). * Changed: :meth:`Value.cast` casts :class:`ValueCastable` objects recursively. * Changed: :meth:`Value.cast` treats instances of classes derived from both :class:`enum.Enum` and :class:`int` (including :class:`enum.IntEnum`) as enumerations rather than integers. * Changed: :class:`Cat` accepts instances of classes derived from both :class:`enum.Enum` and :class:`int` (including :class:`enum.IntEnum`) without warning. +* Removed: (deprecated in 0.1) casting of :class:`Shape` to and from a ``(width, signed)`` tuple. +* Removed: (deprecated in 0.3) :class:`ast.UserValue`. +* Removed: (deprecated in 0.3) support for ``# nmigen:`` linter instructions at the beginning of file. Toolchain changes @@ -43,6 +45,10 @@ Toolchain changes * Added: ``debug_verilog`` override in :class:`build.TemplatedPlatform`. * Deprecated: use of mixed-case toolchain environment variable names, such as ``NMIGEN_ENV_Diamond`` or ``AMARANTH_ENV_Diamond``; use upper-case environment variable names, such as ``AMARANTH_ENV_DIAMOND``. +* Removed: (deprecated in 0.3) :meth:`sim.Simulator.step`. +* Removed: (deprecated in 0.3) :mod:`back.pysim`. +* Removed: (deprecated in 0.3) support for invoking :func:`back.rtlil.convert()` and :func:`back.verilog.convert()` without an explicit `ports=` argument. +* Removed: (deprecated in 0.3) :mod:`test`. Platform integration changes @@ -52,6 +58,9 @@ Platform integration changes * Added: ``OSCH`` as ``default_clk`` clock source in :class:`vendor.lattice_machxo_2_3l.LatticeMachXO2Or3LPlatform`. * Added: Xray toolchain support in :class:`vendor.xilinx.XilinxPlatform`. +* Removed: (deprecated in 0.3) :mod:`lattice_machxo2` +* Removed: (deprecated in 0.3) :class:`lattice_machxo_2_3l.LatticeMachXO2Or3LPlatform` SVF programming vector ``{{name}}.svf``. +* Removed: (deprecated in 0.3) :class:`xilinx_spartan_3_6.XilinxSpartan3APlatform`, :class:`xilinx_spartan_3_6.XilinxSpartan6Platform`, :class:`xilinx_7series.Xilinx7SeriesPlatform`, :class:`xilinx_ultrascale.XilinxUltrascalePlatform`. Version 0.3 diff --git a/tests/test_hdl_ast.py b/tests/test_hdl_ast.py index 5231c0a..38502e1 100644 --- a/tests/test_hdl_ast.py +++ b/tests/test_hdl_ast.py @@ -1083,39 +1083,6 @@ class ResetSignalTestCase(FHDLTestCase): ResetSignal("comb") -class MockUserValue(UserValue): - def __init__(self, lowered): - super().__init__() - self.lower_count = 0 - self.lowered = lowered - - def lower(self): - self.lower_count += 1 - return self.lowered - - -class UserValueTestCase(FHDLTestCase): - def test_shape(self): - with warnings.catch_warnings(): - warnings.filterwarnings(action="ignore", category=DeprecationWarning) - uv = MockUserValue(1) - self.assertEqual(uv.shape(), unsigned(1)) - self.assertIsInstance(uv.shape(), Shape) - uv.lowered = 2 - self.assertEqual(uv.shape(), unsigned(1)) - self.assertEqual(uv.lower_count, 1) - - def test_lower_to_user_value(self): - with warnings.catch_warnings(): - warnings.filterwarnings(action="ignore", category=DeprecationWarning) - uv = MockUserValue(MockUserValue(1)) - self.assertEqual(uv.shape(), unsigned(1)) - self.assertIsInstance(uv.shape(), Shape) - uv.lowered = MockUserValue(2) - self.assertEqual(uv.shape(), unsigned(1)) - self.assertEqual(uv.lower_count, 1) - - class MockValueCastable(ValueCastable): def __init__(self, dest): self.dest = dest diff --git a/tests/test_hdl_xfrm.py b/tests/test_hdl_xfrm.py index ec3ebc1..14b1173 100644 --- a/tests/test_hdl_xfrm.py +++ b/tests/test_hdl_xfrm.py @@ -601,56 +601,3 @@ class TransformedElaboratableTestCase(FHDLTestCase): ) ) """) - - -class MockUserValue(UserValue): - def __init__(self, lowered): - super().__init__() - self.lowered = lowered - - def lower(self): - return self.lowered - - -class UserValueTestCase(FHDLTestCase): - def setUp(self): - self.s = Signal() - self.c = Signal() - with warnings.catch_warnings(): - warnings.filterwarnings(action="ignore", category=DeprecationWarning) - self.uv = MockUserValue(self.s) - - def test_lower(self): - sync = ClockDomain() - f = Fragment() - f.add_domains(sync) - f.add_statements( - self.uv.eq(1) - ) - for signal in self.uv._lhs_signals(): - f.add_driver(signal, "sync") - - f = ResetInserter(self.c)(f) - f = DomainLowerer()(f) - self.assertRepr(f.statements, """ - ( - (eq (sig s) (const 1'd1)) - (switch (sig c) - (case 1 (eq (sig s) (const 1'd0))) - ) - (switch (sig rst) - (case 1 (eq (sig s) (const 1'd0))) - ) - ) - """) - - -class UserValueRecursiveTestCase(UserValueTestCase): - def setUp(self): - self.s = Signal() - self.c = Signal() - with warnings.catch_warnings(): - warnings.filterwarnings(action="ignore", category=DeprecationWarning) - self.uv = MockUserValue(MockUserValue(self.s)) - - # inherit the test_lower method from UserValueTestCase because the checks are the same