pass in flatten/processing function into _connect_in/out
[ieee754fpu.git] / src / add / singlepipe.py
index caaedae104501edc47857478ca23fa46fc9206b9..8296bf2d4ecd9702cd2d32c20dc345734ed2a641 100644 (file)
@@ -181,12 +181,12 @@ class RecordObject(Record):
     def __setattr__(self, k, v):
         if k in dir(Record) or "fields" not in self.__dict__:
             return object.__setattr__(self, k, v)
-        self.__dict__["fields"][k] = v
+        self.fields[k] = v
         if isinstance(v, Record):
             newlayout = {k: (k, v.layout)}
         else:
             newlayout = {k: (k, v.shape())}
-        self.__dict__["layout"].fields.update(newlayout)
+        self.layout.fields.update(newlayout)
 
 
 
@@ -215,17 +215,15 @@ class PrevControl:
             return self.s_o_ready # set dynamically by stage
         return self._o_ready      # return this when not under dynamic control
 
-    def _connect_in(self, prev, direct=False):
+    def _connect_in(self, prev, direct=False, fn=None):
         """ internal helper function to connect stage to an input source.
             do not use to connect stage-to-stage!
         """
-        if direct:
-            i_valid = prev.i_valid
-        else:
-            i_valid = prev.i_valid_test
+        i_valid = prev.i_valid if direct else prev.i_valid_test
+        i_data = fn(prev.i_data) if fn is not None else prev.i_data
         return [self.i_valid.eq(i_valid),
                 prev.o_ready.eq(self.o_ready),
-                eq(self.i_data, prev.i_data),
+                eq(self.i_data, i_data),
                ]
 
     @property
@@ -277,17 +275,15 @@ class NextControl:
                 eq(nxt.i_data, self.o_data),
                ]
 
-    def _connect_out(self, nxt, direct=False):
+    def _connect_out(self, nxt, direct=False, fn=None):
         """ internal helper function to connect stage to an output source.
             do not use to connect stage-to-stage!
         """
-        if direct:
-            i_ready = nxt.i_ready
-        else:
-            i_ready = nxt.i_ready_test
+        i_ready = nxt.i_ready if direct else nxt.i_ready_test
+        o_data = fn(self.o_data) if fn is not None else self.o_data
         return [nxt.o_valid.eq(self.o_valid),
                 self.i_ready.eq(i_ready),
-                eq(nxt.o_data, self.o_data),
+                eq(nxt.o_data, o_data),
                ]
 
 
@@ -351,9 +347,9 @@ class Visitor:
                 val = val[field_name] # dictionary-style specification
             val = self.visit(ao.fields[field_name], val, act)
             if isinstance(val, Sequence):
-                rres += val
+                res += val
             else:
-                rres.append(val)
+                res.append(val)
         return res
 
     def arrayproxy_visit(self, ao, ai, act):
@@ -1023,28 +1019,32 @@ class FIFOtest(ControlBase):
         Note: the only things it will accept is a Signal of width "width".
     """
 
-    def __init__(self, width, depth):
+    def __init__(self, iospecfn, width, depth):
 
-        self.fwidth = width
+        self.iospecfn = iospecfn
+        self.fwidth = width # XXX temporary
         self.fdepth = depth
-        def iospecfn():
-            return Signal(width, name="data")
-        stage = PassThroughStage(iospecfn)
-        ControlBase.__init__(self, stage=stage)
+        #stage = PassThroughStage(iospecfn)
+        ControlBase.__init__(self, stage=self)
+
+    def ispec(self): return self.iospecfn()
+    def ospec(self): return Signal(self.fwidth, name="dout")
+    def process(self, i): return i
 
     def elaborate(self, platform):
         self.m = m = ControlBase._elaborate(self, platform)
 
-        fifo = SyncFIFO(self.fwidth, self.fdepth)
+        (fwidth, _) = self.p.i_data.shape()
+        fifo = SyncFIFO(fwidth, self.fdepth)
         m.submodules.fifo = fifo
 
-        # prev: make the FIFO "look" like a PrevControl...
+        # XXX TODO: would be nice to do these...
+        ## prev: make the FIFO "look" like a PrevControl...
         fp = PrevControl()
         fp.i_valid = fifo.we
         fp._o_ready = fifo.writable
         fp.i_data = fifo.din
-        # ... so we can do this!
-        m.d.comb += fp._connect_in(self.p, True)
+        m.d.comb += fp._connect_in(self.p, True, fn=flatten)
 
         # next: make the FIFO "look" like a NextControl...
         fn = NextControl()
@@ -1052,7 +1052,19 @@ class FIFOtest(ControlBase):
         fn.i_ready = fifo.re
         fn.o_data = fifo.dout
         # ... so we can do this!
-        m.d.comb += fn._connect_out(self.n)
+        m.d.comb += fn._connect_out(self.n, fn=flatten)
+
+        # connect previous rdy/valid/data - do flatten on i_data
+        #m.d.comb += [fifo.we.eq(self.p.i_valid_test),
+        #             self.p.o_ready.eq(fifo.writable),
+        #             eq(fifo.din, flatten(self.p.i_data)),
+        #           ]
+
+        # connect next rdy/valid/data - do flatten on o_data
+        #m.d.comb += [self.n.o_valid.eq(fifo.readable),
+        #             fifo.re.eq(self.n.i_ready_test),
+        #             flatten(self.n.o_data).eq(fifo.dout),
+        #           ]
 
         # err... that should be all!
         return m