add new Parts class
[ieee754fpu.git] / src / nmutil / iocontrol.py
index af46d25ab5171b4b0db964887199c7ce7ff6362a..2f8c9ccfaf6d5f4df4f5bf4344a057fe09e49cb8 100644 (file)
@@ -171,8 +171,12 @@ class PrevControl(Elaboratable):
         * data_i : an input - MUST be added by the USER of this class
     """
 
-    def __init__(self, i_width=1, stage_ctl=False):
+    def __init__(self, i_width=1, stage_ctl=False, maskwid=0, offs=0):
         self.stage_ctl = stage_ctl
+        self.maskwid = maskwid
+        if maskwid:
+            self.mask_i = Signal(maskwid)                # prev   >>in  self
+            self.stop_i = Signal(maskwid)                # prev   >>in  self
         self.valid_i = Signal(i_width, name="p_valid_i") # prev   >>in  self
         self._ready_o = Signal(name="p_ready_o")         # prev   <<out self
         self.data_i = None # XXX MUST BE ADDED BY USER
@@ -188,13 +192,18 @@ class PrevControl(Elaboratable):
             return self.s_ready_o # set dynamically by stage
         return self._ready_o      # return this when not under dynamic control
 
-    def _connect_in(self, prev, direct=False, fn=None, do_data=True):
+    def _connect_in(self, prev, direct=False, fn=None,
+                    do_data=True, do_stop=True):
         """ internal helper function to connect stage to an input source.
             do not use to connect stage-to-stage!
         """
         valid_i = prev.valid_i if direct else prev.valid_i_test
         res = [self.valid_i.eq(valid_i),
                prev.ready_o.eq(self.ready_o)]
+        if self.maskwid:
+            res.append(self.mask_i.eq(prev.mask_i))
+            if do_stop:
+                res.append(self.stop_i.eq(prev.stop_i))
         if do_data is False:
             return res
         data_i = fn(prev.data_i) if fn is not None else prev.data_i
@@ -224,13 +233,19 @@ class PrevControl(Elaboratable):
         return m
 
     def eq(self, i):
-        return [nmoperator.eq(self.data_i, i.data_i),
+        res = [nmoperator.eq(self.data_i, i.data_i),
                 self.ready_o.eq(i.ready_o),
                 self.valid_i.eq(i.valid_i)]
+        if self.maskwid:
+            res.append(self.mask_i.eq(i.mask_i))
+        return res
 
     def __iter__(self):
         yield self.valid_i
         yield self.ready_o
+        if self.maskwid:
+            yield self.mask_i
+            yield self.stop_i
         if hasattr(self.data_i, "ports"):
             yield from self.data_i.ports()
         elif isinstance(self.data_i, Sequence):
@@ -248,8 +263,12 @@ class NextControl(Elaboratable):
         * ready_i: input from next stage indicating that it can accept data
         * data_o : an output - MUST be added by the USER of this class
     """
-    def __init__(self, stage_ctl=False):
+    def __init__(self, stage_ctl=False, maskwid=0):
         self.stage_ctl = stage_ctl
+        self.maskwid = maskwid
+        if maskwid:
+            self.mask_o = Signal(maskwid)       # self out>>  next
+            self.stop_o = Signal(maskwid)       # self out>>  next
         self.valid_o = Signal(name="n_valid_o") # self out>>  next
         self.ready_i = Signal(name="n_ready_i") # self <<in   next
         self.data_o = None # XXX MUST BE ADDED BY USER
@@ -263,24 +282,37 @@ class NextControl(Elaboratable):
             return self.ready_i & self.d_valid
         return self.ready_i
 
-    def connect_to_next(self, nxt, do_data=True):
+    def connect_to_next(self, nxt, do_data=True, do_stop=True):
         """ helper function to connect to the next stage data/valid/ready.
             data/valid is passed *TO* nxt, and ready comes *IN* from nxt.
             use this when connecting stage-to-stage
+
+            note: a "connect_from_prev" is completely unnecessary: it's
+            just nxt.connect_to_next(self)
         """
         res = [nxt.valid_i.eq(self.valid_o),
                self.ready_i.eq(nxt.ready_o)]
+        if self.maskwid:
+            res.append(nxt.mask_i.eq(self.mask_o))
+            if do_stop:
+                res.append(nxt.stop_i.eq(self.stop_o))
         if do_data:
             res.append(nmoperator.eq(nxt.data_i, self.data_o))
+        print ("connect to next", self, self.maskwid, nxt.data_i, do_data, do_stop)
         return res
 
-    def _connect_out(self, nxt, direct=False, fn=None, do_data=True):
+    def _connect_out(self, nxt, direct=False, fn=None,
+                     do_data=True, do_stop=True):
         """ internal helper function to connect stage to an output source.
             do not use to connect stage-to-stage!
         """
         ready_i = nxt.ready_i if direct else nxt.ready_i_test
         res = [nxt.valid_o.eq(self.valid_o),
                self.ready_i.eq(ready_i)]
+        if self.maskwid:
+            res.append(nxt.mask_o.eq(self.mask_o))
+            if do_stop:
+                res.append(nxt.stop_o.eq(self.stop_o))
         if not do_data:
             return res
         data_o = fn(nxt.data_o) if fn is not None else nxt.data_o
@@ -294,6 +326,9 @@ class NextControl(Elaboratable):
     def __iter__(self):
         yield self.ready_i
         yield self.valid_o
+        if self.maskwid:
+            yield self.mask_o
+            yield self.stop_o
         if hasattr(self.data_o, "ports"):
             yield from self.data_o.ports()
         elif isinstance(self.data_o, Sequence):