+class StageHandler(Elaboratable):
+ """ Stage handling class
+ """
+ def __init__(self, ctrl, stage):
+ """
+ """
+ if stage is not None:
+ self.new_data(self, self, "data")
+
+ @property
+ def data_r(self):
+ return self.stage.process(self.p.data_i)
+
+ def _postprocess(self, i): # XXX DISABLED
+ return i # RETURNS INPUT
+ if hasattr(self.stage, "postprocess"):
+ return self.stage.postprocess(i)
+ return i
+
+ def new_data(self, p, n, 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)
+
+ def elaborate(self, platform):
+ """ handles case where stage has dynamic ready/valid functions
+ """
+ m = Module()
+ m.submodules.p = self.p
+ m.submodules.n = self.n
+
+ if self.stage is not None and hasattr(self.stage, "setup"):
+ self.stage.setup(m, self.p.data_i)
+
+ if not self.p.stage_ctl:
+ return m
+
+ # intercept the previous (outgoing) "ready", combine with stage ready
+ m.d.comb += self.p.s_ready_o.eq(self.p._ready_o & self.stage.d_ready)
+
+ # intercept the next (incoming) "ready" and combine it with data valid
+ sdv = self.stage.d_valid(self.n.ready_i)
+ m.d.comb += self.n.d_valid.eq(self.n.ready_i & sdv)
+
+ return m
+
+
+class ControlBase(StageHandler):