From 49dee891e870fa350ed95a042b0360540ba8c04e Mon Sep 17 00:00:00 2001 From: Wanda Date: Wed, 13 Mar 2024 18:54:42 +0100 Subject: [PATCH] tests: Exorcise some star-imports. --- tests/test_lib_data.py | 377 +++++++++++++++++++-------------------- tests/test_lib_memory.py | 187 ++++++++++--------- 2 files changed, 281 insertions(+), 283 deletions(-) diff --git a/tests/test_lib_data.py b/tests/test_lib_data.py index cfe4cec..071692e 100644 --- a/tests/test_lib_data.py +++ b/tests/test_lib_data.py @@ -3,8 +3,7 @@ import operator from unittest import TestCase from amaranth.hdl import * -from amaranth.hdl._ast import ShapeCastable -from amaranth.lib.data import * +from amaranth.lib import data from amaranth.sim import Simulator from .utils import * @@ -26,56 +25,56 @@ class MockShapeCastable(ShapeCastable): class FieldTestCase(TestCase): def test_construct(self): - f = Field(unsigned(2), 1) + f = data.Field(unsigned(2), 1) self.assertEqual(f.shape, unsigned(2)) self.assertEqual(f.offset, 1) self.assertEqual(f.width, 2) def test_repr(self): - f = Field(unsigned(2), 1) + f = data.Field(unsigned(2), 1) self.assertEqual(repr(f), "Field(unsigned(2), 1)") def test_equal(self): - f1 = Field(unsigned(2), 1) - f2 = Field(unsigned(2), 0) + f1 = data.Field(unsigned(2), 1) + f2 = data.Field(unsigned(2), 0) self.assertNotEqual(f1, f2) - f3 = Field(unsigned(2), 1) + f3 = data.Field(unsigned(2), 1) self.assertEqual(f1, f3) - f4 = Field(2, 1) + f4 = data.Field(2, 1) self.assertEqual(f1, f4) - f5 = Field(MockShapeCastable(unsigned(2)), 1) + f5 = data.Field(MockShapeCastable(unsigned(2)), 1) self.assertEqual(f1, f5) self.assertNotEqual(f1, object()) def test_preserve_shape(self): sc = MockShapeCastable(unsigned(2)) - f = Field(sc, 0) + f = data.Field(sc, 0) self.assertEqual(f.shape, sc) self.assertEqual(f.width, 2) def test_shape_wrong(self): with self.assertRaisesRegex(TypeError, r"^Field shape must be a shape-castable object, not <.+>$"): - Field(object(), 0) + data.Field(object(), 0) def test_offset_wrong(self): with self.assertRaisesRegex(TypeError, r"^Field offset must be a non-negative integer, not <.+>$"): - Field(unsigned(2), object()) + data.Field(unsigned(2), object()) with self.assertRaisesRegex(TypeError, r"^Field offset must be a non-negative integer, not -1$"): - Field(unsigned(2), -1) + data.Field(unsigned(2), -1) def test_immutable(self): with self.assertRaises(AttributeError): - Field(1, 0).shape = unsigned(2) + data.Field(1, 0).shape = unsigned(2) with self.assertRaises(AttributeError): - Field(1, 0).offset = 1 + data.Field(1, 0).offset = 1 class StructLayoutTestCase(TestCase): def test_construct(self): - sl = StructLayout({ + sl = data.StructLayout({ "a": unsigned(1), "b": 2 }) @@ -85,25 +84,25 @@ class StructLayoutTestCase(TestCase): }) self.assertEqual(sl.size, 3) self.assertEqual(list(iter(sl)), [ - ("a", Field(unsigned(1), 0)), - ("b", Field(2, 1)) + ("a", data.Field(unsigned(1), 0)), + ("b", data.Field(2, 1)) ]) - self.assertEqual(sl["a"], Field(unsigned(1), 0)) - self.assertEqual(sl["b"], Field(2, 1)) + self.assertEqual(sl["a"], data.Field(unsigned(1), 0)) + self.assertEqual(sl["b"], data.Field(2, 1)) def test_size_empty(self): - self.assertEqual(StructLayout({}).size, 0) + self.assertEqual(data.StructLayout({}).size, 0) def test_eq(self): - self.assertEqual(StructLayout({"a": unsigned(1), "b": 2}), - StructLayout({"a": unsigned(1), "b": unsigned(2)})) - self.assertNotEqual(StructLayout({"a": unsigned(1), "b": 2}), - StructLayout({"b": unsigned(2), "a": unsigned(1)})) - self.assertNotEqual(StructLayout({"a": unsigned(1), "b": 2}), - StructLayout({"a": unsigned(1)})) + self.assertEqual(data.StructLayout({"a": unsigned(1), "b": 2}), + data.StructLayout({"a": unsigned(1), "b": unsigned(2)})) + self.assertNotEqual(data.StructLayout({"a": unsigned(1), "b": 2}), + data.StructLayout({"b": unsigned(2), "a": unsigned(1)})) + self.assertNotEqual(data.StructLayout({"a": unsigned(1), "b": 2}), + data.StructLayout({"a": unsigned(1)})) def test_repr(self): - sl = StructLayout({ + sl = data.StructLayout({ "a": unsigned(1), "b": 2 }) @@ -112,22 +111,22 @@ class StructLayoutTestCase(TestCase): def test_members_wrong(self): with self.assertRaisesRegex(TypeError, r"^Struct layout members must be provided as a mapping, not <.+>$"): - StructLayout(object()) + data.StructLayout(object()) def test_member_key_wrong(self): with self.assertRaisesRegex(TypeError, r"^Struct layout member name must be a string, not 1\.0$"): - StructLayout({1.0: unsigned(1)}) + data.StructLayout({1.0: unsigned(1)}) def test_member_value_wrong(self): with self.assertRaisesRegex(TypeError, r"^Struct layout member shape must be a shape-castable object, not 1\.0$"): - StructLayout({"a": 1.0}) + data.StructLayout({"a": 1.0}) class UnionLayoutTestCase(TestCase): def test_construct(self): - ul = UnionLayout({ + ul = data.UnionLayout({ "a": unsigned(1), "b": 2 }) @@ -137,25 +136,25 @@ class UnionLayoutTestCase(TestCase): }) self.assertEqual(ul.size, 2) self.assertEqual(list(iter(ul)), [ - ("a", Field(unsigned(1), 0)), - ("b", Field(2, 0)) + ("a", data.Field(unsigned(1), 0)), + ("b", data.Field(2, 0)) ]) - self.assertEqual(ul["a"], Field(unsigned(1), 0)) - self.assertEqual(ul["b"], Field(2, 0)) + self.assertEqual(ul["a"], data.Field(unsigned(1), 0)) + self.assertEqual(ul["b"], data.Field(2, 0)) def test_size_empty(self): - self.assertEqual(UnionLayout({}).size, 0) + self.assertEqual(data.UnionLayout({}).size, 0) def test_eq(self): - self.assertEqual(UnionLayout({"a": unsigned(1), "b": 2}), - UnionLayout({"a": unsigned(1), "b": unsigned(2)})) - self.assertEqual(UnionLayout({"a": unsigned(1), "b": 2}), - UnionLayout({"b": unsigned(2), "a": unsigned(1)})) - self.assertNotEqual(UnionLayout({"a": unsigned(1), "b": 2}), - UnionLayout({"a": unsigned(1)})) + self.assertEqual(data.UnionLayout({"a": unsigned(1), "b": 2}), + data.UnionLayout({"a": unsigned(1), "b": unsigned(2)})) + self.assertEqual(data.UnionLayout({"a": unsigned(1), "b": 2}), + data.UnionLayout({"b": unsigned(2), "a": unsigned(1)})) + self.assertNotEqual(data.UnionLayout({"a": unsigned(1), "b": 2}), + data.UnionLayout({"a": unsigned(1)})) def test_repr(self): - ul = UnionLayout({ + ul = data.UnionLayout({ "a": unsigned(1), "b": 2 }) @@ -164,79 +163,79 @@ class UnionLayoutTestCase(TestCase): def test_members_wrong(self): with self.assertRaisesRegex(TypeError, r"^Union layout members must be provided as a mapping, not <.+>$"): - UnionLayout(object()) + data.UnionLayout(object()) def test_member_key_wrong(self): with self.assertRaisesRegex(TypeError, r"^Union layout member name must be a string, not 1\.0$"): - UnionLayout({1.0: unsigned(1)}) + data.UnionLayout({1.0: unsigned(1)}) def test_member_value_wrong(self): with self.assertRaisesRegex(TypeError, r"^Union layout member shape must be a shape-castable object, not 1\.0$"): - UnionLayout({"a": 1.0}) + data.UnionLayout({"a": 1.0}) def test_const_two_members_wrong(self): with self.assertRaisesRegex(ValueError, r"^Initializer for at most one field can be provided for a union layout " r"\(specified: a, b\)$"): - UnionLayout({"a": 1, "b": 2}).const(dict(a=1, b=2)) + data.UnionLayout({"a": 1, "b": 2}).const(dict(a=1, b=2)) class ArrayLayoutTestCase(TestCase): def test_construct(self): - al = ArrayLayout(unsigned(2), 3) + al = data.ArrayLayout(unsigned(2), 3) self.assertEqual(al.elem_shape, unsigned(2)) self.assertEqual(al.length, 3) self.assertEqual(list(iter(al)), [ - (0, Field(unsigned(2), 0)), - (1, Field(unsigned(2), 2)), - (2, Field(unsigned(2), 4)), + (0, data.Field(unsigned(2), 0)), + (1, data.Field(unsigned(2), 2)), + (2, data.Field(unsigned(2), 4)), ]) - self.assertEqual(al[0], Field(unsigned(2), 0)) - self.assertEqual(al[1], Field(unsigned(2), 2)) - self.assertEqual(al[2], Field(unsigned(2), 4)) - self.assertEqual(al[-1], Field(unsigned(2), 4)) - self.assertEqual(al[-2], Field(unsigned(2), 2)) - self.assertEqual(al[-3], Field(unsigned(2), 0)) + self.assertEqual(al[0], data.Field(unsigned(2), 0)) + self.assertEqual(al[1], data.Field(unsigned(2), 2)) + self.assertEqual(al[2], data.Field(unsigned(2), 4)) + self.assertEqual(al[-1], data.Field(unsigned(2), 4)) + self.assertEqual(al[-2], data.Field(unsigned(2), 2)) + self.assertEqual(al[-3], data.Field(unsigned(2), 0)) self.assertEqual(al.size, 6) def test_shape_castable(self): - al = ArrayLayout(2, 3) + al = data.ArrayLayout(2, 3) self.assertEqual(al.size, 6) def test_eq(self): - self.assertEqual(ArrayLayout(unsigned(2), 3), - ArrayLayout(unsigned(2), 3)) - self.assertNotEqual(ArrayLayout(unsigned(2), 3), - ArrayLayout(unsigned(2), 4)) + self.assertEqual(data.ArrayLayout(unsigned(2), 3), + data.ArrayLayout(unsigned(2), 3)) + self.assertNotEqual(data.ArrayLayout(unsigned(2), 3), + data.ArrayLayout(unsigned(2), 4)) def test_repr(self): - al = ArrayLayout(unsigned(2), 3) + al = data.ArrayLayout(unsigned(2), 3) self.assertEqual(repr(al), "ArrayLayout(unsigned(2), 3)") def test_elem_shape_wrong(self): with self.assertRaisesRegex(TypeError, r"^Array layout element shape must be a shape-castable object, not <.+>$"): - ArrayLayout(object(), 1) + data.ArrayLayout(object(), 1) def test_length_wrong(self): with self.assertRaisesRegex(TypeError, r"^Array layout length must be a non-negative integer, not <.+>$"): - ArrayLayout(unsigned(1), object()) + data.ArrayLayout(unsigned(1), object()) with self.assertRaisesRegex(TypeError, r"^Array layout length must be a non-negative integer, not -1$"): - ArrayLayout(unsigned(1), -1) + data.ArrayLayout(unsigned(1), -1) def test_key_wrong_bounds(self): - al = ArrayLayout(unsigned(2), 3) + al = data.ArrayLayout(unsigned(2), 3) with self.assertRaisesRegex(KeyError, r"^4$"): al[4] with self.assertRaisesRegex(KeyError, r"^-4$"): al[-4] def test_key_wrong_type(self): - al = ArrayLayout(unsigned(2), 3) + al = data.ArrayLayout(unsigned(2), 3) with self.assertRaisesRegex(TypeError, r"^Cannot index array layout with 'a'$"): al["a"] @@ -244,54 +243,54 @@ class ArrayLayoutTestCase(TestCase): class FlexibleLayoutTestCase(TestCase): def test_construct(self): - il = FlexibleLayout(8, { - "a": Field(unsigned(1), 1), - "b": Field(unsigned(3), 0), - 0: Field(unsigned(2), 5) + il = data.FlexibleLayout(8, { + "a": data.Field(unsigned(1), 1), + "b": data.Field(unsigned(3), 0), + 0: data.Field(unsigned(2), 5) }) self.assertEqual(il.size, 8) self.assertEqual(il.fields, { - "a": Field(unsigned(1), 1), - "b": Field(unsigned(3), 0), - 0: Field(unsigned(2), 5) + "a": data.Field(unsigned(1), 1), + "b": data.Field(unsigned(3), 0), + 0: data.Field(unsigned(2), 5) }) self.assertEqual(list(iter(il)), [ - ("a", Field(unsigned(1), 1)), - ("b", Field(unsigned(3), 0)), - (0, Field(unsigned(2), 5)) + ("a", data.Field(unsigned(1), 1)), + ("b", data.Field(unsigned(3), 0)), + (0, data.Field(unsigned(2), 5)) ]) - self.assertEqual(il["a"], Field(unsigned(1), 1)) - self.assertEqual(il["b"], Field(unsigned(3), 0)) - self.assertEqual(il[0], Field(unsigned(2), 5)) + self.assertEqual(il["a"], data.Field(unsigned(1), 1)) + self.assertEqual(il["b"], data.Field(unsigned(3), 0)) + self.assertEqual(il[0], data.Field(unsigned(2), 5)) def test_is_not_mutated(self): - il = FlexibleLayout(8, {"a": Field(unsigned(1), 0)}) + il = data.FlexibleLayout(8, {"a": data.Field(unsigned(1), 0)}) del il.fields["a"] self.assertIn("a", il.fields) def test_eq(self): - self.assertEqual(FlexibleLayout(3, {"a": Field(unsigned(1), 0)}), - FlexibleLayout(3, {"a": Field(unsigned(1), 0)})) - self.assertNotEqual(FlexibleLayout(3, {"a": Field(unsigned(1), 0)}), - FlexibleLayout(4, {"a": Field(unsigned(1), 0)})) - self.assertNotEqual(FlexibleLayout(3, {"a": Field(unsigned(1), 0)}), - FlexibleLayout(3, {"a": Field(unsigned(1), 1)})) + self.assertEqual(data.FlexibleLayout(3, {"a": data.Field(unsigned(1), 0)}), + data.FlexibleLayout(3, {"a": data.Field(unsigned(1), 0)})) + self.assertNotEqual(data.FlexibleLayout(3, {"a": data.Field(unsigned(1), 0)}), + data.FlexibleLayout(4, {"a": data.Field(unsigned(1), 0)})) + self.assertNotEqual(data.FlexibleLayout(3, {"a": data.Field(unsigned(1), 0)}), + data.FlexibleLayout(3, {"a": data.Field(unsigned(1), 1)})) def test_eq_duck(self): - self.assertEqual(FlexibleLayout(3, {"a": Field(unsigned(1), 0), - "b": Field(unsigned(2), 1)}), - StructLayout({"a": unsigned(1), + self.assertEqual(data.FlexibleLayout(3, {"a": data.Field(unsigned(1), 0), + "b": data.Field(unsigned(2), 1)}), + data.StructLayout({"a": unsigned(1), "b": unsigned(2)})) - self.assertEqual(FlexibleLayout(2, {"a": Field(unsigned(1), 0), - "b": Field(unsigned(2), 0)}), - UnionLayout({"a": unsigned(1), + self.assertEqual(data.FlexibleLayout(2, {"a": data.Field(unsigned(1), 0), + "b": data.Field(unsigned(2), 0)}), + data.UnionLayout({"a": unsigned(1), "b": unsigned(2)})) def test_repr(self): - il = FlexibleLayout(8, { - "a": Field(unsigned(1), 1), - "b": Field(unsigned(3), 0), - 0: Field(unsigned(2), 5) + il = data.FlexibleLayout(8, { + "a": data.Field(unsigned(1), 1), + "b": data.Field(unsigned(3), 0), + 0: data.Field(unsigned(2), 5) }) self.assertEqual(repr(il), "FlexibleLayout(8, {" "'a': Field(unsigned(1), 1), " @@ -301,44 +300,44 @@ class FlexibleLayoutTestCase(TestCase): def test_fields_wrong(self): with self.assertRaisesRegex(TypeError, r"^Flexible layout fields must be provided as a mapping, not <.+>$"): - FlexibleLayout(8, object()) + data.FlexibleLayout(8, object()) def test_field_key_wrong(self): with self.assertRaisesRegex(TypeError, r"^Flexible layout field name must be a non-negative integer or a string, " r"not 1\.0$"): - FlexibleLayout(8, {1.0: unsigned(1)}) + data.FlexibleLayout(8, {1.0: unsigned(1)}) with self.assertRaisesRegex(TypeError, r"^Flexible layout field name must be a non-negative integer or a string, " r"not -1$"): - FlexibleLayout(8, {-1: unsigned(1)}) + data.FlexibleLayout(8, {-1: unsigned(1)}) def test_field_value_wrong(self): with self.assertRaisesRegex(TypeError, r"^Flexible layout field value must be a Field instance, not 1\.0$"): - FlexibleLayout(8, {"a": 1.0}) + data.FlexibleLayout(8, {"a": 1.0}) def test_size_wrong_negative(self): with self.assertRaisesRegex(TypeError, r"^Flexible layout size must be a non-negative integer, not -1$"): - FlexibleLayout(-1, {}) + data.FlexibleLayout(-1, {}) def test_size_wrong_small(self): with self.assertRaisesRegex(ValueError, r"^Flexible layout field 'a' ends at bit 8, exceeding the size of 4 bit\(s\)$"): - FlexibleLayout(4, {"a": Field(unsigned(8), 0)}) + data.FlexibleLayout(4, {"a": data.Field(unsigned(8), 0)}) with self.assertRaisesRegex(ValueError, r"^Flexible layout field 'a' ends at bit 5, exceeding the size of 4 bit\(s\)$"): - FlexibleLayout(4, {"a": Field(unsigned(2), 3)}) + data.FlexibleLayout(4, {"a": data.Field(unsigned(2), 3)}) def test_key_wrong_missing(self): - il = FlexibleLayout(8, {"a": Field(unsigned(2), 3)}) + il = data.FlexibleLayout(8, {"a": data.Field(unsigned(2), 3)}) with self.assertRaisesRegex(KeyError, r"^0$"): il[0] def test_key_wrong_type(self): - il = FlexibleLayout(8, {"a": Field(unsigned(2), 3)}) + il = data.FlexibleLayout(8, {"a": data.Field(unsigned(2), 3)}) with self.assertRaisesRegex(TypeError, r"^Cannot index flexible layout with <.+>$"): il[object()] @@ -346,62 +345,62 @@ class FlexibleLayoutTestCase(TestCase): class LayoutTestCase(FHDLTestCase): def test_cast(self): - sl = StructLayout({}) - self.assertIs(Layout.cast(sl), sl) + sl = data.StructLayout({}) + self.assertIs(data.Layout.cast(sl), sl) def test_cast_wrong_not_layout(self): with self.assertRaisesRegex(TypeError, r"^Object unsigned\(1\) cannot be converted to a data layout$"): - Layout.cast(unsigned(1)) + data.Layout.cast(unsigned(1)) def test_cast_wrong_type(self): with self.assertRaisesRegex(TypeError, r"^Object <.+> cannot be converted to an Amaranth shape$"): - Layout.cast(object()) + data.Layout.cast(object()) def test_cast_wrong_recur(self): sc = MockShapeCastable(None) sc.shape = sc with self.assertRaisesRegex(RecursionError, r"^Shape-castable object <.+> casts to itself$"): - Layout.cast(sc) + data.Layout.cast(sc) def test_eq_wrong_recur(self): sc = MockShapeCastable(None) sc.shape = sc - self.assertNotEqual(StructLayout({}), sc) + self.assertNotEqual(data.StructLayout({}), sc) def test_call(self): - sl = StructLayout({"f": unsigned(1)}) + sl = data.StructLayout({"f": unsigned(1)}) s = Signal(1) v = sl(s) self.assertIs(v.shape(), sl) self.assertIs(v.as_value(), s) def test_const(self): - sl = StructLayout({ + sl = data.StructLayout({ "a": unsigned(1), "b": unsigned(2) }) self.assertRepr(sl.const(None).as_value(), "(const 3'd0)") self.assertRepr(sl.const({"a": 0b1, "b": 0b10}).as_value(), "(const 3'd5)") - fl = FlexibleLayout(2, { - "a": Field(unsigned(1), 0), - "b": Field(unsigned(2), 0) + fl = data.FlexibleLayout(2, { + "a": data.Field(unsigned(1), 0), + "b": data.Field(unsigned(2), 0) }) self.assertRepr(fl.const({"a": 0b11}).as_value(), "(const 2'd1)") self.assertRepr(fl.const({"b": 0b10}).as_value(), "(const 2'd2)") self.assertRepr(fl.const({"a": 0b1, "b": 0b10}).as_value(), "(const 2'd2)") - sls = StructLayout({ + sls = data.StructLayout({ "a": signed(4), "b": signed(4) }) self.assertRepr(sls.const({"b": 0, "a": -1}).as_value(), "(const 8'd15)") def test_const_wrong(self): - sl = StructLayout({"f": unsigned(1)}) + sl = data.StructLayout({"f": unsigned(1)}) with self.assertRaisesRegex(TypeError, r"^Layout constant initializer must be a mapping or a sequence, not " r"<.+?object.+?>$"): @@ -418,7 +417,7 @@ class LayoutTestCase(FHDLTestCase): def const(self, init): return int(init, 16) - sl = StructLayout({"f": CastableFromHex()}) + sl = data.StructLayout({"f": CastableFromHex()}) self.assertRepr(sl.const({"f": "aa"}).as_value(), "(const 8'd170)") with self.assertRaisesRegex(ValueError, @@ -427,11 +426,11 @@ class LayoutTestCase(FHDLTestCase): sl.const({"f": "01"}) def test_const_field_const(self): - sl = StructLayout({"f": unsigned(1)}) + sl = data.StructLayout({"f": unsigned(1)}) self.assertRepr(sl.const({"f": Const(1)}).as_value(), "(const 1'd1)") def test_signal_init(self): - sl = StructLayout({ + sl = data.StructLayout({ "a": unsigned(1), "b": unsigned(2) }) @@ -442,73 +441,73 @@ class LayoutTestCase(FHDLTestCase): class ViewTestCase(FHDLTestCase): def test_construct(self): s = Signal(3) - v = View(StructLayout({"a": unsigned(1), "b": unsigned(2)}), s) + v = data.View(data.StructLayout({"a": unsigned(1), "b": unsigned(2)}), s) self.assertIs(Value.cast(v), s) self.assertRepr(v["a"], "(slice (sig s) 0:1)") self.assertRepr(v["b"], "(slice (sig s) 1:3)") def test_construct_signal(self): - v = Signal(StructLayout({"a": unsigned(1), "b": unsigned(2)})) + v = Signal(data.StructLayout({"a": unsigned(1), "b": unsigned(2)})) cv = Value.cast(v) self.assertIsInstance(cv, Signal) self.assertEqual(cv.shape(), unsigned(3)) self.assertEqual(cv.name, "v") def test_construct_signal_init(self): - v1 = Signal(StructLayout({"a": unsigned(1), "b": unsigned(2)}), + v1 = Signal(data.StructLayout({"a": unsigned(1), "b": unsigned(2)}), init={"a": 0b1, "b": 0b10}) self.assertEqual(Value.cast(v1).init, 0b101) - v2 = Signal(StructLayout({"a": unsigned(1), - "b": StructLayout({"x": unsigned(1), "y": unsigned(1)})}), + v2 = Signal(data.StructLayout({"a": unsigned(1), + "b": data.StructLayout({"x": unsigned(1), "y": unsigned(1)})}), init={"a": 0b1, "b": {"x": 0b0, "y": 0b1}}) self.assertEqual(Value.cast(v2).init, 0b101) - v3 = Signal(ArrayLayout(unsigned(2), 2), + v3 = Signal(data.ArrayLayout(unsigned(2), 2), init=[0b01, 0b10]) self.assertEqual(Value.cast(v3).init, 0b1001) def test_layout_wrong(self): with self.assertRaisesRegex(TypeError, r"^View layout must be a layout, not <.+?>$"): - View(object(), Signal(1)) + data.View(object(), Signal(1)) def test_layout_conflict_with_attr(self): with self.assertWarnsRegex(SyntaxWarning, r"^View layout includes a field 'as_value' that will be shadowed by the view " r"attribute 'amaranth\.lib\.data\.View\.as_value'$"): - View(StructLayout({"as_value": unsigned(1)}), Signal(1)) + data.View(data.StructLayout({"as_value": unsigned(1)}), Signal(1)) def test_layout_conflict_with_attr_derived(self): - class DerivedView(View): + class DerivedView(data.View): def foo(self): pass with self.assertWarnsRegex(SyntaxWarning, r"^View layout includes a field 'foo' that will be shadowed by the view " r"attribute 'tests\.test_lib_data\.ViewTestCase\." r"test_layout_conflict_with_attr_derived\..DerivedView\.foo'$"): - DerivedView(StructLayout({"foo": unsigned(1)}), Signal(1)) + DerivedView(data.StructLayout({"foo": unsigned(1)}), Signal(1)) def test_target_wrong_type(self): with self.assertRaisesRegex(TypeError, r"^View target must be a value-castable object, not <.+?>$"): - View(StructLayout({}), object()) + data.View(data.StructLayout({}), object()) def test_target_wrong_size(self): with self.assertRaisesRegex(ValueError, r"^View target is 2 bit\(s\) wide, which is not compatible with the 1 bit\(s\) " r"wide view layout$"): - View(StructLayout({"a": unsigned(1)}), Signal(2)) + data.View(data.StructLayout({"a": unsigned(1)}), Signal(2)) def test_getitem(self): - v = Signal(UnionLayout({ + v = Signal(data.UnionLayout({ "a": unsigned(2), - "s": StructLayout({ + "s": data.StructLayout({ "b": unsigned(1), "c": unsigned(3) }), "p": 1, "q": signed(1), - "r": ArrayLayout(unsigned(2), 2), - "t": ArrayLayout(StructLayout({ + "r": data.ArrayLayout(unsigned(2), 2), + "t": data.ArrayLayout(data.StructLayout({ "u": unsigned(1), "v": unsigned(1) }), 2), @@ -541,7 +540,7 @@ class ViewTestCase(FHDLTestCase): def const(self, init): return Const(init, 2) - v = Signal(StructLayout({ + v = Signal(data.StructLayout({ "f": Reverser() })) self.assertRepr(v.f, "(cat (slice (slice (sig v) 0:2) 1:2) " @@ -558,7 +557,7 @@ class ViewTestCase(FHDLTestCase): def const(self, init): return Const(init, 2) - v = Signal(StructLayout({ + v = Signal(data.StructLayout({ "f": WrongCastable() })) with self.assertRaisesRegex(TypeError, @@ -569,18 +568,18 @@ class ViewTestCase(FHDLTestCase): def test_index_wrong_missing(self): with self.assertRaisesRegex(KeyError, r"^'a'$"): - Signal(StructLayout({}))["a"] + Signal(data.StructLayout({}))["a"] def test_index_wrong_struct_dynamic(self): with self.assertRaisesRegex(TypeError, r"^Only views with array layout, not StructLayout\(\{\}\), may be indexed " r"with a value$"): - Signal(StructLayout({}))[Signal(1)] + Signal(data.StructLayout({}))[Signal(1)] def test_getattr(self): - v = Signal(UnionLayout({ + v = Signal(data.UnionLayout({ "a": unsigned(2), - "s": StructLayout({ + "s": data.StructLayout({ "b": unsigned(1), "c": unsigned(3) }), @@ -600,7 +599,7 @@ class ViewTestCase(FHDLTestCase): self.assertEqual(v.q.shape(), signed(1)) def test_getattr_reserved(self): - v = Signal(UnionLayout({ + v = Signal(data.UnionLayout({ "_a": unsigned(2) })) self.assertRepr(v["_a"], "(slice (sig v) 0:2)") @@ -609,34 +608,34 @@ class ViewTestCase(FHDLTestCase): with self.assertRaisesRegex(AttributeError, r"^View of \(sig \$signal\) does not have a field 'a'; " r"did you mean one of: 'b', 'c'\?$"): - Signal(StructLayout({"b": unsigned(1), "c": signed(1)})).a + Signal(data.StructLayout({"b": unsigned(1), "c": signed(1)})).a def test_attr_wrong_reserved(self): with self.assertRaisesRegex(AttributeError, r"^View of \(sig \$signal\) field '_c' has a reserved name " r"and may only be accessed by indexing$"): - Signal(StructLayout({"_c": signed(1)}))._c + Signal(data.StructLayout({"_c": signed(1)}))._c def test_signal_like(self): - s1 = Signal(StructLayout({"a": unsigned(1)})) + s1 = Signal(data.StructLayout({"a": unsigned(1)})) s2 = Signal.like(s1) - self.assertEqual(s2.shape(), StructLayout({"a": unsigned(1)})) + self.assertEqual(s2.shape(), data.StructLayout({"a": unsigned(1)})) def test_bug_837_array_layout_getitem_str(self): with self.assertRaisesRegex(TypeError, r"^Views with array layout may only be indexed with an integer or a value, " r"not 'init'$"): - Signal(ArrayLayout(unsigned(1), 1), init=[0])["init"] + Signal(data.ArrayLayout(unsigned(1), 1), init=[0])["init"] def test_bug_837_array_layout_getattr(self): with self.assertRaisesRegex(AttributeError, r"^View of \(sig \$signal\) with an array layout does not have fields$"): - Signal(ArrayLayout(unsigned(1), 1), init=[0]).init + Signal(data.ArrayLayout(unsigned(1), 1), init=[0]).init def test_eq(self): - s1 = Signal(StructLayout({"a": unsigned(2)})) - s2 = Signal(StructLayout({"a": unsigned(2)})) - s3 = Signal(StructLayout({"a": unsigned(1), "b": unsigned(1)})) + s1 = Signal(data.StructLayout({"a": unsigned(2)})) + s2 = Signal(data.StructLayout({"a": unsigned(2)})) + s3 = Signal(data.StructLayout({"a": unsigned(1), "b": unsigned(1)})) self.assertRepr(s1 == s2, "(== (sig s1) (sig s2))") self.assertRepr(s1 != s2, "(!= (sig s1) (sig s2))") with self.assertRaisesRegex(TypeError, @@ -653,7 +652,7 @@ class ViewTestCase(FHDLTestCase): s1 != Const(0, 2) def test_operator(self): - s1 = Signal(StructLayout({"a": unsigned(2)})) + s1 = Signal(data.StructLayout({"a": unsigned(2)})) s2 = Signal(unsigned(2)) for op in [ operator.__add__, @@ -687,18 +686,18 @@ class ViewTestCase(FHDLTestCase): op(s2, s1) def test_repr(self): - s1 = Signal(StructLayout({"a": unsigned(2)})) + s1 = Signal(data.StructLayout({"a": unsigned(2)})) self.assertRepr(s1, "View(StructLayout({'a': unsigned(2)}), (sig s1))") class StructTestCase(FHDLTestCase): def test_construct(self): - class S(Struct): + class S(data.Struct): a: unsigned(1) b: signed(3) self.assertEqual(Shape.cast(S), unsigned(4)) - self.assertEqual(Layout.cast(S), StructLayout({ + self.assertEqual(data.Layout.cast(S), data.StructLayout({ "a": unsigned(1), "b": signed(3) })) @@ -711,13 +710,13 @@ class StructTestCase(FHDLTestCase): self.assertRepr(v.b, "(s (slice (sig v) 1:4))") def test_construct_nested(self): - Q = StructLayout({"r": signed(2), "s": signed(2)}) + Q = data.StructLayout({"r": signed(2), "s": signed(2)}) - class R(Struct): + class R(data.Struct): p: 4 q: Q - class S(Struct): + class S(data.Struct): a: unsigned(1) b: R @@ -729,14 +728,14 @@ class StructTestCase(FHDLTestCase): self.assertIs(v.b.shape(), R) self.assertIsInstance(v.b, R) self.assertIs(v.b.q.shape(), Q) - self.assertIsInstance(v.b.q, View) + self.assertIsInstance(v.b.q, data.View) self.assertRepr(v.b.p, "(slice (slice (sig v) 1:9) 0:4)") self.assertRepr(v.b.q.as_value(), "(slice (slice (sig v) 1:9) 4:8)") self.assertRepr(v.b.q.r, "(s (slice (slice (slice (sig v) 1:9) 4:8) 0:2))") self.assertRepr(v.b.q.s, "(s (slice (slice (slice (sig v) 1:9) 4:8) 2:4))") def test_construct_init(self): - class S(Struct): + class S(data.Struct): p: 4 q: 2 = 1 @@ -751,7 +750,7 @@ class StructTestCase(FHDLTestCase): self.assertEqual(v3.as_value().init, 0b000011) def test_shape_undefined_wrong(self): - class S(Struct): + class S(data.Struct): pass with self.assertRaisesRegex(TypeError, @@ -759,7 +758,7 @@ class StructTestCase(FHDLTestCase): Shape.cast(S) def test_base_class_1(self): - class Sb(Struct): + class Sb(data.Struct): def add(self): return self.a + self.b @@ -775,7 +774,7 @@ class StructTestCase(FHDLTestCase): self.assertEqual(Signal(Sb2).add().shape(), unsigned(3)) def test_base_class_2(self): - class Sb(Struct): + class Sb(data.Struct): a: 2 b: 2 @@ -791,7 +790,7 @@ class StructTestCase(FHDLTestCase): self.assertEqual(Signal(Sb2).do().shape(), unsigned(3)) def test_layout_redefined_wrong(self): - class Sb(Struct): + class Sb(data.Struct): a: 1 with self.assertRaisesRegex(TypeError, @@ -800,17 +799,17 @@ class StructTestCase(FHDLTestCase): b: 1 def test_typing_annotation_coexistence(self): - class S(Struct): + class S(data.Struct): a: unsigned(1) b: int c: str = "x" - self.assertEqual(Layout.cast(S), StructLayout({"a": unsigned(1)})) + self.assertEqual(data.Layout.cast(S), data.StructLayout({"a": unsigned(1)})) self.assertEqual(S.__annotations__, {"b": int, "c": str}) self.assertEqual(S.c, "x") def test_signal_like(self): - class S(Struct): + class S(data.Struct): a: 1 s1 = Signal(S) s2 = Signal.like(s1) @@ -819,12 +818,12 @@ class StructTestCase(FHDLTestCase): class UnionTestCase(FHDLTestCase): def test_construct(self): - class U(Union): + class U(data.Union): a: unsigned(1) b: signed(3) self.assertEqual(Shape.cast(U), unsigned(3)) - self.assertEqual(Layout.cast(U), UnionLayout({ + self.assertEqual(data.Layout.cast(U), data.UnionLayout({ "a": unsigned(1), "b": signed(3) })) @@ -839,12 +838,12 @@ class UnionTestCase(FHDLTestCase): with self.assertRaisesRegex(ValueError, r"^Initial value for at most one field can be provided for a union class " r"\(specified: a, b\)$"): - class U(Union): + class U(data.Union): a: unsigned(1) = 1 b: unsigned(2) = 1 def test_construct_init_two_wrong(self): - class U(Union): + class U(data.Union): a: unsigned(1) b: unsigned(2) @@ -856,7 +855,7 @@ class UnionTestCase(FHDLTestCase): r"class \(specified: a, b\)$") def test_construct_init_override(self): - class U(Union): + class U(data.Union): a: unsigned(1) = 1 b: unsigned(2) @@ -875,7 +874,7 @@ class RFCExamplesTestCase(TestCase): return wrapper def test_rfc_example_1(self): - class Float32(Struct): + class Float32(data.Struct): fraction: unsigned(23) exponent: unsigned(8) sign: unsigned(1) @@ -896,7 +895,7 @@ class RFCExamplesTestCase(TestCase): def check_m1(): self.assertEqual((yield flt_a.as_value()), 0xbf800000) - class FloatOrInt32(Union): + class FloatOrInt32(data.Union): float: Float32 int: signed(32) @@ -916,7 +915,7 @@ class RFCExamplesTestCase(TestCase): ADD = 0 SUB = 1 - adder_op_layout = StructLayout({ + adder_op_layout = data.StructLayout({ "op": Op, "a": Float32, "b": Float32 @@ -941,17 +940,17 @@ class RFCExamplesTestCase(TestCase): ONE_SIGNED = 0 TWO_UNSIGNED = 1 - layout1 = StructLayout({ + layout1 = data.StructLayout({ "kind": Kind, - "value": UnionLayout({ + "value": data.UnionLayout({ "one_signed": signed(2), - "two_unsigned": ArrayLayout(unsigned(1), 2) + "two_unsigned": data.ArrayLayout(unsigned(1), 2) }) }) self.assertEqual(layout1.size, 3) view1 = Signal(layout1) - self.assertIsInstance(view1, View) + self.assertIsInstance(view1, data.View) self.assertEqual(view1.shape(), layout1) self.assertEqual(view1.as_value().shape(), unsigned(3)) @@ -965,10 +964,10 @@ class RFCExamplesTestCase(TestCase): def check_m1(): self.assertEqual((yield view1.as_value()), 0b011) - class SomeVariant(Struct): - class Value(Union): + class SomeVariant(data.Struct): + class Value(data.Union): one_signed: signed(2) - two_unsigned: ArrayLayout(unsigned(1), 2) + two_unsigned: data.ArrayLayout(unsigned(1), 2) kind: Kind value: Value @@ -990,12 +989,12 @@ class RFCExamplesTestCase(TestCase): def check_m2(): self.assertEqual((yield view2.as_value()), 0b010) - layout2 = StructLayout({ + layout2 = data.StructLayout({ "ready": unsigned(1), "payload": SomeVariant }) self.assertEqual(layout2.size, 4) - self.assertEqual(layout1, Layout.cast(SomeVariant)) + self.assertEqual(layout1, data.Layout.cast(SomeVariant)) self.assertIs(SomeVariant, view2.shape()) diff --git a/tests/test_lib_memory.py b/tests/test_lib_memory.py index 222b98b..357d90a 100644 --- a/tests/test_lib_memory.py +++ b/tests/test_lib_memory.py @@ -1,21 +1,20 @@ # amaranth: UnusedElaboratable=no -from amaranth.hdl._ast import * +from amaranth.hdl import * from amaranth.hdl._mem import MemoryInstance -from amaranth.lib.memory import * -from amaranth.lib.data import * +from amaranth.lib import memory, data from amaranth.lib.wiring import In, Out, SignatureMembers from .utils import * -class MyStruct(Struct): +class MyStruct(data.Struct): a: unsigned(3) b: signed(2) class WritePortTestCase(FHDLTestCase): def test_signature(self): - sig = WritePort.Signature(addr_width=2, shape=signed(4)) + sig = memory.WritePort.Signature(addr_width=2, shape=signed(4)) self.assertEqual(sig.addr_width, 2) self.assertEqual(sig.shape, signed(4)) self.assertEqual(sig.granularity, None) @@ -24,7 +23,7 @@ class WritePortTestCase(FHDLTestCase): "data": In(signed(4)), "en": In(1), })) - sig = WritePort.Signature(addr_width=2, shape=8, granularity=2) + sig = memory.WritePort.Signature(addr_width=2, shape=8, granularity=2) self.assertEqual(sig.addr_width, 2) self.assertEqual(sig.shape, 8) self.assertEqual(sig.members, SignatureMembers({ @@ -32,15 +31,15 @@ class WritePortTestCase(FHDLTestCase): "data": In(8), "en": In(4), })) - sig = WritePort.Signature(addr_width=2, shape=ArrayLayout(9, 8), granularity=2) + sig = memory.WritePort.Signature(addr_width=2, shape=data.ArrayLayout(9, 8), granularity=2) self.assertEqual(sig.addr_width, 2) - self.assertEqual(sig.shape, ArrayLayout(9, 8)) + self.assertEqual(sig.shape, data.ArrayLayout(9, 8)) self.assertEqual(sig.members, SignatureMembers({ "addr": In(2), - "data": In(ArrayLayout(9, 8)), + "data": In(data.ArrayLayout(9, 8)), "en": In(4), })) - sig = WritePort.Signature(addr_width=2, shape=0, granularity=0) + sig = memory.WritePort.Signature(addr_width=2, shape=0, granularity=0) self.assertEqual(sig.addr_width, 2) self.assertEqual(sig.shape, 0) self.assertEqual(sig.members, SignatureMembers({ @@ -48,66 +47,66 @@ class WritePortTestCase(FHDLTestCase): "data": In(0), "en": In(0), })) - sig = WritePort.Signature(addr_width=2, shape=ArrayLayout(9, 0), granularity=0) + sig = memory.WritePort.Signature(addr_width=2, shape=data.ArrayLayout(9, 0), granularity=0) self.assertEqual(sig.addr_width, 2) - self.assertEqual(sig.shape, ArrayLayout(9, 0)) + self.assertEqual(sig.shape, data.ArrayLayout(9, 0)) self.assertEqual(sig.members, SignatureMembers({ "addr": In(2), - "data": In(ArrayLayout(9, 0)), + "data": In(data.ArrayLayout(9, 0)), "en": In(0), })) def test_signature_wrong(self): with self.assertRaisesRegex(TypeError, "^`addr_width` must be a non-negative int, not -2$"): - WritePort.Signature(addr_width=-2, shape=8) + memory.WritePort.Signature(addr_width=-2, shape=8) with self.assertRaisesRegex(TypeError, "^Granularity must be a non-negative int or None, not -2$"): - WritePort.Signature(addr_width=4, shape=8, granularity=-2) + memory.WritePort.Signature(addr_width=4, shape=8, granularity=-2) with self.assertRaisesRegex(ValueError, "^Granularity cannot be specified with signed shape$"): - WritePort.Signature(addr_width=2, shape=signed(8), granularity=2) + memory.WritePort.Signature(addr_width=2, shape=signed(8), granularity=2) with self.assertRaisesRegex(TypeError, "^Granularity can only be specified for plain unsigned `Shape` or `ArrayLayout`$"): - WritePort.Signature(addr_width=2, shape=MyStruct, granularity=2) + memory.WritePort.Signature(addr_width=2, shape=MyStruct, granularity=2) with self.assertRaisesRegex(ValueError, "^Granularity must be positive$"): - WritePort.Signature(addr_width=2, shape=8, granularity=0) + memory.WritePort.Signature(addr_width=2, shape=8, granularity=0) with self.assertRaisesRegex(ValueError, "^Granularity must be positive$"): - WritePort.Signature(addr_width=2, shape=ArrayLayout(8, 8), granularity=0) + memory.WritePort.Signature(addr_width=2, shape=data.ArrayLayout(8, 8), granularity=0) with self.assertRaisesRegex(ValueError, "^Granularity must divide data width$"): - WritePort.Signature(addr_width=2, shape=8, granularity=3) + memory.WritePort.Signature(addr_width=2, shape=8, granularity=3) with self.assertRaisesRegex(ValueError, "^Granularity must divide data array length$"): - WritePort.Signature(addr_width=2, shape=ArrayLayout(8, 8), granularity=3) + memory.WritePort.Signature(addr_width=2, shape=data.ArrayLayout(8, 8), granularity=3) def test_signature_eq(self): - sig = WritePort.Signature(addr_width=2, shape=8) - self.assertEqual(sig, WritePort.Signature(addr_width=2, shape=8)) - self.assertNotEqual(sig, WritePort.Signature(addr_width=2, shape=7)) - self.assertNotEqual(sig, WritePort.Signature(addr_width=1, shape=8)) - self.assertNotEqual(sig, WritePort.Signature(addr_width=2, shape=8, granularity=8)) - sig = WritePort.Signature(addr_width=2, shape=8, granularity=4) - self.assertEqual(sig, WritePort.Signature(addr_width=2, shape=8, granularity=4)) - self.assertNotEqual(sig, WritePort.Signature(addr_width=2, shape=8, granularity=8)) + sig = memory.WritePort.Signature(addr_width=2, shape=8) + self.assertEqual(sig, memory.WritePort.Signature(addr_width=2, shape=8)) + self.assertNotEqual(sig, memory.WritePort.Signature(addr_width=2, shape=7)) + self.assertNotEqual(sig, memory.WritePort.Signature(addr_width=1, shape=8)) + self.assertNotEqual(sig, memory.WritePort.Signature(addr_width=2, shape=8, granularity=8)) + sig = memory.WritePort.Signature(addr_width=2, shape=8, granularity=4) + self.assertEqual(sig, memory.WritePort.Signature(addr_width=2, shape=8, granularity=4)) + self.assertNotEqual(sig, memory.WritePort.Signature(addr_width=2, shape=8, granularity=8)) def test_constructor(self): - signature = WritePort.Signature(shape=MyStruct, addr_width=4) - port = WritePort(signature, memory=None, domain="sync") + signature = memory.WritePort.Signature(shape=MyStruct, addr_width=4) + port = memory.WritePort(signature, memory=None, domain="sync") self.assertEqual(port.signature, signature) self.assertIsNone(port.memory) self.assertEqual(port.domain, "sync") self.assertIsInstance(port.addr, Signal) self.assertEqual(port.addr.shape(), unsigned(4)) - self.assertIsInstance(port.data, View) + self.assertIsInstance(port.data, data.View) self.assertEqual(port.data.shape(), MyStruct) self.assertIsInstance(port.en, Signal) self.assertEqual(port.en.shape(), unsigned(1)) - signature = WritePort.Signature(shape=8, addr_width=4, granularity=2) - port = WritePort(signature, memory=None, domain="sync") + signature = memory.WritePort.Signature(shape=8, addr_width=4, granularity=2) + port = memory.WritePort(signature, memory=None, domain="sync") self.assertEqual(port.signature, signature) self.assertIsNone(port.memory) self.assertEqual(port.domain, "sync") @@ -118,40 +117,40 @@ class WritePortTestCase(FHDLTestCase): self.assertIsInstance(port.en, Signal) self.assertEqual(port.en.shape(), unsigned(4)) - m = Memory(depth=16, shape=8, init=[]) - port = WritePort(signature, memory=m, domain="sync") + m = memory.Memory(depth=16, shape=8, init=[]) + port = memory.WritePort(signature, memory=m, domain="sync") self.assertIs(port.memory, m) self.assertEqual(m.w_ports, (port,)) def test_constructor_wrong(self): - signature = ReadPort.Signature(shape=8, addr_width=4) + signature = memory.ReadPort.Signature(shape=8, addr_width=4) with self.assertRaisesRegex(TypeError, r"^Expected `WritePort.Signature`, not ReadPort.Signature\(.*\)$"): - WritePort(signature, memory=None, domain="sync") - signature = WritePort.Signature(shape=8, addr_width=4, granularity=2) + memory.WritePort(signature, memory=None, domain="sync") + signature = memory.WritePort.Signature(shape=8, addr_width=4, granularity=2) with self.assertRaisesRegex(TypeError, r"^Domain has to be a string, not None$"): - WritePort(signature, memory=None, domain=None) + memory.WritePort(signature, memory=None, domain=None) with self.assertRaisesRegex(TypeError, r"^Expected `Memory` or `None`, not 'a'$"): - WritePort(signature, memory="a", domain="sync") + memory.WritePort(signature, memory="a", domain="sync") with self.assertRaisesRegex(ValueError, r"^Write port domain cannot be \"comb\"$"): - WritePort(signature, memory=None, domain="comb") - signature = WritePort.Signature(shape=8, addr_width=4) - m = Memory(depth=8, shape=8, init=[]) + memory.WritePort(signature, memory=None, domain="comb") + signature = memory.WritePort.Signature(shape=8, addr_width=4) + m = memory.Memory(depth=8, shape=8, init=[]) with self.assertRaisesRegex(ValueError, r"^Memory address width 3 doesn't match port address width 4$"): - WritePort(signature, memory=m, domain="sync") - m = Memory(depth=16, shape=signed(8), init=[]) + memory.WritePort(signature, memory=m, domain="sync") + m = memory.Memory(depth=16, shape=signed(8), init=[]) with self.assertRaisesRegex(ValueError, r"^Memory shape signed\(8\) doesn't match port shape 8$"): - WritePort(signature, memory=m, domain="sync") + memory.WritePort(signature, memory=m, domain="sync") class ReadPortTestCase(FHDLTestCase): def test_signature(self): - sig = ReadPort.Signature(addr_width=2, shape=signed(4)) + sig = memory.ReadPort.Signature(addr_width=2, shape=signed(4)) self.assertEqual(sig.addr_width, 2) self.assertEqual(sig.shape, signed(4)) self.assertEqual(sig.members, SignatureMembers({ @@ -159,7 +158,7 @@ class ReadPortTestCase(FHDLTestCase): "data": Out(signed(4)), "en": In(1, init=1), })) - sig = ReadPort.Signature(addr_width=2, shape=8) + sig = memory.ReadPort.Signature(addr_width=2, shape=8) self.assertEqual(sig.addr_width, 2) self.assertEqual(sig.shape, 8) self.assertEqual(sig.members, SignatureMembers({ @@ -167,7 +166,7 @@ class ReadPortTestCase(FHDLTestCase): "data": Out(8), "en": In(1, init=1), })) - sig = ReadPort.Signature(addr_width=2, shape=MyStruct) + sig = memory.ReadPort.Signature(addr_width=2, shape=MyStruct) self.assertEqual(sig.addr_width, 2) self.assertEqual(sig.shape, MyStruct) self.assertEqual(sig.members, SignatureMembers({ @@ -179,31 +178,31 @@ class ReadPortTestCase(FHDLTestCase): def test_signature_wrong(self): with self.assertRaisesRegex(TypeError, "^`addr_width` must be a non-negative int, not -2$"): - ReadPort.Signature(addr_width=-2, shape=8) + memory.ReadPort.Signature(addr_width=-2, shape=8) def test_signature_eq(self): - sig = ReadPort.Signature(addr_width=2, shape=8) - self.assertEqual(sig, ReadPort.Signature(addr_width=2, shape=8)) - self.assertNotEqual(sig, ReadPort.Signature(addr_width=2, shape=7)) - self.assertNotEqual(sig, ReadPort.Signature(addr_width=1, shape=8)) - self.assertNotEqual(sig, WritePort.Signature(addr_width=2, shape=8)) + sig = memory.ReadPort.Signature(addr_width=2, shape=8) + self.assertEqual(sig, memory.ReadPort.Signature(addr_width=2, shape=8)) + self.assertNotEqual(sig, memory.ReadPort.Signature(addr_width=2, shape=7)) + self.assertNotEqual(sig, memory.ReadPort.Signature(addr_width=1, shape=8)) + self.assertNotEqual(sig, memory.WritePort.Signature(addr_width=2, shape=8)) def test_constructor(self): - signature = ReadPort.Signature(shape=MyStruct, addr_width=4) - port = ReadPort(signature, memory=None, domain="sync") + signature = memory.ReadPort.Signature(shape=MyStruct, addr_width=4) + port = memory.ReadPort(signature, memory=None, domain="sync") self.assertEqual(port.signature, signature) self.assertIsNone(port.memory) self.assertEqual(port.domain, "sync") self.assertIsInstance(port.addr, Signal) self.assertEqual(port.addr.shape(), unsigned(4)) - self.assertIsInstance(port.data, View) + self.assertIsInstance(port.data, data.View) self.assertEqual(port.data.shape(), MyStruct) self.assertIsInstance(port.en, Signal) self.assertEqual(port.en.shape(), unsigned(1)) self.assertEqual(port.transparent_for, ()) - signature = ReadPort.Signature(shape=8, addr_width=4) - port = ReadPort(signature, memory=None, domain="comb") + signature = memory.ReadPort.Signature(shape=8, addr_width=4) + port = memory.ReadPort(signature, memory=None, domain="comb") self.assertEqual(port.signature, signature) self.assertIsNone(port.memory) self.assertEqual(port.domain, "comb") @@ -216,60 +215,60 @@ class ReadPortTestCase(FHDLTestCase): self.assertEqual(port.en.value, 1) self.assertEqual(port.transparent_for, ()) - m = Memory(depth=16, shape=8, init=[]) - port = ReadPort(signature, memory=m, domain="sync") + m = memory.Memory(depth=16, shape=8, init=[]) + port = memory.ReadPort(signature, memory=m, domain="sync") self.assertIs(port.memory, m) self.assertEqual(m.r_ports, (port,)) write_port = m.write_port() - port = ReadPort(signature, memory=m, domain="sync", transparent_for=[write_port]) + port = memory.ReadPort(signature, memory=m, domain="sync", transparent_for=[write_port]) self.assertIs(port.memory, m) self.assertEqual(port.transparent_for, (write_port,)) def test_constructor_wrong(self): - signature = WritePort.Signature(shape=8, addr_width=4) + signature = memory.WritePort.Signature(shape=8, addr_width=4) with self.assertRaisesRegex(TypeError, r"^Expected `ReadPort.Signature`, not WritePort.Signature\(.*\)$"): - ReadPort(signature, memory=None, domain="sync") - signature = ReadPort.Signature(shape=8, addr_width=4) + memory.ReadPort(signature, memory=None, domain="sync") + signature = memory.ReadPort.Signature(shape=8, addr_width=4) with self.assertRaisesRegex(TypeError, r"^Domain has to be a string, not None$"): - ReadPort(signature, memory=None, domain=None) + memory.ReadPort(signature, memory=None, domain=None) with self.assertRaisesRegex(TypeError, r"^Expected `Memory` or `None`, not 'a'$"): - ReadPort(signature, memory="a", domain="sync") - signature = ReadPort.Signature(shape=8, addr_width=4) - m = Memory(depth=8, shape=8, init=[]) + memory.ReadPort(signature, memory="a", domain="sync") + signature = memory.ReadPort.Signature(shape=8, addr_width=4) + m = memory.Memory(depth=8, shape=8, init=[]) with self.assertRaisesRegex(ValueError, r"^Memory address width 3 doesn't match port address width 4$"): - ReadPort(signature, memory=m, domain="sync") - m = Memory(depth=16, shape=signed(8), init=[]) + memory.ReadPort(signature, memory=m, domain="sync") + m = memory.Memory(depth=16, shape=signed(8), init=[]) with self.assertRaisesRegex(ValueError, r"^Memory shape signed\(8\) doesn't match port shape 8$"): - ReadPort(signature, memory=m, domain="sync") - m = Memory(depth=16, shape=8, init=[]) + memory.ReadPort(signature, memory=m, domain="sync") + m = memory.Memory(depth=16, shape=8, init=[]) port = m.read_port() with self.assertRaisesRegex(TypeError, r"^`transparent_for` must contain only `WritePort` instances$"): - ReadPort(signature, memory=m, domain="sync", transparent_for=[port]) + memory.ReadPort(signature, memory=m, domain="sync", transparent_for=[port]) write_port = m.write_port() - m2 = Memory(depth=16, shape=8, init=[]) + m2 = memory.Memory(depth=16, shape=8, init=[]) with self.assertRaisesRegex(ValueError, r"^Transparent write ports must belong to the same memory$"): - ReadPort(signature, memory=m2, domain="sync", transparent_for=[write_port]) + memory.ReadPort(signature, memory=m2, domain="sync", transparent_for=[write_port]) with self.assertRaisesRegex(ValueError, r"^Transparent write ports must belong to the same domain$"): - ReadPort(signature, memory=m, domain="other", transparent_for=[write_port]) + memory.ReadPort(signature, memory=m, domain="other", transparent_for=[write_port]) class MemoryTestCase(FHDLTestCase): def test_constructor(self): - m = Memory(shape=8, depth=4, init=[1, 2, 3]) + m = memory.Memory(shape=8, depth=4, init=[1, 2, 3]) self.assertEqual(m.shape, 8) self.assertEqual(m.depth, 4) self.assertEqual(m.init.shape, 8) self.assertEqual(m.init.depth, 4) self.assertEqual(m.attrs, {}) - self.assertIsInstance(m.init, Memory.Init) + self.assertIsInstance(m.init, memory.Memory.Init) self.assertEqual(list(m.init), [1, 2, 3, 0]) self.assertEqual(m.init._raw, [1, 2, 3, 0]) self.assertRepr(m.init, "Memory.Init([1, 2, 3, 0])") @@ -281,31 +280,31 @@ class MemoryTestCase(FHDLTestCase): {"a": 0, "b": 1}, {"a": 2, "b": 3}, ] - m = Memory(shape=MyStruct, depth=4, init=init, attrs={"ram_style": "block"}) + m = memory.Memory(shape=MyStruct, depth=4, init=init, attrs={"ram_style": "block"}) self.assertEqual(m.shape, MyStruct) self.assertEqual(m.depth, 4) self.assertEqual(m.attrs, {"ram_style": "block"}) - self.assertIsInstance(m.init, Memory.Init) + self.assertIsInstance(m.init, memory.Memory.Init) self.assertEqual(list(m.init), [{"a": 0, "b": 1}, {"a": 2, "b": 3}, None, None]) self.assertEqual(m.init._raw, [8, 0x1a, 0, 0]) def test_constructor_wrong(self): with self.assertRaisesRegex(TypeError, r"^Memory depth must be a non-negative integer, not 'a'$"): - Memory(shape=8, depth="a", init=[]) + memory.Memory(shape=8, depth="a", init=[]) with self.assertRaisesRegex(TypeError, r"^Memory depth must be a non-negative integer, not -1$"): - Memory(shape=8, depth=-1, init=[]) + memory.Memory(shape=8, depth=-1, init=[]) with self.assertRaisesRegex(TypeError, r"^Object 'a' cannot be converted to an Amaranth shape$"): - Memory(shape="a", depth=3, init=[]) + memory.Memory(shape="a", depth=3, init=[]) with self.assertRaisesRegex(TypeError, (r"^Memory initialization value at address 1: " r"'str' object cannot be interpreted as an integer$")): - Memory(shape=8, depth=4, init=[1, "0"]) + memory.Memory(shape=8, depth=4, init=[1, "0"]) def test_init_set(self): - m = Memory(shape=8, depth=4, init=[]) + m = memory.Memory(shape=8, depth=4, init=[]) m.init[1] = 2 self.assertEqual(list(m.init), [0, 2, 0, 0]) self.assertEqual(m.init._raw, [0, 2, 0, 0]) @@ -315,23 +314,23 @@ class MemoryTestCase(FHDLTestCase): self.assertEqual(list(m.init), [6, 7, 0, 0]) def test_init_set_shapecastable(self): - m = Memory(shape=MyStruct, depth=4, init=[]) + m = memory.Memory(shape=MyStruct, depth=4, init=[]) m.init[1] = {"a": 1, "b": 2} self.assertEqual(list(m.init), [None, {"a": 1, "b": 2}, None, None]) self.assertEqual(m.init._raw, [0, 0x11, 0, 0]) def test_init_set_wrong(self): - m = Memory(shape=8, depth=4, init=[]) + m = memory.Memory(shape=8, depth=4, init=[]) with self.assertRaisesRegex(TypeError, r"^'str' object cannot be interpreted as an integer$"): m.init[0] = "a" - m = Memory(shape=MyStruct, depth=4, init=[]) + m = memory.Memory(shape=MyStruct, depth=4, init=[]) # underlying TypeError message differs between PyPy and CPython with self.assertRaises(TypeError): m.init[0] = 1 def test_init_set_slice_wrong(self): - m = Memory(shape=8, depth=4, init=[]) + m = memory.Memory(shape=8, depth=4, init=[]) with self.assertRaisesRegex(ValueError, r"^Changing length of Memory.init is not allowed$"): m.init[1:] = [1, 2] @@ -350,7 +349,7 @@ class MemoryTestCase(FHDLTestCase): (4, 2), (5, 3), ]: - m = Memory(shape=8, depth=depth, init=[]) + m = memory.Memory(shape=8, depth=depth, init=[]) rp = m.read_port() self.assertEqual(rp.signature.addr_width, addr_width) self.assertEqual(rp.signature.shape, 8) @@ -361,7 +360,7 @@ class MemoryTestCase(FHDLTestCase): self.assertEqual(m.w_ports, (wp,)) def test_elaborate(self): - m = Memory(shape=MyStruct, depth=4, init=[{"a": 1, "b": 2}]) + m = memory.Memory(shape=MyStruct, depth=4, init=[{"a": 1, "b": 2}]) wp = m.write_port() rp0 = m.read_port(domain="sync", transparent_for=[wp]) rp1 = m.read_port(domain="comb")