endeavouring to work out muxer logic
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 25 Mar 2019 14:11:24 +0000 (14:11 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 25 Mar 2019 14:11:24 +0000 (14:11 +0000)
src/add/example_buf_pipe.py
src/add/test_prioritymux_pipe.py

index 3ff5bbf2d18f0c4f198cd77537cae67a660ef5e6..7f70af6f608862d0a7a93d3c706c7df2465b3a29 100644 (file)
@@ -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
 
 
index 10874f375f334323851d087e4a2ea9d52e7e9e86..c1af804534bbe00e49ba4dddf000e14af0a4875c 100644 (file)
@@ -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]