Better record layout parameterization mechanism
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 23 Oct 2013 10:54:50 +0000 (12:54 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 23 Oct 2013 10:54:50 +0000 (12:54 +0200)
migen/bus/csr.py
migen/bus/wishbone.py
migen/genlib/record.py

index 699228bf4dc0657ca81be7280508032a96759703..14708fd03a594493d79878bba7f8274f44df0170 100644 (file)
@@ -13,7 +13,8 @@ _layout = [
 
 class Interface(Record):
        def __init__(self, data_width=8):
-               Record.__init__(self, _layout, data_width=data_width)
+               Record.__init__(self, set_layout_parameters(_layout,
+                       data_width=data_width))
 
 class Interconnect(Module):
        def __init__(self, master, slaves):
index c38bc6b3d38286918564943b97b9655276b43c01..af5ae5c048f773e977c8aef3bba399dc39ef3d56 100644 (file)
@@ -22,8 +22,9 @@ _layout = [
 
 class Interface(Record):
        def __init__(self, data_width=32):
-               Record.__init__(self, _layout, data_width=data_width,
-                       sel_width=data_width//8)
+               Record.__init__(self, set_layout_parameters(_layout,
+                       data_width=data_width,
+                       sel_width=data_width//8))
 
 class InterconnectPointToPoint(Module):
        def __init__(self, master, slave):
index 10e3a43cf186714954b53a01bf8a6dbce9c4289c..ebc4b9bfbe8355769adbc481d3575a770ed19b00 100644 (file)
@@ -11,21 +11,42 @@ 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, **layout_dict):
-       r = 0
+def set_layout_parameters(layout, **layout_dict):
+       def resolve(p):
+               if isinstance(p, str):
+                       try:
+                               return layout_dict[p]
+                       except KeyError:
+                               return p
+               else:
+                       return p
+
+       r = []
        for f in layout:
                if isinstance(f[1], (int, tuple, str)): # cases 1/2
-                       if(len(f) == 3):
+                       if len(f) == 3:
+                               r.append((f[0], resolve(f[1]), f[2]))
+                       else:
+                               r.append((f[0], resolve(f[1])))
+               elif isinstance(f[1], list): # case 3
+                       r.append((f[0], set_layout_parameters(f[1], **layout_dict)))
+               else:
+                       raise TypeError
+       return r
+
+def layout_len(layout):
+       r = 0
+       for f in layout:
+               if isinstance(f[1], (int, tuple)): # 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, **layout_dict)
+                       fsize = layout_len(fsublayout)
                else:
                        raise TypeError
-               if isinstance(fsize, str):
-                       fsize = layout_dict[fsize]
                if isinstance(fsize, tuple):
                        r += fsize[0]
                else:
@@ -57,23 +78,20 @@ def layout_partial(layout, *elements):
        return r
 
 class Record:
-       def __init__(self, layout, name=None, **layout_dict):
+       def __init__(self, layout, name=None):
                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, str)): # cases 1/2
+                       if isinstance(f[1], (int, tuple)): # 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
@@ -144,7 +162,7 @@ class Record:
                return r
 
        def __len__(self):
-               return layout_len(self.layout, **self.layout_dict)
+               return layout_len(self.layout)
 
        def __repr__(self):
                return "<Record " + ":".join(f[0] for f in self.layout) + " at " + hex(id(self)) + ">"