from nmigen.cli import verilog, rtlil
from nmigen.hdl.rec import Record, Layout
+from abc import ABCMeta, abstractmethod
from collections.abc import Sequence
return res
-class StageChain:
+class StageCls(metaclass=ABCMeta):
+ """ Class-based "Stage" API. requires instantiation (after derivation)
+ see "Stage API" above.
+ """
+ @abstractmethod
+ def ispec(self): pass # REQUIRED
+ @abstractmethod
+ def ospec(self): pass # REQUIRED
+ #@abstractmethod
+ #def setup(self, m, i): pass # OPTIONAL
+ @abstractmethod
+ def process(self, i): pass # REQUIRED
+
+
+class Stage(metaclass=ABCMeta):
+ """ Static "Stage" API. does not require instantiation (after derivation)
+ see "Stage API" above
+ """
+ @staticmethod
+ @abstractmethod
+ def ispec(): pass
+
+ @staticmethod
+ @abstractmethod
+ def ospec(): pass
+
+ #@staticmethod
+ #@abstractmethod
+ #def setup(m, i): pass
+
+ @staticmethod
+ @abstractmethod
+ def process(i): pass
+
+
+class StageChain(StageCls):
""" pass in a list of stages, and they will automatically be
chained together via their input and output specs into a
combinatorial chain.
return self.o
-class PipelineBase:
+class ControlBase:
""" Common functions for Pipeline API
"""
def __init__(self, stage=None, in_multi=None):
]
-class BufferedPipeline(PipelineBase):
+class BufferedPipeline(ControlBase):
""" buffered pipeline stage. data and strobe signals travel in sync.
if ever the input is ready and the output is not, processed data
is stored in a temporary register.
"""
def __init__(self, stage):
- PipelineBase.__init__(self, stage)
+ ControlBase.__init__(self)
+ self.stage = stage
# set up the input and output data
self.p.i_data = stage.ispec() # input type
return m
-class ExampleAddStage:
+class ExampleAddStage(StageCls):
""" an example of how to use the buffered pipeline, as a class instance
"""
BufferedPipeline.__init__(self, addstage)
-class ExampleStage:
+class ExampleStage(Stage):
""" an example of how to use the buffered pipeline, in a static class
fashion
"""
return i + 1
-class ExampleStageCls:
+class ExampleStageCls(StageCls):
""" an example of how to use the buffered pipeline, in a static class
fashion
"""
BufferedPipeline.__init__(self, ExampleStage)
-class UnbufferedPipeline(PipelineBase):
+class UnbufferedPipeline(ControlBase):
""" A simple pipeline stage with single-clock synchronisation
and two-way valid/ready synchronised signalling.
"""
def __init__(self, stage):
- PipelineBase.__init__(self, stage)
+ ControlBase.__init__(self)
+ self.stage = stage
self._data_valid = Signal()
# set up the input and output data