record: preserve order

This commit is contained in:
Sebastien Bourdeauducq 2012-01-09 15:14:42 +01:00
parent bdcaeb159b
commit 89bf704b2b
4 changed files with 34 additions and 36 deletions

View file

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

View file

@ -2,9 +2,10 @@ from migen.fhdl.structure import *
from migen.fhdl.structure import _make_signal_name from migen.fhdl.structure import _make_signal_name
class Record: class Record:
def __init__(self, template, name=None): def __init__(self, layout, name=None):
self.name = name or _make_signal_name() self.name = name or _make_signal_name()
for f in template: self.field_order = []
for f in layout:
if isinstance(f, tuple): if isinstance(f, tuple):
if isinstance(f[1], BV): if isinstance(f[1], BV):
setattr(self, f[0], Signal(f[1], self.name + "_" + f[0])) setattr(self, f[0], Signal(f[1], self.name + "_" + f[0]))
@ -14,24 +15,26 @@ 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])
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)
def template(self): def layout(self):
l = [] l = []
for key in sorted(self.__dict__): for key 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))
elif isinstance(e, Record): elif isinstance(e, Record):
l.append((key, e.template())) l.append((key, e.layout()))
return l return l
def copy(self, name=None): def copy(self, name=None):
return Record(self.template(), name or _make_signal_name()) return Record(self.layout(), name or _make_signal_name())
def subrecord(self, *descr): def subrecord(self, *descr):
fields = {} fields = []
for item in descr: for item in descr:
path = item.split('/') path = item.split('/')
last = path.pop() last = path.pop()
@ -40,24 +43,19 @@ class Record:
for hop in path: for hop in path:
pos_self = getattr(pos_self, hop) pos_self = getattr(pos_self, hop)
try: try:
pos_fields = fields[hop] lu = list(filter(lambda x: x[0] == hop, pos_fields))
except KeyError: pos_fields = lu[0][1]
pos_fields = fields[hop] = {} except IndexError:
if not isinstance(pos_fields, dict): n = []
pos_fields.append((hop, n))
pos_fields = n
if not isinstance(pos_fields, list):
raise ValueError raise ValueError
if last in pos_fields: if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0:
raise ValueError raise ValueError
pos_fields[last] = getattr(pos_self, last) pos_fields.append((last, getattr(pos_self, last)))
def dict_to_list(d): print(fields)
l = [] return Record(fields, "subrecord")
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 compatible(self, other): def compatible(self, other):
tpl1 = self.flatten() tpl1 = self.flatten()
@ -66,7 +64,7 @@ class Record:
def flatten(self): def flatten(self):
l = [] l = []
for key in sorted(self.__dict__): for key in self.field_order:
e = self.__dict__[key] e = self.__dict__[key]
if isinstance(e, Signal): if isinstance(e, Signal):
l.append(e) l.append(e)
@ -75,4 +73,4 @@ class Record:
return l return l
def __repr__(self): def __repr__(self):
return repr(self.template()) return repr(self.layout())

View file

@ -14,7 +14,7 @@ def _simple_binary(a, b, actor_class):
width = max(signal_self.bv.width, signal_other.bv.width) width = max(signal_self.bv.width, signal_other.bv.width)
signed = signal_self.bv.signed and signal_other.bv.signed signed = signal_self.bv.signed and signal_other.bv.signed
actor = actor_class(BV(width, signed)) actor = actor_class(BV(width, signed))
combinator = Combinator(actor.operands.template(), ["a"], ["b"]) combinator = Combinator(actor.operands.layout(), ["a"], ["b"])
add_connection(a.dfg, combinator, actor) add_connection(a.dfg, combinator, actor)
add_connection(a.dfg, a.actor, combinator, a.endp, combinator.sinks()[0]) add_connection(a.dfg, a.actor, combinator, a.endp, combinator.sinks()[0])
add_connection(a.dfg, b.actor, combinator, b.endp, combinator.sinks()[1]) add_connection(a.dfg, b.actor, combinator, b.endp, combinator.sinks()[1])

View file

@ -4,9 +4,9 @@ from migen.corelogic.record import *
from migen.corelogic.misc import optree from migen.corelogic.misc import optree
class Buffer(Actor): class Buffer(Actor):
def __init__(self, template): def __init__(self, layout):
self.d = Record(template) self.d = Record(layout)
self.q = Record(template) self.q = Record(layout)
Actor.__init__(self, Actor.__init__(self,
SchedulingModel(SchedulingModel.PIPELINE, 1), SchedulingModel(SchedulingModel.PIPELINE, 1),
self.d, self.q) self.d, self.q)
@ -18,8 +18,8 @@ class Buffer(Actor):
return Fragment(sync=sync) return Fragment(sync=sync)
class Combinator(Actor): class Combinator(Actor):
def __init__(self, template, *subrecords): def __init__(self, layout, *subrecords):
self.destination = Record(template) self.destination = Record(layout)
self.ins = [self.destination.subrecord(*subr) for subr in subrecords] self.ins = [self.destination.subrecord(*subr) for subr in subrecords]
Actor.__init__(self, Actor.__init__(self,
SchedulingModel(SchedulingModel.COMBINATORIAL), SchedulingModel(SchedulingModel.COMBINATORIAL),
@ -36,8 +36,8 @@ class Combinator(Actor):
return Fragment(comb) return Fragment(comb)
class Splitter(Actor): class Splitter(Actor):
def __init__(self, template, *subrecords): def __init__(self, layout, *subrecords):
self.source = Record(template) self.source = Record(layout)
self.outs = [self.source.subrecord(*subr) for subr in subrecords] self.outs = [self.source.subrecord(*subr) for subr in subrecords]
Actor.__init__(self, Actor.__init__(self,
SchedulingModel(SchedulingModel.COMBINATORIAL), SchedulingModel(SchedulingModel.COMBINATORIAL),