From a802ef32bff549ae328d73c3aa925d516455357a Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 25 Mar 2019 14:11:24 +0000 Subject: [PATCH] endeavouring to work out muxer logic --- src/add/example_buf_pipe.py | 57 ++++++++++++++++++++++---------- src/add/test_prioritymux_pipe.py | 11 ++++-- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/add/example_buf_pipe.py b/src/add/example_buf_pipe.py index 3ff5bbf2..7f70af6f 100644 --- a/src/add/example_buf_pipe.py +++ b/src/add/example_buf_pipe.py @@ -560,38 +560,61 @@ class UnbufferedPipeline(PipelineBase): # need an array of buffer registers conforming to *input* spec r_data = [] data_valid = [] + p_i_valid = [] + n_i_readyn = [] p_len = len(self.p) for i in range(p_len): r = self.stage.ispec() # input type r_data.append(r) data_valid.append(Signal(name="data_valid")) + p_i_valid.append(Signal(name="p_i_valid", reset_less=True)) + n_i_readyn.append(Signal(name="n_i_readyn", reset_less=True)) if hasattr(self.stage, "setup"): self.stage.setup(m, r) if len(r_data) > 1: r_data = Array(r_data) + p_i_valid = Array(p_i_valid) + n_i_readyn = Array(n_i_readyn) + data_valid = Array(data_valid) ni = 0 # TODO: use n_nux to decide which to select - n_i_readyn = Signal(reset_less=True) - m.d.comb += n_i_readyn.eq(~self.n[ni].i_ready & data_valid[i]) - - for i in range(p_len): - p_i_valid = Signal(reset_less=True) - m.d.comb += p_i_valid.eq(self.p[i].i_valid_logic()) - m.d.comb += self.n[ni].o_valid.eq(data_valid[i]) - m.d.comb += self.p[i].o_ready.eq(~data_valid[i] | \ - self.n[ni].i_ready) - m.d.sync += data_valid[i].eq(p_i_valid | \ - (n_i_readyn & data_valid[i])) - with m.If(self.p[i].i_valid & self.p[i].o_ready): - m.d.sync += eq(r_data[i], self.p[i].i_data) if self.p_mux: mid = self.p_mux.m_id - with m.If(self.p_mux.active): - m.d.comb += eq(self.n[ni].o_data, - self.stage.process(r_data[mid])) + for i in range(p_len): + m.d.comb += p_i_valid[i].eq(0) + m.d.comb += self.p[i].o_ready.eq(0) + m.d.comb += p_i_valid[mid].eq(self.p_mux.active) + m.d.comb += self.p[mid].o_ready.eq(~data_valid[mid] | \ + self.n[ni].i_ready) + m.d.comb += self.n[ni].o_valid.eq(data_valid[mid]) + + for i in range(p_len): + m.d.comb += n_i_readyn[i].eq(~self.n[ni].i_ready & \ + data_valid[i]) + m.d.sync += data_valid[i].eq(p_i_valid[i] | \ + (n_i_readyn[i] & data_valid[i])) + with m.If(self.p[i].i_valid & self.p[i].o_ready): + m.d.sync += eq(r_data[i], self.p[i].i_data) + + m.d.comb += eq(self.n[ni].o_data, + self.stage.process(r_data[mid])) else: - m.d.comb += eq(self.n[ni].o_data, self.stage.process(r_data[i])) + for i in range(p_len): + m.d.comb += p_i_valid[i].eq(self.p[i].i_valid_logic()) + m.d.comb += self.p[i].o_ready.eq(~data_valid[i] | \ + self.n[ni].i_ready) + m.d.comb += self.n[ni].o_valid.eq(data_valid[i]) + + m.d.comb += n_i_readyn[i].eq(~self.n[ni].i_ready & \ + data_valid[i]) + m.d.sync += data_valid[i].eq(p_i_valid[i] | \ + (n_i_readyn[i] & data_valid[i])) + with m.If(self.p[i].i_valid & self.p[i].o_ready): + m.d.sync += eq(r_data[i], self.p[i].i_data) + + m.d.comb += eq(self.n[ni].o_data, self.stage.process(r_data[i])) + return m diff --git a/src/add/test_prioritymux_pipe.py b/src/add/test_prioritymux_pipe.py index 10874f37..c1af8045 100644 --- a/src/add/test_prioritymux_pipe.py +++ b/src/add/test_prioritymux_pipe.py @@ -52,7 +52,7 @@ class PriorityUnbufferedPipeline(UnbufferedPipeline): class PassData: def __init__(self): self.mid = Signal(2) - self.idx = Signal(5) + self.idx = Signal(6) self.data = Signal(16) def eq(self, i): @@ -170,7 +170,7 @@ class InputTest: self.dut = dut self.di = {} self.do = {} - self.tlen = 10 + self.tlen = 4 for mid in range(dut.num_rows): self.di[mid] = {} self.do[mid] = {} @@ -188,6 +188,8 @@ class InputTest: yield o_p_ready = yield rs.o_ready + print ("send", mid, i, op2) + yield rs.i_valid.eq(1) yield rs.i_data.data.eq(op2) yield rs.i_data.idx.eq(i) @@ -226,8 +228,11 @@ class InputTest: out_i = yield n.o_data.idx out_v = yield n.o_data.data + print ("recv", mid, out_i, out_v) + # see if this output has occurred already, delete it if it has - assert out_i in self.do[mid] + assert out_i in self.do[mid], "out_i %d not in array %s" % \ + (out_i, repr(self.do[mid])) assert self.do[mid][out_i] == out_v # pass-through data del self.do[mid][out_i] -- 2.30.2