use stage names instead of numbers in the pipeline
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 30 Mar 2019 23:52:10 +0000 (23:52 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 30 Mar 2019 23:52:10 +0000 (23:52 +0000)
src/add/pipeline.py
src/add/pipeline_example.py

index c4afc9d862f7722bb3855da4b5d1e7585110fb0f..4cfe125948ec50ef3dfe0be55a473d7994cc3175 100644 (file)
@@ -74,38 +74,35 @@ class PipelineStage:
     """ Pipeline builder stage with auto generation of pipeline registers.
     """
 
-    def __init__(self, m, prev=None):
+    def __init__(self, name, m, prev=None):
         self._m = m
+        self._stagename = name
         self._preg_map = {}
         self._prev_stage = prev
         if prev:
             print ("prev", prev._preg_map)
-            if prev._current_stage_num in prev._preg_map:
-                m = prev._preg_map[prev._current_stage_num]
-                self._preg_map[prev._current_stage_num] = m
-            self._current_stage_num = prev._current_stage_num + 1
-            if self._current_stage_num in prev._preg_map:
-                m = prev._preg_map[self._current_stage_num]
-                self._preg_map[self._current_stage_num] = m
+            if prev._stagename in prev._preg_map:
+                m = prev._preg_map[prev._stagename]
+                self._preg_map[prev._stagename] = m
+            if '__nextstage__' in prev._preg_map:
+                m = prev._preg_map['__nextstage__']
+                self._preg_map[self._stagename] = m
                 print ("make current", m)
-        else:
-            self._current_stage_num = 0
 
     def __getattr__(self, name):
         try:
-            return self._preg_map[self._current_stage_num][name]
+            return self._preg_map[self._stagename][name]
         except KeyError:
             raise AttributeError(
                 'error, no pipeline register "%s" defined for stage %d'
-                % (name, self._current_stage_num))
+                % (name, self._stagename))
 
     def __setattr__(self, name, value):
         if name.startswith('_'):
             # do not do anything tricky with variables starting with '_'
             object.__setattr__(self, name, value)
             return
-        next_stage = self._current_stage_num + 1
-        pipereg_id = str(self._current_stage_num) + 'to' + str(next_stage)
+        pipereg_id = self._stagename
         rname = 'pipereg_' + pipereg_id + '_' + name
         #new_pipereg = Signal(value_bits_sign(value), name=rname,
         #                     reset_less=True)
@@ -114,6 +111,7 @@ class PipelineStage:
                                            name=rname, reset_less = True)
         else:
             new_pipereg = Signal.like(value, name=rname, reset_less = True)
+        next_stage = '__nextstage__'
         if next_stage not in self._preg_map:
             self._preg_map[next_stage] = {}
         self._preg_map[next_stage][name] = new_pipereg
@@ -125,8 +123,8 @@ class PipeManager:
         self.m = m
 
     @contextmanager
-    def Stage(self, prev=None):
-        stage = PipelineStage(self.m, prev)
+    def Stage(self, name, prev=None):
+        stage = PipelineStage(name, self.m, prev)
         try:
             yield stage, stage._m
         finally:
index e1806b302b5f81903c8db4de837cf3b6c4992637..e612bb0c0df05fab124a870b5015431b51377d9e 100644 (file)
@@ -109,11 +109,11 @@ class PipelineStageExample(PipeManager):
 
     def get_fragment(self, platform=None):
 
-        with self.Stage() as (p, m):
+        with self.Stage("first") as (p, m):
             p.n = ~self._loopback
-        with self.Stage(p) as (p, m):
+        with self.Stage("second", p) as (p, m):
             p.n = p.n + 2
-        with self.Stage(p) as (p, m):
+        with self.Stage("third", p) as (p, m):
             localv = Signal(4)
             m.d.comb += localv.eq(2)
             p.n = p.n << localv