move DynamicPipe to nmutil
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 14:31:05 +0000 (15:31 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 14:31:05 +0000 (15:31 +0100)
src/ieee754/pipeline.py
src/nmutil/dynamicpipe.py [new file with mode: 0644]

index 17cde15a721c6050eaa255bd44ab53290939ffc2..8a9c408ce1992d4f4c60e86190d0bec2c4c3238d 100644 (file)
@@ -1,11 +1,8 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 # See Notices.txt for copyright information
 
-from abc import ABCMeta
-from nmigen import Elaboratable
-
 from nmutil.singlepipe import SimpleHandshake
-import threading
+from nmutil.dynamicpipe import DynamicPipe, SimpleHandshakeRedir
 
 
 class PipelineSpec:
@@ -37,71 +34,3 @@ class PipelineSpec:
         self.fpformat = None
         self.n_comb_stages = None
 
-# with many thanks to jsbueno on stackexchange for this one
-# https://stackoverflow.com/questions/57273070/
-# list post:
-# http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-July/002259.html
-
-class Meta(ABCMeta):
-    registry = {}
-    recursing = threading.local()
-    recursing.check = False
-    mlock = threading.Lock()
-
-    def __call__(cls, *args, **kw):
-        mcls = cls.__class__
-        if mcls.recursing.check:
-            return super().__call__(*args, **kw)
-        spec = args[0]
-        base = spec.pipekls # pick up the dynamic class from PipelineSpec, HERE
-
-        if (cls, base) not in mcls.registry:
-            print ("__call__", args, kw, cls, base,
-                   base.__bases__, cls.__bases__)
-            mcls.registry[cls, base] = type(
-                cls.__name__,
-                (cls, base) + cls.__bases__[1:],
-                {}
-            )
-        real_cls = mcls.registry[cls, base]
-
-        with mcls.mlock:
-            mcls.recursing.check = True
-            instance = real_cls.__class__.__call__(real_cls, *args, **kw)
-            mcls.recursing.check = False
-        return instance
-
-
-# Inherit from this class instead of SimpleHandshake (or other ControlBase
-# derivative), and the metaclass will instead *replace* DynamicPipe -
-# *at runtime* - with the class that is specified *as a parameter*
-# in PipelineSpec.
-#
-# as explained in the list posting and in the stackexchange post, this is
-# needed to avoid a MASSIVE suite of duplicated multiple-inheritance classes
-# that "Mix in" SimpleHandshake (or other).
-#
-# unfortunately, composition does not work in this instance
-# (make an *instance* of SimpleHandshake or other class and pass it in)
-# due to the multiple level inheritance, and in several places
-# the inheriting class needs to do some setup that the deriving class
-# needs in order to function correctly.
-
-class DynamicPipe(metaclass=Meta):
-    def __init__(self, *args):
-        print ("DynamicPipe init", super(), args)
-        super().__init__(self, *args)
-
-
-# bad hack: the DynamicPipe metaclass ends up creating an __init__ signature
-# for the dynamically-derived class.  luckily, SimpleHandshake only needs
-# "self" as the 1st argument (it is its own "Stage").  anything else
-# could hypothetically be passed through the pspec.
-class SimpleHandshakeRedir(SimpleHandshake):
-    def __init__(self, mod, *args):
-        print ("redir", mod, args)
-        stage = self
-        if args and args[0].stage:
-            stage = args[0].stage
-        SimpleHandshake.__init__(self, stage)
-
diff --git a/src/nmutil/dynamicpipe.py b/src/nmutil/dynamicpipe.py
new file mode 100644 (file)
index 0000000..01a3f99
--- /dev/null
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# See Notices.txt for copyright information
+
+from abc import ABCMeta
+
+from nmutil.singlepipe import SimpleHandshake
+import threading
+
+# with many thanks to jsbueno on stackexchange for this one
+# https://stackoverflow.com/questions/57273070/
+# list post:
+# http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-July/002259.html
+
+class Meta(ABCMeta):
+    registry = {}
+    recursing = threading.local()
+    recursing.check = False
+    mlock = threading.Lock()
+
+    def __call__(cls, *args, **kw):
+        mcls = cls.__class__
+        if mcls.recursing.check:
+            return super().__call__(*args, **kw)
+        spec = args[0]
+        base = spec.pipekls # pick up the dynamic class from PipelineSpec, HERE
+
+        if (cls, base) not in mcls.registry:
+            print ("__call__", args, kw, cls, base,
+                   base.__bases__, cls.__bases__)
+            mcls.registry[cls, base] = type(
+                cls.__name__,
+                (cls, base) + cls.__bases__[1:],
+                {}
+            )
+        real_cls = mcls.registry[cls, base]
+
+        with mcls.mlock:
+            mcls.recursing.check = True
+            instance = real_cls.__class__.__call__(real_cls, *args, **kw)
+            mcls.recursing.check = False
+        return instance
+
+
+# Inherit from this class instead of SimpleHandshake (or other ControlBase
+# derivative), and the metaclass will instead *replace* DynamicPipe -
+# *at runtime* - with the class that is specified *as a parameter*
+# in PipelineSpec.
+#
+# as explained in the list posting and in the stackexchange post, this is
+# needed to avoid a MASSIVE suite of duplicated multiple-inheritance classes
+# that "Mix in" SimpleHandshake (or other).
+#
+# unfortunately, composition does not work in this instance
+# (make an *instance* of SimpleHandshake or other class and pass it in)
+# due to the multiple level inheritance, and in several places
+# the inheriting class needs to do some setup that the deriving class
+# needs in order to function correctly.
+
+class DynamicPipe(metaclass=Meta):
+    def __init__(self, *args):
+        print ("DynamicPipe init", super(), args)
+        super().__init__(self, *args)
+
+
+# bad hack: the DynamicPipe metaclass ends up creating an __init__ signature
+# for the dynamically-derived class.  luckily, SimpleHandshake only needs
+# "self" as the 1st argument (it is its own "Stage").  anything else
+# could hypothetically be passed through the pspec.
+class SimpleHandshakeRedir(SimpleHandshake):
+    def __init__(self, mod, *args):
+        print ("redir", mod, args)
+        stage = self
+        if args and args[0].stage:
+            stage = args[0].stage
+        SimpleHandshake.__init__(self, stage)
+