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 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\.<locals>.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())
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in a new issue