start on ObjectProxy example
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 1 Apr 2019 00:23:39 +0000 (01:23 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 1 Apr 2019 00:23:39 +0000 (01:23 +0100)
src/add/pipeline.py
src/add/pipeline_example.py

index e4be410099906edb1bd13406930899296399d32c..7df6a67dc32352c776fe33c0afb4740983f28663 100644 (file)
@@ -21,7 +21,7 @@ from singlepipe import UnbufferedPipeline
 
 def like(value, rname, pipe):
     if isinstance(value, ObjectProxy):
-        return ObjectProxy.like(pipe, value, name=rname, reset_less=True)
+        return ObjectProxy.like(None, value, name=rname, reset_less=True)
     else:
         return Signal(value_bits_sign(value), name=rname,
                              reset_less=True)
@@ -29,19 +29,20 @@ def like(value, rname, pipe):
 
 
 class ObjectProxy:
-    def __init__(self, pipe, name=None):
-        self._pipe = pipe
+    def __init__(self, m, name=None, pipemode=False):
+        self._m = m
         if name is None:
             name = tracer.get_var_name(default=None)
         self.name = name
+        self._pipemode = pipemode
 
     @classmethod
-    def like(cls, pipe, value, name=None, src_loc_at=0, **kwargs):
+    def like(cls, m, value, name=None, src_loc_at=0, **kwargs):
         name = name or tracer.get_var_name(depth=2 + src_loc_at,
                                             default="$like")
 
         src_loc_at_1 = 1 + src_loc_at
-        r = ObjectProxy(pipe, value.name)
+        r = ObjectProxy(m, value.name)
         for a in value.ports():
             aname = a.name
             setattr(r, aname, a)
@@ -71,10 +72,10 @@ class ObjectProxy:
             return
         #rname = "%s_%s" % (self.name, name)
         rname = name
-        new_pipereg = like(value, rname, self._pipe)
+        new_pipereg = like(value, rname, self._m)
         object.__setattr__(self, name, new_pipereg)
-        if self._pipe:
-            self._pipe.sync += eq(new_pipereg, value)
+        if self._m:
+            self._m.d.sync += eq(new_pipereg, value)
 
 
 class PipelineStage:
@@ -208,8 +209,8 @@ class SimplePipeline:
     """ Pipeline builder with auto generation of pipeline registers.
     """
 
-    def __init__(self, pipe):
-        self._pipe = pipe
+    def __init__(self, m):
+        self._m = m
         self._pipeline_register_map = {}
         self._current_stage_num = 0
 
@@ -242,12 +243,12 @@ class SimplePipeline:
         #new_pipereg = Signal(value_bits_sign(value), name=rname,
         #                     reset_less=True)
         if isinstance(value, ObjectProxy):
-            new_pipereg = ObjectProxy.like(self._pipe, value,
+            new_pipereg = ObjectProxy.like(self._m, value,
                                            name=rname, reset_less = True)
         else:
             new_pipereg = Signal.like(value, name=rname, reset_less = True)
         if next_stage not in self._pipeline_register_map:
             self._pipeline_register_map[next_stage] = {}
         self._pipeline_register_map[next_stage][name] = new_pipereg
-        self._pipe.sync += eq(new_pipereg, value)
+        self._m.d.sync += eq(new_pipereg, value)
 
index 0d060da31bf53379ce328b8efe8dd2ec9810b8d3..86bc8549bbeec06cc966c3227c0706daa4860cd2 100644 (file)
@@ -36,10 +36,10 @@ class SimplePipelineExample(SimplePipeline):
 class ObjectBasedPipelineExample(SimplePipeline):
     """ A very simple pipeline to show how registers are inferred. """
 
-    def __init__(self, pipe):
-        SimplePipeline.__init__(self, pipe)
+    def __init__(self, m):
+        SimplePipeline.__init__(self, m)
         self._loopback = Signal(4)
-        o = ObjectProxy(pipe)
+        o = ObjectProxy(m)
         o.a = Signal(4)
         o.b = Signal(4)
         self._obj = o
@@ -51,16 +51,16 @@ class ObjectBasedPipelineExample(SimplePipeline):
 
     def stage1(self):
         self.n = self.n + self.o.a
-        o = ObjectProxy(self._pipe)
+        o = ObjectProxy(self._m)
         o.a = self.n
         o.b = self.o.b
         self.o = o
 
     def stage2(self):
         localv = Signal(4)
-        self._pipe.comb += localv.eq(2)
+        self._m.d.comb += localv.eq(2)
         self.n = self.n << localv
-        o = ObjectProxy(self._pipe)
+        o = ObjectProxy(self._m)
         o.b = self.n + self.o.a + self.o.b
         self.o = o
 
@@ -70,14 +70,14 @@ class ObjectBasedPipelineExample(SimplePipeline):
         self.o.b = self.o.b + self.n
 
     def stage4(self):
-        self._pipe.sync += self._loopback.eq(self.n + 3 + self.o.b)
+        self._m.d.sync += self._loopback.eq(self.n + 3 + self.o.b)
 
 
 class PipeModule:
 
     def __init__(self):
         self.m = Module()
-        self.p = ObjectBasedPipelineExample(self.m.d)
+        self.p = ObjectBasedPipelineExample(self.m)
 
     def get_fragment(self, platform=None):
         return self.m
@@ -109,6 +109,46 @@ class PipelineStageExample:
 
         return m
 
+class PipelineStageObjectExample:
+
+    def __init__(self):
+        self._loopback = Signal(4)
+
+    def get_fragment(self, platform=None):
+
+        m = Module()
+
+        o = ObjectProxy(None)
+        o.a = Signal(4)
+        o.b = Signal(4)
+        self._obj = o
+
+        with PipeManager(m, pipemode=True) as pipe:
+
+            with pipe.Stage("first",
+                            ispec=[self._loopback, self._obj]) as (p, m):
+                p.n = ~self._loopback
+                p.o = self._obj
+            with pipe.Stage("second", p) as (p, m):
+                #p.n = ~self._loopback + 2
+                p.n = p.n + 2
+                o = ObjectProxy(None)
+                o.a = p.n
+                o.b = p.o.b
+                p.o = o
+            with pipe.Stage("third", p) as (p, m):
+                #p.n = ~self._loopback + 5
+                localv = Signal(4)
+                m.d.comb += localv.eq(2)
+                p.n = p.n << localv
+                o = ObjectProxy(None)
+                o.b = p.n + p.o.a + p.o.b
+                p.o = o
+
+        print (pipe.stages)
+
+        return m
+
 
 
 if __name__ == "__main__":
@@ -122,3 +162,8 @@ if __name__ == "__main__":
         f.write(rtlil.convert(example, ports=[
                example._loopback,
              ]))
+    example = PipelineStageObjectExample()
+    with open("pipe_stage_object_module.il", "w") as f:
+        f.write(rtlil.convert(example, ports=[
+               example._loopback,
+             ]))