update comments
[ieee754fpu.git] / src / add / singlepipe.py
index 3675ea90d75f8e854c7e6d657196605e98ccb39a..68b62e432d4fc6022b99361c3358d01638414fce 100644 (file)
@@ -198,13 +198,12 @@ class ControlBase(StageHelper, Elaboratable):
 
         # set up the input and output data
         if stage is not None:
-            self._new_data(self, self, "data")
+            self._new_data("data")
 
-    def _new_data(self, p, n, name):
+    def _new_data(self, name):
         """ allocates new data_i and data_o
         """
-        self.p.data_i = _spec(p.stage.ispec, "%s_i" % name)
-        self.n.data_o = _spec(n.stage.ospec, "%s_o" % name)
+        self.p.data_i, self.n.data_o = self.new_specs(name)
 
     @property
     def data_r(self):
@@ -280,9 +279,10 @@ class ControlBase(StageHelper, Elaboratable):
         # connect front and back of chain to ourselves
         front = pipechain[0]                # first in chain
         end = pipechain[-1]                 # last in chain
-        self._new_data(front, end, "chain") # NOTE: REPLACES existing data
+        self.set_specs(front, end) # sets up ispec/ospec functions
+        self._new_data("chain") # NOTE: REPLACES existing data
         eqs += front._connect_in(self)      # front p to our p
-        eqs += end._connect_out(self)       # end n   to out n
+        eqs += end._connect_out(self)       # end n   to our n
 
         return eqs
 
@@ -735,14 +735,20 @@ class FIFOControl(ControlBase):
                                      fwft=True, pipe=False):
         """ FIFO Control
 
-            * :depth:    number of entries in the FIFO
-            * :stage:    data processing block
-            * :fwft:     first word fall-thru mode (non-fwft introduces delay)
-            * :buffered: use buffered FIFO (introduces extra cycle delay)
+            * :depth: number of entries in the FIFO
+            * :stage: data processing block
+            * :fwft:  first word fall-thru mode (non-fwft introduces delay)
+            * :pipe:  specifies pipe mode.
 
-            NOTE 1: FPGAs may have trouble with the defaults for SyncFIFO
-                    (fwft=True, buffered=False).  XXX TODO: fix this by
-                    using Queue in all cases instead.
+            when fwft = True it indicates that transfers may occur
+            combinatorially through stage processing in the same clock cycle.
+            This requires that the Stage be a Moore FSM:
+            https://en.wikipedia.org/wiki/Moore_machine
+
+            when fwft = False it indicates that all output signals are
+            produced only from internal registers or memory, i.e. that the
+            Stage is a Mealy FSM:
+            https://en.wikipedia.org/wiki/Mealy_machine
 
             data is processed (and located) as follows:
 
@@ -766,27 +772,29 @@ class FIFOControl(ControlBase):
         fifo = Queue(fwidth, self.fdepth, fwft=self.fwft, pipe=self.pipe)
         m.submodules.fifo = fifo
 
-        # store result of processing in combinatorial temporary
-        result = _spec(self.stage.ospec, "r_temp")
-        m.d.comb += nmoperator.eq(result, self.data_r)
+        def processfn(data_i):
+            # store result of processing in combinatorial temporary
+            result = _spec(self.stage.ospec, "r_temp")
+            m.d.comb += nmoperator.eq(result, self.process(data_i))
+            return nmoperator.cat(result)
+
+        ## prev: make the FIFO (Queue object) "look" like a PrevControl...
+        m.submodules.fp = fp = PrevControl()
+        fp.valid_i, fp._ready_o, fp.data_i = fifo.we, fifo.writable, fifo.din
+        m.d.comb += fp._connect_in(self.p, fn=processfn)
+
+        # next: make the FIFO (Queue object) "look" like a NextControl...
+        m.submodules.fn = fn = NextControl()
+        fn.valid_o, fn.ready_i, fn.data_o  = fifo.readable, fifo.re, fifo.dout
+        connections = fn._connect_out(self.n, fn=nmoperator.cat)
 
-        # connect previous rdy/valid/data - do cat on data_i
-        # NOTE: cannot do the PrevControl-looking trick because
-        # of need to process the data.  shaaaame....
-        m.d.comb += [fifo.we.eq(self.p.valid_i_test),
-                     self.p.ready_o.eq(fifo.writable),
-                     nmoperator.eq(fifo.din, nmoperator.cat(result)),
-                   ]
-
-        # connect next rdy/valid/data - do cat on data_o (further below)
-        connections = [self.n.valid_o.eq(fifo.readable),
-                       fifo.re.eq(self.n.ready_i_test),
-                      ]
+        # ok ok so we can't just do the ready/valid eqs straight:
+        # first 2 from connections are the ready/valid, 3rd is data.
         if self.fwft:
-            m.d.comb += connections # combinatorial on next ready/valid
+            m.d.comb += connections[:2] # combinatorial on next ready/valid
         else:
-            m.d.sync += connections # unbuffered fwft mode needs sync
-        data_o = nmoperator.cat(self.n.data_o).eq(fifo.dout)
+            m.d.sync += connections[:2]  # non-fwft mode needs sync
+        data_o = connections[2] # get the data
         data_o = self._postprocess(data_o) # XXX TBD, does nothing right now
         m.d.comb += data_o