record: preserve order
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 9 Jan 2012 14:14:42 +0000 (15:14 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 9 Jan 2012 14:14:42 +0000 (15:14 +0100)
examples/using_record.py
migen/corelogic/record.py
migen/flow/composer.py
migen/flow/plumbing.py

index 0940715edda81e946e41de0d4190e549b9e8d5b5..0b61430c38473a863cb99990009826d036d48ec2 100644 (file)
@@ -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())
index 3e293825e0bcb0885bf0b10ff9ed90e12cebf4ca..59b5cc2d884fb0a26ee64b499de9c9849fb9d684 100644 (file)
@@ -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())
index 3a8f00e6747a8e1aa6f84b6793017d6e5c7bb2e5..d6a713a6a9f4dd108aa2ea531f8858c479bdeaea 100644 (file)
@@ -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])
index e55ddf9820fbcb03bc8936160a8ea62a5bef9f03..e7f06efcec40e466e7158c7ac0ceaede64240d27 100644 (file)
@@ -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),