+ NOTE 1: FPGAs may have trouble with the defaults for SyncFIFO
+
+ NOTE 2: i_data *must* have a shape function. it can therefore
+ be a Signal, or a Record, or a RecordObject.
+
+ data is processed (and located) as follows:
+
+ self.p self.stage temp fn temp fn temp fp self.n
+ i_data->process()->result->flatten->din.FIFO.dout->flatten(o_data)
+
+ yes, really: flatten produces a Cat() which can be assigned to.
+ this is how the FIFO gets de-flattened without needing a de-flatten
+ function