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