From f3945d1317aa236b752c1e286801caa2c3a07703 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 20 Mar 2019 11:13:59 +0000 Subject: [PATCH] create example pipeline buffer "StageChain" example, fix bug where output from one stage was not being assigned as the input to the next --- src/add/example_buf_pipe.py | 23 +++++++++++++++-- src/add/test_buf_pipe.py | 50 +++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/add/example_buf_pipe.py b/src/add/example_buf_pipe.py index ce4781b1..b83d5035 100644 --- a/src/add/example_buf_pipe.py +++ b/src/add/example_buf_pipe.py @@ -171,8 +171,10 @@ class StageChain: o = self.chain[idx].ospec() # only the last assignment survives m.d.comb += eq(o, c.process(i)) # process input into "o" if idx != len(self.chain)-1: - i = self.chain[idx+1] # becomes new input on next loop - self.o = o # last loop is the output + ni = self.chain[idx+1].ispec() # becomes new input on next loop + m.d.comb += eq(ni, o) # assign output to next input + i = ni + self.o = o # last loop is the output def process(self, i): return self.o @@ -366,6 +368,23 @@ class ExampleStage: return i + 1 +class ExampleStageCls: + """ an example of how to use the buffered pipeline, in a static class + fashion + """ + + def ispec(self): + return Signal(16, name="example_input_signal") + + def ospec(self): + return Signal(16, name="example_output_signal") + + def process(self, i): + """ process the input data and returns it (adds 1) + """ + return i + 1 + + class ExampleBufPipe(BufferedPipeline): """ an example of how to use the buffered pipeline. """ diff --git a/src/add/test_buf_pipe.py b/src/add/test_buf_pipe.py index 546e6ad7..e38043ec 100644 --- a/src/add/test_buf_pipe.py +++ b/src/add/test_buf_pipe.py @@ -4,8 +4,10 @@ from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil from example_buf_pipe import ExampleBufPipe, ExampleBufPipeAdd -from example_buf_pipe import ExampleCombPipe, CombPipe +from example_buf_pipe import ExampleCombPipe, CombPipe, ExampleStageCls from example_buf_pipe import PrevControl, NextControl, BufferedPipeline +from example_buf_pipe import StageChain + from random import randint @@ -282,6 +284,31 @@ class ExampleBufPipe2: return m + +class ExampleBufPipeChain2(BufferedPipeline): + """ connects two stages together as a *single* combinatorial stage. + """ + def __init__(self): + stage1 = ExampleStageCls() + stage2 = ExampleStageCls() + combined = StageChain([stage1, stage2]) + BufferedPipeline.__init__(self, combined) + + +def data_chain2(): + data = [] + for i in range(num_tests): + data.append(randint(0, 1<<16-2)) + return data + + +def test9_resultfn(o_data, expected, i, o): + res = expected + 2 + assert o_data == res, \ + "%d-%d data %x not match %s\n" \ + % (i, o, o_data, repr(expected)) + + class SetLessThan: def __init__(self, width, signed): self.src1 = Signal((width, signed)) @@ -411,13 +438,18 @@ class ExampleBufPipeAddClass(BufferedPipeline): 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 test8_resultfn(o_data, expected, i, o): - res = expected.op1 + expected.op2 + res = expected.op1 + expected.op2 # these are a TestInputAdd instance assert o_data == res, \ "%d-%d data %x not match %s\n" \ % (i, o, o_data, repr(expected)) @@ -491,3 +523,17 @@ if __name__ == '__main__': test = Test5(dut, test8_resultfn, data=data) run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe8.vcd") + print ("test 9") + dut = ExampleBufPipeChain2() + 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_bufpipechain2.il", "w") as f: + f.write(vl) + + data = data_chain2() + test = Test5(dut, test9_resultfn, data=data) + run_simulation(dut, [test.send, test.rcv], + vcd_name="test_bufpipechain2.vcd") + -- 2.30.2