add bug #148 record
[ieee754fpu.git] / src / nmutil / stageapi.py
index 33fd995d22d6ad2ded3cda886ab2031d04323006..b709abd801d5b9c31aa574bcf32bc03c6bd788a0 100644 (file)
@@ -1,6 +1,7 @@
 """ Stage API
 
     Associated development bugs:
+    * http://bugs.libre-riscv.org/show_bug.cgi?id=148
     * http://bugs.libre-riscv.org/show_bug.cgi?id=64
     * http://bugs.libre-riscv.org/show_bug.cgi?id=57
 
@@ -77,6 +78,7 @@
     all the optional bits.
 """
 
+from nmigen import Elaboratable
 from abc import ABCMeta, abstractmethod
 import inspect
 
@@ -157,11 +159,11 @@ class StageHelper(Stage):
         if stage is not None:
             self.set_specs(self, self)
 
-    def ospec(self, name):
+    def ospec(self, name=None):
         assert self._ospecfn is not None
         return _spec(self._ospecfn, name)
 
-    def ispec(self, name):
+    def ispec(self, name=None):
         assert self._ispecfn is not None
         return _spec(self._ispecfn, name)
 
@@ -198,11 +200,12 @@ class StageHelper(Stage):
 
 
 class StageChain(StageHelper):
-    """ pass in a list of stages, and they will automatically be
-        chained together via their input and output specs into a
-        combinatorial chain, to create one giant combinatorial block.
+    """ pass in a list of stages (combinatorial blocks), and they will
+        automatically be chained together via their input and output specs
+        into a combinatorial chain, to create one giant combinatorial
+        block.
 
-        the end result basically conforms to the exact same Stage API.
+        the end result conforms to the exact same Stage API.
 
         * input to this class will be the input of the first stage
         * output of first stage goes into input of second
@@ -213,7 +216,7 @@ class StageChain(StageHelper):
         NOTE: whilst this is very similar to ControlBase.connect(), it is
         *really* important to appreciate that StageChain is pure
         combinatorial and bypasses (does not involve, at all, ready/valid
-        signalling of any kind).
+        signalling OF ANY KIND).
 
         ControlBase.connect on the other hand respects, connects, and uses
         ready/valid signalling.
@@ -231,7 +234,7 @@ class StageChain(StageHelper):
                          "driving from two sources, module is being flattened"
                          will be issued.
 
-        NOTE: do NOT use StageChain with combinatorial blocks that have
+        NOTE: DO NOT use StageChain with combinatorial blocks that have
         side-effects (state-based / clock-based input) or conditional
         (inter-chain) dependencies, unless you really know what you are doing.
     """
@@ -239,7 +242,10 @@ class StageChain(StageHelper):
         assert len(chain) > 0, "stage chain must be non-zero length"
         self.chain = chain
         StageHelper.__init__(self, None)
-        self.setup = self._sa_setup if specallocate else self._na_setup
+        if specallocate:
+            self.setup = self._sa_setup
+        else:
+            self.setup = self._na_setup
         self.set_specs(self.chain[0], self.chain[-1])
 
     def _sa_setup(self, m, i):
@@ -247,7 +253,10 @@ class StageChain(StageHelper):
             if hasattr(c, "setup"):
                 c.setup(m, i)               # stage may have some module stuff
             ofn = self.chain[idx].ospec     # last assignment survives
-            o = _spec(ofn, 'chainin%d' % idx)
+            cname = 'chainin%d' % idx
+            o = _spec(ofn, cname)
+            if isinstance(o, Elaboratable):
+                setattr(m.submodules, cname, o)
             m.d.comb += nmoperator.eq(o, c.process(i)) # process input into "o"
             if idx == len(self.chain)-1:
                 break