if name in self.fields:
raise NameError("Field {!r} has a name that is already present in the layout"
.format(field))
+ if isinstance(shape, int):
+ shape = (shape, False)
self.fields[name] = (shape, direction)
def __getitem__(self, name):
for name, (shape, dir) in self.fields.items():
yield (name, shape, dir)
+ def __eq__(self, other):
+ return self.fields == other.fields
+
# Unlike most Values, Record *can* be subclassed.
class Record(Value):
- def __init__(self, layout, name=None):
+ def __init__(self, layout, name=None, *, fields=None):
if name is None:
name = tracer.get_var_name(default=None)
self.layout = Layout.wrap(layout)
self.fields = OrderedDict()
for field_name, field_shape, field_dir in self.layout:
- if isinstance(field_shape, Layout):
- self.fields[field_name] = Record(field_shape, name=concat(name, field_name))
+ if fields is not None and field_name in fields:
+ field = fields[field_name]
+ if isinstance(field_shape, Layout):
+ assert isinstance(field, Record) and field_shape == field.layout
+ else:
+ assert isinstance(field, Signal) and field_shape == field.shape()
+ self.fields[field_name] = field
else:
- self.fields[field_name] = Signal(field_shape, name=concat(name, field_name))
+ if isinstance(field_shape, Layout):
+ self.fields[field_name] = Record(field_shape, name=concat(name, field_name))
+ else:
+ self.fields[field_name] = Signal(field_shape, name=concat(name, field_name))
def __getattr__(self, name):
return self[name]
])
])
- self.assertEqual(layout["cyc"], (1, DIR_NONE))
+ self.assertEqual(layout["cyc"], ((1, False), DIR_NONE))
self.assertEqual(layout["data"], ((32, True), DIR_NONE))
- self.assertEqual(layout["stb"], (1, DIR_FANOUT))
- self.assertEqual(layout["ack"], (1, DIR_FANIN))
+ self.assertEqual(layout["stb"], ((1, False), DIR_FANOUT))
+ self.assertEqual(layout["ack"], ((1, False), DIR_FANIN))
sublayout = layout["info"][0]
self.assertEqual(layout["info"][1], DIR_NONE)
- self.assertEqual(sublayout["a"], (1, DIR_NONE))
- self.assertEqual(sublayout["b"], (1, DIR_NONE))
+ self.assertEqual(sublayout["a"], ((1, False), DIR_NONE))
+ self.assertEqual(sublayout["b"], ((1, False), DIR_NONE))
def test_wrong_field(self):
with self.assertRaises(TypeError,
msg="Unnamed record does not have a field 'en'. Did you mean one of: stb, ack?"):
r.en
+ def test_construct_with_fields(self):
+ ns = Signal(1)
+ nr = Record([
+ ("burst", 1)
+ ])
+ r = Record([
+ ("stb", 1),
+ ("info", [
+ ("burst", 1)
+ ])
+ ], fields={
+ "stb": ns,
+ "info": nr
+ })
+ self.assertIs(r.stb, ns)
+ self.assertIs(r.info, nr)
+
class ConnectTestCase(FHDLTestCase):
def setUp_flat(self):
def test_pin_layout_i(self):
layout_1 = pin_layout(1, dir="i")
self.assertEqual(layout_1.fields, {
- "i": (1, DIR_NONE),
+ "i": ((1, False), DIR_NONE),
})
layout_2 = pin_layout(2, dir="i")
self.assertEqual(layout_2.fields, {
- "i": (2, DIR_NONE),
+ "i": ((2, False), DIR_NONE),
})
def test_pin_layout_o(self):
layout_1 = pin_layout(1, dir="o")
self.assertEqual(layout_1.fields, {
- "o": (1, DIR_NONE),
+ "o": ((1, False), DIR_NONE),
})
layout_2 = pin_layout(2, dir="o")
self.assertEqual(layout_2.fields, {
- "o": (2, DIR_NONE),
+ "o": ((2, False), DIR_NONE),
})
def test_pin_layout_io(self):
layout_1 = pin_layout(1, dir="io")
self.assertEqual(layout_1.fields, {
- "i": (1, DIR_NONE),
- "o": (1, DIR_NONE),
- "oe": (1, DIR_NONE),
+ "i": ((1, False), DIR_NONE),
+ "o": ((1, False), DIR_NONE),
+ "oe": ((1, False), DIR_NONE),
})
layout_2 = pin_layout(2, dir="io")
self.assertEqual(layout_2.fields, {
- "i": (2, DIR_NONE),
- "o": (2, DIR_NONE),
- "oe": (1, DIR_NONE),
+ "i": ((2, False), DIR_NONE),
+ "o": ((2, False), DIR_NONE),
+ "oe": ((1, False), DIR_NONE),
})
def test_pin_layout_i(self):
layout_1 = pin_layout(1, dir="i", xdr=2)
self.assertEqual(layout_1.fields, {
- "i0": (1, DIR_NONE),
- "i1": (1, DIR_NONE),
+ "i0": ((1, False), DIR_NONE),
+ "i1": ((1, False), DIR_NONE),
})
layout_2 = pin_layout(2, dir="i", xdr=2)
self.assertEqual(layout_2.fields, {
- "i0": (2, DIR_NONE),
- "i1": (2, DIR_NONE),
+ "i0": ((2, False), DIR_NONE),
+ "i1": ((2, False), DIR_NONE),
})
def test_pin_layout_o(self):
layout_1 = pin_layout(1, dir="o", xdr=2)
self.assertEqual(layout_1.fields, {
- "o0": (1, DIR_NONE),
- "o1": (1, DIR_NONE),
+ "o0": ((1, False), DIR_NONE),
+ "o1": ((1, False), DIR_NONE),
})
layout_2 = pin_layout(2, dir="o", xdr=2)
self.assertEqual(layout_2.fields, {
- "o0": (2, DIR_NONE),
- "o1": (2, DIR_NONE),
+ "o0": ((2, False), DIR_NONE),
+ "o1": ((2, False), DIR_NONE),
})
def test_pin_layout_io(self):
layout_1 = pin_layout(1, dir="io", xdr=2)
self.assertEqual(layout_1.fields, {
- "i0": (1, DIR_NONE),
- "i1": (1, DIR_NONE),
- "o0": (1, DIR_NONE),
- "o1": (1, DIR_NONE),
- "oe": (1, DIR_NONE),
+ "i0": ((1, False), DIR_NONE),
+ "i1": ((1, False), DIR_NONE),
+ "o0": ((1, False), DIR_NONE),
+ "o1": ((1, False), DIR_NONE),
+ "oe": ((1, False), DIR_NONE),
})
layout_2 = pin_layout(2, dir="io", xdr=2)
self.assertEqual(layout_2.fields, {
- "i0": (2, DIR_NONE),
- "i1": (2, DIR_NONE),
- "o0": (2, DIR_NONE),
- "o1": (2, DIR_NONE),
- "oe": (1, DIR_NONE),
+ "i0": ((2, False), DIR_NONE),
+ "i1": ((2, False), DIR_NONE),
+ "o0": ((2, False), DIR_NONE),
+ "o1": ((2, False), DIR_NONE),
+ "oe": ((1, False), DIR_NONE),
})