diff --git a/amaranth/lib/coding.py b/amaranth/lib/coding.py
deleted file mode 100644
index f7a4b75ee..000000000
--- a/amaranth/lib/coding.py
+++ /dev/null
@@ -1,192 +0,0 @@
-import warnings
-
-warnings.warn("the `amaranth.lib.coding` module will be removed without a replacement; "
- "copy the module into your project to continue using it",
- DeprecationWarning, stacklevel=2)
-
-
-from .. import *
-
-
-__all__ = [
- "Encoder", "Decoder",
- "PriorityEncoder", "PriorityDecoder",
- "GrayEncoder", "GrayDecoder",
-]
-
-
-class Encoder(Elaboratable):
- """Encode one-hot to binary.
-
- If one bit in ``i`` is asserted, ``n`` is low and ``o`` indicates the asserted bit.
- Otherwise, ``n`` is high and ``o`` is ``0``.
-
- Parameters
- ----------
- width : int
- Bit width of the input
-
- Attributes
- ----------
- i : Signal(width), in
- One-hot input.
- o : Signal(range(width)), out
- Encoded natural binary.
- n : Signal, out
- Invalid: either none or multiple input bits are asserted.
- """
- def __init__(self, width):
- self.width = width
-
- self.i = Signal(width)
- self.o = Signal(range(width))
- self.n = Signal()
-
- def elaborate(self, platform):
- m = Module()
- with m.Switch(self.i):
- for j in range(self.width):
- with m.Case(1 << j):
- m.d.comb += self.o.eq(j)
- with m.Default():
- m.d.comb += self.n.eq(1)
- return m
-
-
-class PriorityEncoder(Elaboratable):
- """Priority encode requests to binary.
-
- If any bit in ``i`` is asserted, ``n`` is low and ``o`` indicates the least significant
- asserted bit.
- Otherwise, ``n`` is high and ``o`` is ``0``.
-
- Parameters
- ----------
- width : int
- Bit width of the input.
-
- Attributes
- ----------
- i : Signal(width), in
- Input requests.
- o : Signal(range(width)), out
- Encoded natural binary.
- n : Signal, out
- Invalid: no input bits are asserted.
- """
- def __init__(self, width):
- self.width = width
-
- self.i = Signal(width)
- self.o = Signal(range(width))
- self.n = Signal()
-
- def elaborate(self, platform):
- m = Module()
- for j in reversed(range(self.width)):
- with m.If(self.i[j]):
- m.d.comb += self.o.eq(j)
- m.d.comb += self.n.eq(self.i == 0)
- return m
-
-
-class Decoder(Elaboratable):
- """Decode binary to one-hot.
-
- If ``n`` is low, only the ``i``-th bit in ``o`` is asserted.
- If ``n`` is high, ``o`` is ``0``.
-
- Parameters
- ----------
- width : int
- Bit width of the output.
-
- Attributes
- ----------
- i : Signal(range(width)), in
- Input binary.
- o : Signal(width), out
- Decoded one-hot.
- n : Signal, in
- Invalid, no output bits are to be asserted.
- """
- def __init__(self, width):
- self.width = width
-
- self.i = Signal(range(width))
- self.n = Signal()
- self.o = Signal(width)
-
- def elaborate(self, platform):
- m = Module()
- with m.Switch(self.i):
- for j in range(len(self.o)):
- with m.Case(j):
- m.d.comb += self.o.eq(1 << j)
- with m.If(self.n):
- m.d.comb += self.o.eq(0)
- return m
-
-
-class PriorityDecoder(Decoder):
- """Decode binary to priority request.
-
- Identical to :class:`Decoder`.
- """
-
-
-class GrayEncoder(Elaboratable):
- """Encode binary to Gray code.
-
- Parameters
- ----------
- width : int
- Bit width.
-
- Attributes
- ----------
- i : Signal(width), in
- Natural binary input.
- o : Signal(width), out
- Encoded Gray code.
- """
- def __init__(self, width):
- self.width = width
-
- self.i = Signal(width)
- self.o = Signal(width)
-
- def elaborate(self, platform):
- m = Module()
- m.d.comb += self.o.eq(self.i ^ self.i[1:])
- return m
-
-
-class GrayDecoder(Elaboratable):
- """Decode Gray code to binary.
-
- Parameters
- ----------
- width : int
- Bit width.
-
- Attributes
- ----------
- i : Signal(width), in
- Gray code input.
- o : Signal(width), out
- Decoded natural binary.
- """
- def __init__(self, width):
- self.width = width
-
- self.i = Signal(width)
- self.o = Signal(width)
-
- def elaborate(self, platform):
- m = Module()
- rhs = Const(0)
- for i in reversed(range(self.width)):
- rhs = rhs ^ self.i[i]
- m.d.comb += self.o[i].eq(rhs)
- return m
diff --git a/docs/changes.rst b/docs/changes.rst
index 028091636..8f2d47859 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -9,6 +9,7 @@ Documentation for past releases
Documentation for past releases of the Amaranth language and toolchain is available online:
+* `Amaranth 0.5.0 `_
* `Amaranth 0.4.5 `_
* `Amaranth 0.4.4 `_
* `Amaranth 0.4.3 `_
@@ -18,6 +19,18 @@ Documentation for past releases of the Amaranth language and toolchain is availa
* `Amaranth 0.3 `_
+Version 0.6 (unreleased)
+========================
+
+
+Standard library changes
+------------------------
+
+.. currentmodule:: amaranth.lib
+
+* Removed: (deprecated in 0.5) :mod:`amaranth.lib.coding`. (`RFC 63`_)
+
+
Version 0.5
===========
diff --git a/docs/stdlib.rst b/docs/stdlib.rst
index 01e203459..78e97b0ff 100644
--- a/docs/stdlib.rst
+++ b/docs/stdlib.rst
@@ -5,7 +5,7 @@ The :mod:`amaranth.lib` module, also known as the standard library, provides mod
1. Modules that will used by essentially all idiomatic Amaranth code, or which are necessary for interoperability. This includes :mod:`amaranth.lib.enum` (enumerations), :mod:`amaranth.lib.data` (data structures), :mod:`amaranth.lib.wiring` (interfaces and components), :mod:`amaranth.lib.meta` (interface metadata), and :mod:`amaranth.lib.stream` (data streams).
2. Modules that abstract common functionality whose implementation differs between hardware platforms. This includes :mod:`amaranth.lib.memory` and :mod:`amaranth.lib.cdc`.
-3. Modules that have essentially one correct implementation and are of broad utility in digital designs. This includes :mod:`amaranth.lib.coding`, :mod:`amaranth.lib.fifo`, and :mod:`amaranth.lib.crc`.
+3. Modules that have essentially one correct implementation and are of broad utility in digital designs. This includes :mod:`amaranth.lib.fifo`, and :mod:`amaranth.lib.crc`.
As part of the Amaranth backwards compatibility guarantee, any behaviors described in these documents will not change from a version to another without at least one version including a warning about the impending change. Any nontrivial change to these behaviors must also go through the public review as a part of the `Amaranth Request for Comments process `_.
@@ -22,6 +22,5 @@ The Amaranth standard library is separate from the Amaranth language: everything
stdlib/memory
stdlib/io
stdlib/cdc
- stdlib/coding
stdlib/fifo
stdlib/crc
diff --git a/docs/stdlib/coding.rst b/docs/stdlib/coding.rst
deleted file mode 100644
index c112c0672..000000000
--- a/docs/stdlib/coding.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-Code conversion
-###############
-
-.. py:module:: amaranth.lib.coding
-
-The :mod:`amaranth.lib.coding` module provides building blocks for conversion between different encodings of binary numbers.
-
-
-One-hot coding
-==============
-
-.. autoclass:: Encoder()
-.. autoclass:: Decoder()
-
-
-Priority coding
-===============
-
-.. autoclass:: PriorityEncoder()
-.. autoclass:: PriorityDecoder()
-
-
-Gray coding
-===========
-
-.. autoclass:: GrayEncoder()
-.. autoclass:: GrayDecoder()
diff --git a/tests/test_lib_coding.py b/tests/test_lib_coding.py
deleted file mode 100644
index fcdcd7ae0..000000000
--- a/tests/test_lib_coding.py
+++ /dev/null
@@ -1,128 +0,0 @@
-import warnings
-
-from amaranth.hdl import *
-from amaranth.sim import *
-with warnings.catch_warnings():
- warnings.filterwarnings(action="ignore", category=DeprecationWarning)
- from amaranth.lib.coding import *
-
-from .utils import *
-
-
-class EncoderTestCase(FHDLTestCase):
- def test_basic(self):
- enc = Encoder(4)
- async def testbench(ctx):
- self.assertEqual(ctx.get(enc.n), 1)
- self.assertEqual(ctx.get(enc.o), 0)
-
- ctx.set(enc.i, 0b0001)
- self.assertEqual(ctx.get(enc.n), 0)
- self.assertEqual(ctx.get(enc.o), 0)
-
- ctx.set(enc.i, 0b0100)
- self.assertEqual(ctx.get(enc.n), 0)
- self.assertEqual(ctx.get(enc.o), 2)
-
- ctx.set(enc.i, 0b0110)
- self.assertEqual(ctx.get(enc.n), 1)
- self.assertEqual(ctx.get(enc.o), 0)
-
- sim = Simulator(enc)
- sim.add_testbench(testbench)
- sim.run()
-
-
-class PriorityEncoderTestCase(FHDLTestCase):
- def test_basic(self):
- enc = PriorityEncoder(4)
- async def testbench(ctx):
- self.assertEqual(ctx.get(enc.n), 1)
- self.assertEqual(ctx.get(enc.o), 0)
-
- ctx.set(enc.i, 0b0001)
- self.assertEqual(ctx.get(enc.n), 0)
- self.assertEqual(ctx.get(enc.o), 0)
-
- ctx.set(enc.i, 0b0100)
- self.assertEqual(ctx.get(enc.n), 0)
- self.assertEqual(ctx.get(enc.o), 2)
-
- ctx.set(enc.i, 0b0110)
- self.assertEqual(ctx.get(enc.n), 0)
- self.assertEqual(ctx.get(enc.o), 1)
-
- sim = Simulator(enc)
- sim.add_testbench(testbench)
- sim.run()
-
-
-class DecoderTestCase(FHDLTestCase):
- def test_basic(self):
- dec = Decoder(4)
- async def testbench(ctx):
- self.assertEqual(ctx.get(dec.o), 0b0001)
-
- ctx.set(dec.i, 1)
- self.assertEqual(ctx.get(dec.o), 0b0010)
-
- ctx.set(dec.i, 3)
- self.assertEqual(ctx.get(dec.o), 0b1000)
-
- ctx.set(dec.n, 1)
- self.assertEqual(ctx.get(dec.o), 0b0000)
-
- sim = Simulator(dec)
- sim.add_testbench(testbench)
- sim.run()
-
-
-class ReversibleSpec(Elaboratable):
- def __init__(self, encoder_cls, decoder_cls, i_width, args):
- self.encoder_cls = encoder_cls
- self.decoder_cls = decoder_cls
- self.coder_args = args
- self.i = Signal(i_width)
-
- def elaborate(self, platform):
- m = Module()
- enc, dec = self.encoder_cls(*self.coder_args), self.decoder_cls(*self.coder_args)
- m.submodules += enc, dec
- m.d.comb += [
- enc.i.eq(self.i),
- dec.i.eq(enc.o),
- Assert(enc.i == dec.o)
- ]
- return m
-
-
-class HammingDistanceSpec(Elaboratable):
- def __init__(self, distance, encoder_cls, i_width, args):
- self.distance = distance
- self.encoder_cls = encoder_cls
- self.coder_args = args
- self.i1 = Signal(i_width)
- self.i2 = Signal(i_width)
-
- def elaborate(self, platform):
- m = Module()
- enc1, enc2 = self.encoder_cls(*self.coder_args), self.encoder_cls(*self.coder_args)
- m.submodules += enc1, enc2
- m.d.comb += [
- enc1.i.eq(self.i1),
- enc2.i.eq(self.i2),
- Assume(enc1.i + 1 == enc2.i),
- Assert(sum(enc1.o ^ enc2.o) == self.distance)
- ]
- return m
-
-
-class GrayCoderTestCase(FHDLTestCase):
- def test_reversible(self):
- spec = ReversibleSpec(encoder_cls=GrayEncoder, decoder_cls=GrayDecoder, i_width=16,
- args=(16,))
- self.assertFormal(spec, [spec.i], mode="prove")
-
- def test_distance(self):
- spec = HammingDistanceSpec(distance=1, encoder_cls=GrayEncoder, i_width=16, args=(16,))
- self.assertFormal(spec, [spec.i1, spec.i2], mode="prove")