semi-working, top-level signals okay, ObjectProxy not yet connected
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 3 Apr 2019 04:01:45 +0000 (05:01 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 3 Apr 2019 04:01:45 +0000 (05:01 +0100)
src/add/pipeline.py
src/add/pipeline_example.py

index e3983e3add8a6379b671ef97c7ac5f2a84dabcc5..1f3d0942bc0a107b7453d025112b707669e44386 100644 (file)
@@ -81,6 +81,15 @@ class ObjectProxy:
             subobjs.append(repr(ai))
         return "<OP %s>" % subobjs
 
+    def get_specs(self, liked=False):
+        res = []
+        for k, v in self._preg_map.items():
+            #v = like(v, k, stage._m)
+            res.append(v)
+            if isinstance(v, ObjectProxy):
+                res += v.get_specs()
+        return res
+
     def eq(self, i):
         print ("ObjectProxy eq", self, i)
         res = []
@@ -121,7 +130,6 @@ class ObjectProxy:
         #object.__setattr__(self, name, new_pipereg)
         if self._pipemode:
             print ("OP pipemode", new_pipereg, value)
-            #self._eqs.append(value)
             #self._m.d.comb += eq(new_pipereg, value)
             pass
         elif self._m:
@@ -130,6 +138,11 @@ class ObjectProxy:
         else:
             print ("OP !pipemode !m", new_pipereg, value, type(value))
             self._assigns += eq(new_pipereg, value)
+            #self._eqs.append(new_pipereg)
+            if isinstance(value, ObjectProxy):
+                print ("OP, defer assigns:", value._assigns)
+                self._assigns += value._assigns
+                self._eqs.append(value._eqs)
 
 
 class PipelineStage:
@@ -182,13 +195,13 @@ class PipelineStage:
             self._preg_map[next_stage] = {}
         self._preg_map[next_stage][name] = new_pipereg
         if self._pipemode:
-            self._eqs.append(value)
+            self._eqs.append(new_pipereg)
             assign = eq(new_pipereg, value)
             print ("pipemode: append", new_pipereg, value, assign)
             if isinstance(value, ObjectProxy):
                 print ("OP, assigns:", value._assigns)
                 self._assigns += value._assigns
-                #self._eqs += value._eqs
+                self._eqs += value._eqs
             #self._m.d.comb += assign
             self._assigns += assign
         elif self._m:
@@ -209,6 +222,7 @@ def likelist(specs):
         res.append(like(v, v.name, None, pipemode=True))
     return res
 
+
 class AutoStage(StageCls):
     def __init__(self, inspecs, outspecs, eqs, assigns):
         self.inspecs, self.outspecs = inspecs, outspecs
@@ -219,13 +233,16 @@ class AutoStage(StageCls):
 
     def process(self, i):
         print ("stage process", i)
-        return self.eqs
+        return self.outspecs
 
     def setup(self, m, i):
-        #self.o = self.ospec()
-        m.d.comb += eq(self.inspecs, i)
-        print ("stage setup", i)
+        print ("stage setup i", i)
         print ("stage setup inspecs", self.inspecs)
+        print ("stage setup outspecs", self.outspecs)
+        print ("stage setup eqs", self.eqs)
+        #self.o = self.ospec()
+        m.d.comb += eq(self.eqs, i)
+        #m.d.comb += eq(self.outspecs, self.eqs)
         #m.d.comb += eq(self.o, i)
 
 
@@ -279,6 +296,8 @@ class PipeManager:
             for k, v in stage._preg_map[name].items():
                 #v = like(v, k, stage._m)
                 res.append(v)
+                #if isinstance(v, ObjectProxy):
+                #    res += v.get_specs()
             return res
         return []
 
index 74c1c5fdc090e99fb6f6a4bbf0f2706ac8ae1de7..922355d64522344322f77158ca4dadebd87ac75a 100644 (file)
@@ -52,8 +52,8 @@ class ObjectBasedPipelineExample(SimplePipeline):
     def stage1(self):
         self.n = self.n + self.o.a
         o = ObjectProxy(self._m)
-        o.a = self.n
-        o.b = self.o.b + self.n + Const(5)
+        o.c = self.n
+        o.d = self.o.b + self.n + Const(5)
         self.o = o
 
     def stage2(self):
@@ -61,16 +61,16 @@ class ObjectBasedPipelineExample(SimplePipeline):
         self._m.d.comb += localv.eq(2)
         self.n = self.n << localv
         o = ObjectProxy(self._m)
-        o.b = self.n + self.o.a + self.o.b
+        o.e = self.n + self.o.c + self.o.d
         self.o = o
 
     def stage3(self):
         self.n = ~self.n
         self.o = self.o
-        self.o.b = self.o.b + self.n
+        self.o.e = self.o.e + self.n
 
     def stage4(self):
-        self._m.d.sync += self._loopback.eq(self.n + 3 + self.o.b)
+        self._m.d.sync += self._loopback.eq(self.n + 3 + self.o.e)
 
 
 class PipeModule:
@@ -141,8 +141,8 @@ class PipelineStageObjectExample:
                 #p.n = ~self._loopback + 2
                 p.n = p.n + Const(2)
                 o = ObjectProxy(None, pipemode=False)
-                o.a = p.n
-                o.b = p.o.b + p.n + Const(5)
+                o.c = p.n
+                o.d = p.o.b + p.n + Const(5)
                 p.o = o
             with pipe.Stage("third", p) as (p, m):
                 #p.n = ~self._loopback + 5
@@ -150,7 +150,31 @@ class PipelineStageObjectExample:
                 m.d.comb += localv.eq(2)
                 p.n = p.n << localv
                 o = ObjectProxy(None, pipemode=False)
-                o.b = p.n + p.o.b + p.o.a
+                o.e = p.n + p.o.c + p.o.d
+                p.o = o
+
+        print ("stages", pipe.stages)
+
+        return m
+
+
+class PipelineStageObjectExample2:
+
+    def __init__(self):
+        self._loopback = Signal(4)
+
+    def get_fragment(self, platform=None):
+
+        m = Module()
+
+        ispec= [self._loopback]
+        with PipeManager(m, pipemode=True) as pipe:
+
+            with pipe.Stage("first",
+                            ispec=ispec) as (p, m):
+                p.n = ~self._loopback
+                o = ObjectProxy(None, pipemode=False)
+                o.b = ~self._loopback + Const(5)
                 p.o = o
 
         print ("stages", pipe.stages)