corelogic: record

This commit is contained in:
Sebastien Bourdeauducq 2012-01-06 11:20:44 +01:00
parent d7a3bed44c
commit 038992e7d2
2 changed files with 89 additions and 0 deletions

19
examples/using_record.py Normal file
View File

@ -0,0 +1,19 @@
from migen.fhdl.structure import *
from migen.corelogic.record import *
TPL = [
("x", BV(10)),
("y", BV(10)),
("level2", [
("a", BV(5)),
("b", BV(5))
])
]
myrec = Record(TPL)
print(myrec.flatten())
s = myrec.subrecord("level2/a", "x")
print(s.flatten())
print(s.level2.template())
myrec2 = myrec.copy()
print(myrec2.flatten())

70
migen/corelogic/record.py Normal file
View File

@ -0,0 +1,70 @@
from migen.fhdl.structure import *
from migen.fhdl.structure import _make_signal_name
class Record:
def __init__(self, template, name=None):
self.name = name or _make_signal_name()
for f in template:
if isinstance(f, tuple):
if isinstance(f[1], BV):
setattr(self, f[0], Signal(f[1], self.name + "_" + f[0]))
elif isinstance(f[1], Signal) or isinstance(f[1], Record):
setattr(self, f[0], f[1])
elif isinstance(f[1], list):
setattr(self, f[0], Record(f[1], self.name + "_" + f[0]))
else:
raise TypeError
else:
setattr(self, f, Signal(BV(1), self.name + "_" + f))
def template(self):
l = []
for key in self.__dict__:
e = self.__dict__[key]
if isinstance(e, Signal):
l.append((key, e.bv))
elif isinstance(e, Record):
l.append((key, e.template()))
return l
def copy(self, name=None):
return Record(self.template(), name or _make_signal_name())
def subrecord(self, *descr):
fields = {}
for item in descr:
path = item.split('/')
last = path.pop()
pos_self = self
pos_fields = fields
for hop in path:
pos_self = getattr(pos_self, hop)
try:
pos_fields = fields[hop]
except KeyError:
pos_fields = fields[hop] = {}
if not isinstance(pos_fields, dict):
raise ValueError
if last in pos_fields:
raise ValueError
pos_fields[last] = getattr(pos_self, last)
def dict_to_list(d):
l = []
for key in d:
e = d[key]
if isinstance(e, dict):
l.append((key, dict_to_list(e)))
else:
l.append((key, e))
return l
return Record(dict_to_list(fields), "subrecord")
def flatten(self):
l = []
for key in sorted(self.__dict__):
e = self.__dict__[key]
if isinstance(e, Signal):
l.append(e)
elif isinstance(e, Record):
l += e.flatten()
return l