+ % (i, o, data_o, repr(expected))
+
+
+######################################################################
+# Test 7
+######################################################################
+
+class ExampleAddRecordStage(StageCls):
+ """ example use of a Record
+ """
+
+ record_spec = [('src1', 16), ('src2', 16)]
+ def ispec(self):
+ """ returns a Record using the specification
+ """
+ return Record(self.record_spec)
+
+ def ospec(self):
+ return Record(self.record_spec)
+
+ def process(self, i):
+ """ process the input data, returning a dictionary with key names
+ that exactly match the Record's attributes.
+ """
+ return {'src1': i.src1 + 1,
+ 'src2': i.src2 + 1}
+
+######################################################################
+# Test 11
+######################################################################
+
+class ExampleAddRecordPlaceHolderStage(StageCls):
+ """ example use of a Record, with a placeholder as the processing result
+ """
+
+ record_spec = [('src1', 16), ('src2', 16)]
+ def ispec(self):
+ """ returns a Record using the specification
+ """
+ return Record(self.record_spec)
+
+ def ospec(self):
+ return Record(self.record_spec)
+
+ def process(self, i):
+ """ process the input data, returning a PlaceHolder class instance
+ with attributes that exactly match those of the Record.
+ """
+ o = PlaceHolder()
+ o.src1 = i.src1 + 1
+ o.src2 = i.src2 + 1
+ return o
+
+
+# a dummy class that may have stuff assigned to instances once created
+class PlaceHolder: pass
+
+
+class ExampleAddRecordPipe(UnbufferedPipeline):
+ """ an example of how to use the combinatorial pipeline.
+ """
+
+ def __init__(self):
+ stage = ExampleAddRecordStage()
+ UnbufferedPipeline.__init__(self, stage)
+
+
+def resultfn_7(data_o, expected, i, o):
+ res = (expected['src1'] + 1, expected['src2'] + 1)
+ assert data_o['src1'] == res[0] and data_o['src2'] == res[1], \
+ "%d-%d data %s not match %s\n" \
+ % (i, o, repr(data_o), repr(expected))
+
+
+class ExampleAddRecordPlaceHolderPipe(UnbufferedPipeline):
+ """ an example of how to use the combinatorial pipeline.
+ """
+
+ def __init__(self):
+ stage = ExampleAddRecordPlaceHolderStage()
+ UnbufferedPipeline.__init__(self, stage)
+
+
+def resultfn_test11(data_o, expected, i, o):
+ res1 = expected.src1 + 1
+ res2 = expected.src2 + 1
+ assert data_o['src1'] == res1 and data_o['src2'] == res2, \
+ "%d-%d data %s not match %s\n" \
+ % (i, o, repr(data_o), repr(expected))
+
+
+######################################################################
+# Test 8
+######################################################################
+
+
+class Example2OpClass:
+ """ an example of a class used to store 2 operands.
+ requires an eq function, to conform with the pipeline stage API
+ """
+
+ def __init__(self):
+ self.op1 = Signal(16)
+ self.op2 = Signal(16)
+
+ def eq(self, i):
+ return [self.op1.eq(i.op1), self.op2.eq(i.op2)]
+
+
+class ExampleAddClassStage(StageCls):
+ """ an example of how to use the buffered pipeline, as a class instance
+ """
+
+ def ispec(self):
+ """ returns an instance of an Example2OpClass.
+ """
+ return Example2OpClass()
+
+ def ospec(self):
+ """ returns an output signal which will happen to contain the sum
+ of the two inputs
+ """
+ return Signal(16, name="add2_out")
+
+ def process(self, i):
+ """ process the input data (sums the values in the tuple) and returns it
+ """
+ return i.op1 + i.op2
+
+
+class ExampleBufPipeAddClass(BufferedHandshake):
+ """ an example of how to use the buffered pipeline, using a class instance
+ """
+
+ def __init__(self):
+ addstage = ExampleAddClassStage()
+ BufferedHandshake.__init__(self, addstage)
+
+
+class TestInputAdd:
+ """ the eq function, called by set_input, needs an incoming object
+ that conforms to the Example2OpClass.eq function requirements
+ easiest way to do that is to create a class that has the exact
+ same member layout (self.op1, self.op2) as Example2OpClass
+ """
+ def __init__(self, op1, op2):
+ self.op1 = op1
+ self.op2 = op2
+
+
+def resultfn_8(data_o, expected, i, o):
+ res = expected.op1 + expected.op2 # these are a TestInputAdd instance
+ assert data_o == res, \
+ "%d-%d data %s res %x not match %s\n" \
+ % (i, o, repr(data_o), res, repr(expected))
+
+def data_2op():
+ data = []
+ for i in range(num_tests):
+ data.append(TestInputAdd(randint(0, 1<<16-1), randint(0, 1<<16-1)))
+ return data
+
+
+######################################################################
+# Test 12
+######################################################################
+
+class ExampleStageDelayCls(StageCls, Elaboratable):
+ """ an example of how to use the buffered pipeline, in a static class
+ fashion
+ """
+
+ def __init__(self, valid_trigger=2):
+ self.count = Signal(2)
+ self.valid_trigger = valid_trigger
+
+ def ispec(self):
+ return Signal(16, name="example_input_signal")
+
+ def ospec(self):
+ return Signal(16, name="example_output_signal")
+
+ @property
+ def d_ready(self):
+ """ data is ready to be accepted when this is true
+ """
+ return (self.count == 1)# | (self.count == 3)
+ return Const(1)
+
+ def d_valid(self, ready_i):
+ """ data is valid at output when this is true
+ """
+ return self.count == self.valid_trigger
+ return Const(1)
+
+ def process(self, i):
+ """ process the input data and returns it (adds 1)
+ """
+ return i + 1
+
+ def elaborate(self, platform):
+ m = Module()
+ m.d.sync += self.count.eq(self.count + 1)
+ return m
+
+
+class ExampleBufDelayedPipe(BufferedHandshake):
+
+ def __init__(self):
+ stage = ExampleStageDelayCls(valid_trigger=2)
+ BufferedHandshake.__init__(self, stage, stage_ctl=True)
+
+ def elaborate(self, platform):
+ m = BufferedHandshake.elaborate(self, platform)
+ m.submodules.stage = self.stage
+ return m
+
+
+def data_chain1():
+ data = []
+ for i in range(num_tests):
+ data.append(1<<((i*3)%15))
+ #data.append(randint(0, 1<<16-2))
+ #print (hex(data[-1]))
+ return data
+
+
+def resultfn_12(data_o, expected, i, o):
+ res = expected + 1
+ assert data_o == res, \
+ "%d-%d data %x not match %x\n" \
+ % (i, o, data_o, res)
+
+
+######################################################################
+# Test 13
+######################################################################
+
+class ExampleUnBufDelayedPipe(BufferedHandshake):
+
+ def __init__(self):
+ stage = ExampleStageDelayCls(valid_trigger=3)
+ BufferedHandshake.__init__(self, stage, stage_ctl=True)
+
+ def elaborate(self, platform):
+ m = BufferedHandshake.elaborate(self, platform)
+ m.submodules.stage = self.stage
+ return m
+
+######################################################################
+# Test 15
+######################################################################
+
+class ExampleBufModeAdd1Pipe(SimpleHandshake):
+
+ def __init__(self):
+ stage = ExampleStageCls()
+ SimpleHandshake.__init__(self, stage)
+
+
+######################################################################
+# Test 16
+######################################################################
+
+class ExampleBufModeUnBufPipe(ControlBase):
+
+ def elaborate(self, platform):
+ m = ControlBase.elaborate(self, platform)
+
+ pipe1 = ExampleBufModeAdd1Pipe()
+ pipe2 = ExampleBufAdd1Pipe()
+
+ m.submodules.pipe1 = pipe1
+ m.submodules.pipe2 = pipe2
+
+ m.d.comb += self.connect([pipe1, pipe2])
+
+ return m
+
+######################################################################
+# Test 17
+######################################################################
+
+class ExampleUnBufAdd1Pipe2(UnbufferedPipeline2):
+
+ def __init__(self):
+ stage = ExampleStageCls()
+ 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 resultfn_identical(data_o, expected, i, o):
+ res = expected
+ assert data_o == res, \
+ "%d-%d data %x not match %x\n" \
+ % (i, o, data_o, res)
+
+
+######################################################################
+# Test 19
+######################################################################
+
+class ExamplePassAdd1Pipe(PassThroughHandshake):
+
+ def __init__(self):
+ stage = ExampleStageCls()
+ PassThroughHandshake.__init__(self, stage)
+
+
+class ExampleBufPassThruPipe(ControlBase):
+
+ def elaborate(self, platform):
+ m = ControlBase.elaborate(self, platform)
+
+ # XXX currently fails: any other permutation works fine.
+ # p1=u,p2=b ok p1=u,p2=u ok p1=b,p2=b ok
+ # also fails using UnbufferedPipeline as well
+ pipe1 = ExampleBufModeAdd1Pipe()
+ pipe2 = ExamplePassAdd1Pipe()
+
+ m.submodules.pipe1 = pipe1
+ m.submodules.pipe2 = pipe2
+
+ m.d.comb += self.connect([pipe1, pipe2])
+
+ return m
+
+
+######################################################################
+# Test 20
+######################################################################
+
+def iospecfn():
+ return Signal(16, name="d_in")
+
+class FIFOTest16(FIFOControl):
+
+ def __init__(self):
+ stage = PassThroughStage(iospecfn)
+ FIFOControl.__init__(self, 2, stage)
+
+
+######################################################################
+# Test 21
+######################################################################
+
+class ExampleFIFOPassThruPipe1(ControlBase):
+
+ def elaborate(self, platform):
+ m = ControlBase.elaborate(self, platform)
+
+ pipe1 = FIFOTest16()
+ pipe2 = FIFOTest16()
+ pipe3 = ExamplePassAdd1Pipe()
+
+ m.submodules.pipe1 = pipe1
+ m.submodules.pipe2 = pipe2
+ m.submodules.pipe3 = pipe3
+
+ m.d.comb += self.connect([pipe1, pipe2, pipe3])
+
+ return m
+
+
+######################################################################
+# Test 22
+######################################################################
+
+class Example2OpRecord(RecordObject):
+ def __init__(self):
+ RecordObject.__init__(self)
+ self.op1 = Signal(16)
+ self.op2 = Signal(16)
+
+
+class ExampleAddRecordObjectStage(StageCls):
+
+ def ispec(self):
+ """ returns an instance of an Example2OpRecord.
+ """
+ return Example2OpRecord()
+
+ def ospec(self):
+ """ returns an output signal which will happen to contain the sum
+ of the two inputs
+ """
+ return Signal(16)
+
+ def process(self, i):
+ """ process the input data (sums the values in the tuple) and returns it
+ """
+ return i.op1 + i.op2
+
+
+class ExampleRecordHandshakeAddClass(SimpleHandshake):
+
+ def __init__(self):
+ addstage = ExampleAddRecordObjectStage()
+ SimpleHandshake.__init__(self, stage=addstage)
+
+
+######################################################################
+# Test 23
+######################################################################
+
+def iospecfnrecord():
+ return Example2OpRecord()
+
+class FIFOTestRecordControl(FIFOControl):
+
+ def __init__(self):
+ stage = PassThroughStage(iospecfnrecord)
+ FIFOControl.__init__(self, 2, stage)
+
+
+class ExampleFIFORecordObjectPipe(ControlBase):
+
+ def elaborate(self, platform):
+ m = ControlBase.elaborate(self, platform)
+
+ pipe1 = FIFOTestRecordControl()
+ pipe2 = ExampleRecordHandshakeAddClass()
+
+ m.submodules.pipe1 = pipe1
+ m.submodules.pipe2 = pipe2
+
+ m.d.comb += self.connect([pipe1, pipe2])
+
+ return m
+
+
+######################################################################
+# Test 24
+######################################################################
+
+class FIFOTestRecordAddStageControl(FIFOControl):
+
+ def __init__(self):
+ stage = ExampleAddRecordObjectStage()
+ FIFOControl.__init__(self, 2, stage)
+
+
+
+######################################################################
+# Test 25
+######################################################################
+
+class FIFOTestAdd16(FIFOControl):
+
+ def __init__(self):
+ stage = ExampleStageCls()
+ FIFOControl.__init__(self, 2, stage)
+
+
+class ExampleFIFOAdd2Pipe(ControlBase):
+
+ def elaborate(self, platform):
+ m = ControlBase.elaborate(self, platform)
+
+ pipe1 = FIFOTestAdd16()
+ pipe2 = FIFOTestAdd16()
+
+ m.submodules.pipe1 = pipe1
+ m.submodules.pipe2 = pipe2
+
+ m.d.comb += self.connect([pipe1, pipe2])
+
+ return m
+
+
+######################################################################
+# Test 26
+######################################################################
+
+def iospecfn24():
+ return (Signal(16, name="src1"), Signal(16, name="src2"))
+
+class FIFOTest2x16(FIFOControl):
+
+ def __init__(self):
+ stage = PassThroughStage(iospecfn2)
+ FIFOControl.__init__(self, 2, stage)
+
+
+######################################################################
+# Test 997
+######################################################################
+
+class ExampleBufPassThruPipe2(ControlBase):
+
+ def elaborate(self, platform):
+ m = ControlBase.elaborate(self, platform)
+
+ # XXX currently fails: any other permutation works fine.
+ # p1=u,p2=b ok p1=u,p2=u ok p1=b,p2=b ok
+ # also fails using UnbufferedPipeline as well
+ #pipe1 = ExampleUnBufAdd1Pipe()
+ #pipe2 = ExampleBufAdd1Pipe()
+ pipe1 = ExampleBufAdd1Pipe()
+ pipe2 = ExamplePassAdd1Pipe()