From c34168075011f9502df45b2ad1394cc627d0d80d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 27 Mar 2019 08:13:15 +0000 Subject: [PATCH] replace manual pipe-connection with a general-purpose ControlBase.connect --- src/add/example_buf_pipe.py | 61 +++++++++++++++++++++++++++++++++---- src/add/test_buf_pipe.py | 20 +++++------- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/add/example_buf_pipe.py b/src/add/example_buf_pipe.py index d28cbd0f..6db46ad9 100644 --- a/src/add/example_buf_pipe.py +++ b/src/add/example_buf_pipe.py @@ -122,7 +122,7 @@ class PrevControl: self.i_valid = Signal(i_width, name="p_i_valid") # prev >>in self self.o_ready = Signal(name="p_o_ready") # prev < self <---> out + | ^ + v | + [pipe1, pipe2, pipe3, pipe4] + | ^ | ^ | ^ + v | v | v | + out---in out--in out---in + + Also takes care of allocating i_data/o_data, by looking up + the data spec for each end of the pipechain. + + Basically this function is the direct equivalent of StageChain, + except that unlike StageChain, the Pipeline logic is followed. + + Just as StageChain presents an object that conforms to the + Stage API from a list of objects that also conform to the + Stage API, an object that calls this Pipeline connect function + has the exact same pipeline API as the list of pipline objects + it is called with. + + Thus it becomes possible to build up larger chains recursively. + More complex chains (multi-input, multi-output) will have to be + done manually. + """ + eqs = [] # collated list of assignment statements + + # connect inter-chain + for i in range(len(pipechain)-1): + pipe1 = pipechain[i] + pipe2 = pipechain[i+1] + eqs += pipe1.connect_to_next(pipe2) + + # connect front of chain to ourselves + front = pipechain[0] + self.p.i_data = front.stage.ispec() + eqs += front._connect_in(self) + + # connect end of chain to ourselves + end = pipechain[-1] + self.n.o_data = end.stage.ospec() + eqs += end._connect_out(self) + + # activate the assignments + m.d.comb += eqs def set_input(self, i): """ helper function to set the input data diff --git a/src/add/test_buf_pipe.py b/src/add/test_buf_pipe.py index 79eac0b8..c92a96cc 100644 --- a/src/add/test_buf_pipe.py +++ b/src/add/test_buf_pipe.py @@ -292,10 +292,6 @@ class ExampleBufPipe2(ControlBase): def __init__(self): ControlBase.__init__(self) - # input / output - self.p.i_data = Signal(32) # >>in - comes in from the PREVIOUS stage - self.n.o_data = Signal(32) # out>> - goes out to the NEXT stage - self.pipe1 = ExampleBufPipe() self.pipe2 = ExampleBufPipe() @@ -304,14 +300,7 @@ class ExampleBufPipe2(ControlBase): m.submodules.pipe1 = self.pipe1 m.submodules.pipe2 = self.pipe2 - # connect inter-pipe input/output valid/ready/data - m.d.comb += self.pipe1.connect_to_next(self.pipe2) - - # inputs/outputs to the module: pipe1 connections here (LHS) - m.d.comb += self.pipe1.connect_in(self) - - # now pipe2 connections (RHS) - m.d.comb += self.pipe2.connect_out(self) + self.connect(m, [self.pipe1, self.pipe2]) return m @@ -599,6 +588,13 @@ if __name__ == '__main__': print ("test 2") dut = ExampleBufPipe2() run_simulation(dut, testbench2(dut), vcd_name="test_bufpipe2.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_bufpipe2.il", "w") as f: + f.write(vl) + print ("test 3") dut = ExampleBufPipe() -- 2.30.2