From 89bf704b2b1f61671381f0e7416c6f0a4a8020e9 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 9 Jan 2012 15:14:42 +0100 Subject: [PATCH] record: preserve order --- examples/using_record.py | 6 ++--- migen/corelogic/record.py | 48 +++++++++++++++++++-------------------- migen/flow/composer.py | 2 +- migen/flow/plumbing.py | 14 ++++++------ 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/examples/using_record.py b/examples/using_record.py index 0940715ed..0b61430c3 100644 --- a/examples/using_record.py +++ b/examples/using_record.py @@ -1,7 +1,7 @@ from migen.fhdl.structure import * from migen.corelogic.record import * -TPL = [ +L = [ ("x", BV(10)), ("y", BV(10)), ("level2", [ @@ -10,10 +10,10 @@ TPL = [ ]) ] -myrec = Record(TPL) +myrec = Record(L) print(myrec.flatten()) s = myrec.subrecord("level2/a", "x") print(s.flatten()) -print(s.level2.template()) +print(s.level2.layout()) myrec2 = myrec.copy() print(myrec2.flatten()) diff --git a/migen/corelogic/record.py b/migen/corelogic/record.py index 3e293825e..59b5cc2d8 100644 --- a/migen/corelogic/record.py +++ b/migen/corelogic/record.py @@ -2,9 +2,10 @@ from migen.fhdl.structure import * from migen.fhdl.structure import _make_signal_name class Record: - def __init__(self, template, name=None): + def __init__(self, layout, name=None): 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[1], BV): 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])) else: raise TypeError + self.field_order.append(f[0]) else: setattr(self, f, Signal(BV(1), self.name + "_" + f)) + self.field_order.append(f) - def template(self): + def layout(self): l = [] - for key in sorted(self.__dict__): + for key in self.field_order: e = self.__dict__[key] if isinstance(e, Signal): l.append((key, e.bv)) elif isinstance(e, Record): - l.append((key, e.template())) + l.append((key, e.layout())) return l 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): - fields = {} + fields = [] for item in descr: path = item.split('/') last = path.pop() @@ -40,24 +43,19 @@ class Record: 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): + lu = list(filter(lambda x: x[0] == hop, pos_fields)) + pos_fields = lu[0][1] + except IndexError: + n = [] + pos_fields.append((hop, n)) + pos_fields = n + if not isinstance(pos_fields, list): raise ValueError - if last in pos_fields: + if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0: 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") + pos_fields.append((last, getattr(pos_self, last))) + print(fields) + return Record(fields, "subrecord") def compatible(self, other): tpl1 = self.flatten() @@ -66,7 +64,7 @@ class Record: def flatten(self): l = [] - for key in sorted(self.__dict__): + for key in self.field_order: e = self.__dict__[key] if isinstance(e, Signal): l.append(e) @@ -75,4 +73,4 @@ class Record: return l def __repr__(self): - return repr(self.template()) + return repr(self.layout()) diff --git a/migen/flow/composer.py b/migen/flow/composer.py index 3a8f00e67..d6a713a6a 100644 --- a/migen/flow/composer.py +++ b/migen/flow/composer.py @@ -14,7 +14,7 @@ def _simple_binary(a, b, actor_class): width = max(signal_self.bv.width, signal_other.bv.width) signed = signal_self.bv.signed and signal_other.bv.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, a.actor, combinator, a.endp, combinator.sinks()[0]) add_connection(a.dfg, b.actor, combinator, b.endp, combinator.sinks()[1]) diff --git a/migen/flow/plumbing.py b/migen/flow/plumbing.py index e55ddf982..e7f06efce 100644 --- a/migen/flow/plumbing.py +++ b/migen/flow/plumbing.py @@ -4,9 +4,9 @@ from migen.corelogic.record import * from migen.corelogic.misc import optree class Buffer(Actor): - def __init__(self, template): - self.d = Record(template) - self.q = Record(template) + def __init__(self, layout): + self.d = Record(layout) + self.q = Record(layout) Actor.__init__(self, SchedulingModel(SchedulingModel.PIPELINE, 1), self.d, self.q) @@ -18,8 +18,8 @@ class Buffer(Actor): return Fragment(sync=sync) class Combinator(Actor): - def __init__(self, template, *subrecords): - self.destination = Record(template) + def __init__(self, layout, *subrecords): + self.destination = Record(layout) self.ins = [self.destination.subrecord(*subr) for subr in subrecords] Actor.__init__(self, SchedulingModel(SchedulingModel.COMBINATORIAL), @@ -36,8 +36,8 @@ class Combinator(Actor): return Fragment(comb) class Splitter(Actor): - def __init__(self, template, *subrecords): - self.source = Record(template) + def __init__(self, layout, *subrecords): + self.source = Record(layout) self.outs = [self.source.subrecord(*subr) for subr in subrecords] Actor.__init__(self, SchedulingModel(SchedulingModel.COMBINATORIAL),