From ccd1388e07261d040ede5f0bf347313fd8a29cd1 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 27 Mar 2019 14:54:57 +0000 Subject: [PATCH] reorganise MultiOutPipe, seems to be near-identical to UnbufferedPipeline --- src/add/multipipe.py | 35 ++++++++++------------------------- src/add/test_outmux_pipe.py | 26 ++++++++++++++++---------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/add/multipipe.py b/src/add/multipipe.py index af52ad9c..f0c9aeac 100644 --- a/src/add/multipipe.py +++ b/src/add/multipipe.py @@ -156,42 +156,27 @@ class CombMultiOutPipeline(MultiOutControlBase): def elaborate(self, platform): m = Module() - #m.submodules += self.n_mux + if hasattr(self.n_mux, "elaborate"): # TODO: identify submodule? + m.submodules += self.n_mux # need buffer register conforming to *input* spec r_data = self.stage.ispec() # input type if hasattr(self.stage, "setup"): self.stage.setup(m, r_data) - data_valid = [] - n_i_readyn = [] - n_len = len(self.n) - for i in range(n_len): - data_valid.append(Signal(name="data_valid", reset_less=True)) - n_i_readyn.append(Signal(name="n_i_readyn", reset_less=True)) - n_i_readyn = Array(n_i_readyn) - data_valid = Array(data_valid) + mid = self.n_mux.m_id + data_valid = Signal() # is data valid or not p_i_valid = Signal(reset_less=True) m.d.comb += p_i_valid.eq(self.p.i_valid_logic()) - mid = self.n_mux.m_id - - for i in range(n_len): - m.d.comb += data_valid[i].eq(0) - m.d.comb += n_i_readyn[i].eq(1) + for i in range(len(self.n)): m.d.comb += self.n[i].o_valid.eq(0) - m.d.comb += self.n[mid].o_valid.eq(data_valid[mid]) - m.d.comb += n_i_readyn[mid].eq(~self.n[mid].i_ready & data_valid[mid]) - anyvalid = Signal(i, reset_less=True) - av = [] - for i in range(n_len): - av.append(~data_valid[i] | self.n[i].i_ready) - anyvalid = Cat(*av) - m.d.comb += self.p.o_ready.eq(anyvalid.bool()) - m.d.comb += data_valid[mid].eq(p_i_valid | \ - (n_i_readyn[mid] & data_valid[mid])) - + data_valid = self.n[mid].o_valid + #m.d.comb += self.n[mid].o_valid.eq(data_valid) + m.d.comb += self.p.o_ready.eq(~data_valid | self.n[mid].i_ready) + m.d.comb += data_valid.eq(p_i_valid | \ + (~self.n[mid].i_ready & data_valid)) with m.If(self.p.i_valid & self.p.o_ready): m.d.comb += eq(r_data, self.p.i_data) m.d.comb += eq(self.n[mid].o_data, self.stage.process(r_data)) diff --git a/src/add/test_outmux_pipe.py b/src/add/test_outmux_pipe.py index a95d2d68..837a1eb2 100644 --- a/src/add/test_outmux_pipe.py +++ b/src/add/test_outmux_pipe.py @@ -142,9 +142,12 @@ class OutputTest: self.dut = dut self.di = [] self.do = {} - self.tlen = 3 + self.tlen = 10 for i in range(self.tlen * dut.num_rows): - mid = randint(0, dut.num_rows-1) + if i < dut.num_rows: + mid = i + else: + mid = randint(0, dut.num_rows-1) data = randint(0, 255) + (mid<<8) if mid not in self.do: self.do[mid] = [] @@ -177,15 +180,10 @@ class OutputTest: def rcv(self, mid): out_i = 0 count = 0 - while out_i != self.tlen: + stall_range = randint(0, 3) + while out_i != len(self.do[mid]): count += 1 - if count == 1000: - break - #stall_range = randint(0, 3) - #for j in range(randint(1,10)): - # stall = randint(0, stall_range) != 0 - # yield self.dut.n[0].i_ready.eq(stall) - # yield + assert count != 2000, "timeout: too long" n = self.dut.n[mid] yield n.i_ready.eq(1) yield @@ -202,6 +200,14 @@ class OutputTest: out_i += 1 + if randint(0, 5) == 0: + stall_range = randint(0, 3) + stall = randint(0, stall_range) != 0 + if stall: + yield n.i_ready.eq(0) + for i in range(stall_range): + yield + class TestPriorityMuxPipe(MuxUnbufferedPipeline): def __init__(self): -- 2.30.2