Skip to content

Commit

Permalink
record: support aligned flattening
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastien Bourdeauducq committed Jan 9, 2012
1 parent b06e70d commit 683e6b4
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
9 changes: 5 additions & 4 deletions examples/using_record.py
Expand Up @@ -2,16 +2,17 @@
from migen.corelogic.record import *

L = [
("x", BV(10)),
("y", BV(10)),
("x", BV(10), 8),
("y", BV(10), 8),
("level2", [
("a", BV(5)),
("b", BV(5))
("a", BV(5), 32),
("b", BV(5), 16)
])
]

myrec = Record(L)
print(myrec.flatten())
print(myrec.flatten(True))
s = myrec.subrecord("level2/a", "x")
print(s.flatten())
print(s.level2.layout())
Expand Down
37 changes: 27 additions & 10 deletions migen/corelogic/record.py
Expand Up @@ -15,24 +15,30 @@ def __init__(self, layout, name=None):
setattr(self, f[0], Record(f[1], self.name + "_" + f[0]))
else:
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:
setattr(self, f, Signal(BV(1), self.name + "_" + f))
self.field_order.append(f)
self.field_order.append((f, 1))

def layout(self):
l = []
for key in self.field_order:
for key, alignment in self.field_order:
e = self.__dict__[key]
if isinstance(e, Signal):
l.append((key, e.bv))
l.append((key, e.bv, alignment))
elif isinstance(e, Record):
l.append((key, e.layout()))
l.append((key, e.layout(), alignment))
return l

def copy(self, name=None):
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):
fields = []
for item in descr:
Expand All @@ -53,22 +59,33 @@ def subrecord(self, *descr):
raise ValueError
if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0:
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")

def compatible(self, other):
tpl1 = self.flatten()
tpl2 = other.flatten()
return len(tpl1) == len(tpl2)

def flatten(self):
def flatten(self, align=False, offset=0):
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]
if isinstance(e, Signal):
l.append(e)
added = [e]
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

def __repr__(self):
Expand Down

0 comments on commit 683e6b4

Please sign in to comment.