fhdl/autofragment: FModule
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 2 Mar 2013 22:30:54 +0000 (23:30 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 2 Mar 2013 22:30:54 +0000 (23:30 +0100)
migen/fhdl/autofragment.py

index 50e7bc379202edaa68dd09bbc13f34c39d4d0c6f..bbc72446b066fd7123926cf7fb883a50a6648bfd 100644 (file)
@@ -18,3 +18,86 @@ def from_attributes(obj):
                if hasattr(x, "get_fragment"):
                        f += x.get_fragment()
        return f
+
+class _FModuleProxy:
+       def __init__(self, fm):
+               object.__setattr__(self, "_fm", fm)
+
+class _FModuleComb(_FModuleProxy):
+       def __iadd__(self, other):
+               if isinstance(other, (list, tuple)):
+                       self._fm._fragment.comb += other
+               else:
+                       self._fm._fragment.comb.append(other)
+               return self
+
+def _cd_append(d, key, statements):
+       try:
+               l = d[key]
+       except KeyError:
+               l = []
+               d[key] = l
+       if isinstance(statements, (list, tuple)):
+               l += other
+       else:
+               l.append(statements)
+
+class _FModuleSyncCD:
+       def __init__(self, fm, cd):
+               self._fm = fm
+               self._cd = cd
+
+       def __iadd__(self, other):
+               _cd_append(self._fm._fragment.sync, self._cd, other)
+               return self
+
+class _FModuleSync(_FModuleProxy):
+       def __iadd__(self, other):
+               _cd_append(self._fm._fragment.sync, "sys", other)
+               return self
+
+       def __getattr__(self, name):
+               return _FModuleSyncCD(self._fm, name)
+
+       def __setattr__(self, name, value):
+               if not isinstance(value, _FModuleSyncCD):
+                       raise AttributeError("Attempted to assign sync property - use += instead")
+
+class _FModuleSpecials(_FModuleProxy):
+       def __iadd__(self, other):
+               if isinstance(other, (set, list, tuple)):
+                       self._fm._fragment.specials |= set(other)
+               else:
+                       self._fm._fragment.specials.add(other)
+               return self
+
+class FModule:
+       def do_simulation(self, s):
+               pass
+
+       def get_fragment(self):
+               assert(not hasattr(self, "_fragment"))
+               self._fragment = Fragment(sim=[self.do_simulation])
+               self.build_fragment()
+               self._fragment += from_attributes(self)
+               return self._fragment
+
+       def __getattr__(self, name):
+               if name == "comb":
+                       return _FModuleComb(self)
+               elif name == "sync":
+                       return _FModuleSync(self)
+               elif name == "specials":
+                       return _FModuleSpecials(self)
+               else:
+                       raise AttributeError
+
+       def __setattr__(self, name, value):
+               if name in ["comb", "sync", "specials"]:
+                       if not isinstance(value, _FModuleProxy):
+                               raise AttributeError("Attempted to assign special FModule property - use += instead")
+               else:
+                       object.__setattr__(self, name, value)
+
+       def build_fragment(self):
+               raise NotImplementedError("FModule.build_fragment needs to be overloaded")