logic, if chained together, is *combinatorial*, resulting in
progressively larger gate delay.
+ PassThroughHandshake:
+ ------------------
+
+ A Control class that introduces a single clock delay, passing its
+ data through unaltered. Unlike RegisterPipeline (which relies
+ on UnbufferedPipeline and PassThroughStage) it handles ready/valid
+ itself.
+
RegisterPipeline:
----------------
def process(self, i): return i
+class PassThroughHandshake(ControlBase):
+ """ A control block that delays by one clock cycle.
+ """
+ def __init__(self, stage, stage_ctl=False):
+ ControlBase.__init__(self, stage_ctl=stage_ctl)
+ self.stage = stage
+
+ # set up the input and output data
+ self.p.i_data = stage.ispec() # input type
+ self.n.o_data = stage.ospec() # output type
+
+ def elaborate(self, platform):
+ m = ControlBase._elaborate(self, platform)
+
+ # temporaries
+ p_i_valid = Signal(reset_less=True)
+ pvr = Signal(reset_less=True)
+ m.d.comb += p_i_valid.eq(self.p.i_valid_test)
+ m.d.comb += pvr.eq(p_i_valid & self.p.o_ready)
+
+ m.d.comb += self.p.o_ready.eq(~self.n.o_valid | self.n.i_ready_test)
+ m.d.sync += self.n.o_valid.eq(p_i_valid | ~self.p.o_ready)
+
+ odata = Mux(pvr, self.stage.process(self.p.i_data), self.n.o_data)
+ m.d.sync += eq(self.n.o_data, odata)
+
+ self.m = m
+ return m
+
+
class RegisterPipeline(UnbufferedPipeline):
""" A pipeline stage that delays by one clock cycle, creating a
sync'd latch out of o_data and o_valid as an indirect byproduct
from example_buf_pipe import StageChain, ControlBase, StageCls
from singlepipe import UnbufferedPipeline2
from singlepipe import SimpleHandshake
+from singlepipe import PassThroughHandshake
+from singlepipe import PassThroughStage
from random import randint, seed
UnbufferedPipeline2.__init__(self, stage)
+######################################################################
+# Test 18
+######################################################################
+
+class PassThroughTest(PassThroughHandshake):
+
+ def iospecfn(self):
+ return Signal(16, "out")
+
+ def __init__(self):
+ stage = PassThroughStage(self.iospecfn)
+ PassThroughHandshake.__init__(self, stage)
+
+def test_identical_resultfn(o_data, expected, i, o):
+ res = expected
+ assert o_data == res, \
+ "%d-%d data %x not match %x\n" \
+ % (i, o, o_data, res)
+
+
######################################################################
# Test 998
######################################################################
with open("test_unbufpipe17.il", "w") as f:
f.write(vl)
+ print ("test 18")
+ dut = PassThroughTest()
+ data = data_chain1()
+ test = Test5(dut, test_identical_resultfn, data=data)
+ run_simulation(dut, [test.send, test.rcv], vcd_name="test_passthru18.vcd")
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
+ [dut.p.i_data] + [dut.n.o_data]
+ vl = rtlil.convert(dut, ports=ports)
+ with open("test_passthru18.il", "w") as f:
+ f.write(vl)
+
print ("test 998 (fails, bug)")
dut = ExampleBufPipe3()
data = data_chain1()