clarify whats being obtained from _connect_out function
[ieee754fpu.git] / src / nmutil / singlepipe.py
index 90a3a06fde2206aebfd795679db63af5c7ec9ef5..e109900dc876faccf3040a745f45a5182f696321 100644 (file)
@@ -4,7 +4,16 @@
     * http://bugs.libre-riscv.org/show_bug.cgi?id=64
     * http://bugs.libre-riscv.org/show_bug.cgi?id=57
 
-    Important: see Stage API (stageapi.py) in combination with below
+    Important: see Stage API (stageapi.py) and IO Control API
+    (iocontrol.py) in combination with below.  This module
+    "combines" the Stage API with the IO Control API to create
+    the Pipeline API.
+
+    The one critically important key difference between StageAPI and
+    PipelineAPI:
+
+        * StageAPI: combinatorial (NO REGISTERS / LATCHES PERMITTED)
+        * PipelineAPI: synchronous registers / latches get added here
 
     RecordBasedStage:
     ----------------
@@ -489,7 +498,7 @@ class MaskCancellable(ControlBase):
     def elaborate(self, platform):
         self.m = m = ControlBase.elaborate(self, platform)
 
-        r_mask = Signal(len(self.p.mask_i), reset_less=True)
+        mask_r = Signal(len(self.p.mask_i), reset_less=True)
         data_r = _spec(self.stage.ospec, "data_r")
         m.d.comb += nmoperator.eq(data_r, self._postprocess(self.data_r))
 
@@ -516,8 +525,8 @@ class MaskCancellable(ControlBase):
             # register is left as-is if idmask is zero, but out-mask is set to
             # zero
             # note however: only the *uncancelled* mask bits get passed on
-            m.d.sync += r_mask.eq(Mux(p_valid_i, maskedout, 0))
-            m.d.comb += self.n.mask_o.eq(r_mask)
+            m.d.sync += mask_r.eq(Mux(p_valid_i, maskedout, 0))
+            m.d.comb += self.n.mask_o.eq(mask_r)
 
             # always pass on stop (as combinatorial: single signal)
             m.d.comb += self.n.stop_o.eq(self.p.stop_i)
@@ -545,7 +554,9 @@ class MaskCancellable(ControlBase):
         with m.Else():
             # pass everything straight through.  p connected to n: data,
             # valid, mask, everything.  this is "effectively" just a
-            # StageChain (except now dynamically selectable)
+            # StageChain: MaskCancellable is doing "nothing" except
+            # combinatorially passing everything through
+            # (except now it's *dynamically selectable* whether to do that)
             m.d.comb += self.n.valid_o.eq(self.p.valid_i_test)
             m.d.comb += self.p._ready_o.eq(self.n.ready_i_test)
             m.d.comb += self.n.stop_o.eq(self.p.stop_i)
@@ -940,14 +951,14 @@ class FIFOControl(ControlBase):
         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)
+        valid_eq, ready_eq, data_o = connections
 
         # 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[:2] # combinatorial on next ready/valid
+            m.d.comb += [valid_eq, ready_eq] # combinatorial on next ready/valid
         else:
-            m.d.sync += connections[:2]  # non-fwft mode needs sync
-        data_o = connections[2] # get the data
+            m.d.sync += [valid_eq, ready_eq] # non-fwft mode needs sync
         data_o = self._postprocess(data_o) # XXX TBD, does nothing right now
         m.d.comb += data_o