record: support aligned flattening
This commit is contained in:
parent
b06e70d849
commit
683e6b4a6c
|
@ -2,16 +2,17 @@ from migen.fhdl.structure import *
|
||||||
from migen.corelogic.record import *
|
from migen.corelogic.record import *
|
||||||
|
|
||||||
L = [
|
L = [
|
||||||
("x", BV(10)),
|
("x", BV(10), 8),
|
||||||
("y", BV(10)),
|
("y", BV(10), 8),
|
||||||
("level2", [
|
("level2", [
|
||||||
("a", BV(5)),
|
("a", BV(5), 32),
|
||||||
("b", BV(5))
|
("b", BV(5), 16)
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
|
||||||
myrec = Record(L)
|
myrec = Record(L)
|
||||||
print(myrec.flatten())
|
print(myrec.flatten())
|
||||||
|
print(myrec.flatten(True))
|
||||||
s = myrec.subrecord("level2/a", "x")
|
s = myrec.subrecord("level2/a", "x")
|
||||||
print(s.flatten())
|
print(s.flatten())
|
||||||
print(s.level2.layout())
|
print(s.level2.layout())
|
||||||
|
|
|
@ -15,24 +15,30 @@ class Record:
|
||||||
setattr(self, f[0], Record(f[1], self.name + "_" + f[0]))
|
setattr(self, f[0], Record(f[1], self.name + "_" + f[0]))
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
self.field_order.append(f[0])
|
if len(f) == 3:
|
||||||
|
self.field_order.append((f[0], f[2]))
|
||||||
|
else:
|
||||||
|
self.field_order.append((f[0], 1))
|
||||||
else:
|
else:
|
||||||
setattr(self, f, Signal(BV(1), self.name + "_" + f))
|
setattr(self, f, Signal(BV(1), self.name + "_" + f))
|
||||||
self.field_order.append(f)
|
self.field_order.append((f, 1))
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
l = []
|
l = []
|
||||||
for key in self.field_order:
|
for key, alignment in self.field_order:
|
||||||
e = self.__dict__[key]
|
e = self.__dict__[key]
|
||||||
if isinstance(e, Signal):
|
if isinstance(e, Signal):
|
||||||
l.append((key, e.bv))
|
l.append((key, e.bv, alignment))
|
||||||
elif isinstance(e, Record):
|
elif isinstance(e, Record):
|
||||||
l.append((key, e.layout()))
|
l.append((key, e.layout(), alignment))
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def copy(self, name=None):
|
def copy(self, name=None):
|
||||||
return Record(self.layout(), name or _make_signal_name())
|
return Record(self.layout(), name or _make_signal_name())
|
||||||
|
|
||||||
|
def get_alignment(self, name):
|
||||||
|
return list(filter(lambda x: x[0] == name, self.field_order))[0][1]
|
||||||
|
|
||||||
def subrecord(self, *descr):
|
def subrecord(self, *descr):
|
||||||
fields = []
|
fields = []
|
||||||
for item in descr:
|
for item in descr:
|
||||||
|
@ -53,7 +59,7 @@ class Record:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0:
|
if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
pos_fields.append((last, getattr(pos_self, last)))
|
pos_fields.append((last, getattr(pos_self, last), pos_self.get_alignment(last)))
|
||||||
return Record(fields, "subrecord")
|
return Record(fields, "subrecord")
|
||||||
|
|
||||||
def compatible(self, other):
|
def compatible(self, other):
|
||||||
|
@ -61,14 +67,25 @@ class Record:
|
||||||
tpl2 = other.flatten()
|
tpl2 = other.flatten()
|
||||||
return len(tpl1) == len(tpl2)
|
return len(tpl1) == len(tpl2)
|
||||||
|
|
||||||
def flatten(self):
|
def flatten(self, align=False, offset=0):
|
||||||
l = []
|
l = []
|
||||||
for key in self.field_order:
|
for key, alignment in self.field_order:
|
||||||
|
if align:
|
||||||
|
pad_size = alignment - (offset % alignment)
|
||||||
|
if pad_size < alignment:
|
||||||
|
l.append(Constant(0, BV(pad_size)))
|
||||||
|
offset += pad_size
|
||||||
|
|
||||||
e = self.__dict__[key]
|
e = self.__dict__[key]
|
||||||
if isinstance(e, Signal):
|
if isinstance(e, Signal):
|
||||||
l.append(e)
|
added = [e]
|
||||||
elif isinstance(e, Record):
|
elif isinstance(e, Record):
|
||||||
l += e.flatten()
|
added = e.flatten(align, offset)
|
||||||
|
else:
|
||||||
|
raise TypeError
|
||||||
|
for x in added:
|
||||||
|
offset += x.bv.width
|
||||||
|
l += added
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
Loading…
Reference in New Issue