genlib/record: support abstract signal width
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 27 Jul 2013 20:18:06 +0000 (22:18 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 27 Jul 2013 20:18:06 +0000 (22:18 +0200)
migen/genlib/record.py

index d2d355ce2e228db83c6ac1218f2691161adb8b44..10e3a43cf186714954b53a01bf8a6dbce9c4289c 100644 (file)
@@ -11,19 +11,21 @@ from migen.genlib.misc import optree
 # size can be an int, or a (int, bool) tuple for signed numbers
 # sublayout must be a list
 
-def layout_len(layout):
+def layout_len(layout, **layout_dict):
        r = 0
        for f in layout:
-               if isinstance(f[1], (int, tuple)): # cases 1/2
+               if isinstance(f[1], (int, tuple, str)): # cases 1/2
                        if(len(f) == 3):
                                fname, fsize, fdirection = f
                        else:
                                fname, fsize = f
                elif isinstance(f[1], list): # case 3
                        fname, fsublayout = f
-                       fsize = layout_len(fsublayout)
+                       fsize = layout_len(fsublayout, **layout_dict)
                else:
                        raise TypeError
+               if isinstance(fsize, str):
+                       fsize = layout_dict[fsize]
                if isinstance(fsize, tuple):
                        r += fsize[0]
                else:
@@ -55,20 +57,23 @@ def layout_partial(layout, *elements):
        return r
 
 class Record:
-       def __init__(self, layout, name=None):
+       def __init__(self, layout, name=None, **layout_dict):
                self.name = get_obj_var_name(name, "")
                self.layout = layout
+               self.layout_dict = layout_dict
 
                if self.name:
                        prefix = self.name + "_"
                else:
                        prefix = ""
                for f in self.layout:
-                       if isinstance(f[1], (int, tuple)): # cases 1/2
+                       if isinstance(f[1], (int, tuple, str)): # cases 1/2
                                if(len(f) == 3):
                                        fname, fsize, fdirection = f
                                else:
                                        fname, fsize = f
+                               if isinstance(fsize, str):
+                                       fsize = layout_dict[fsize]
                                finst = Signal(fsize, name=prefix + fname)
                        elif isinstance(f[1], list): # case 3
                                fname, fsublayout = f
@@ -139,7 +144,7 @@ class Record:
                return r
 
        def __len__(self):
-               return layout_len(self.layout)
+               return layout_len(self.layout, **self.layout_dict)
 
        def __repr__(self):
                return "<Record " + ":".join(f[0] for f in self.layout) + " at " + hex(id(self)) + ">"