convert to use PrevControl and NextControl instead of Trigger class
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Apr 2019 15:21:48 +0000 (16:21 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Apr 2019 15:21:48 +0000 (16:21 +0100)
Trigger contained stb/ack where it is ok to call them ready/valid prev/next

src/add/fpadd/statemachine.py
src/add/fpbase.py
src/add/fpcommon/getop.py
src/add/fpcommon/putz.py
src/add/nmigen_div_experiment.py
src/add/singlepipe.py
src/add/test_fsm_experiment.py
src/add/unit_test_single.py

index 01847074c2d1a3d05bf5cb2b3133f38e9cb9ebd6..dab9dd79cb3b4c9dbc9e0f013e74754718779088 100644 (file)
@@ -6,7 +6,7 @@ from nmigen import Module, Signal, Cat, Mux, Array, Const
 from nmigen.cli import main, verilog
 from math import log
 
-from fpbase import FPOp
+from fpbase import FPOpIn, FPOpOut
 from fpbase import Trigger
 from singlepipe import (StageChain, SimpleHandshake)
 
@@ -31,7 +31,7 @@ from fpadd.addstages import FPAddAlignSingleAdd
 
 class FPOpData:
     def __init__(self, width, id_wid):
-        self.z = FPOp(width)
+        self.z = FPOpOut(width)
         self.mid = Signal(id_wid, reset_less=True)
 
     def eq(self, i):
@@ -202,13 +202,13 @@ class FPADDBase(FPState):
                      self.in_t.ack.eq(self.mod.in_t.ack),
                      self.o.mid.eq(self.mod.o.mid),
                      self.o.z.v.eq(self.mod.o.z.v),
-                     self.o.z.stb.eq(self.mod.o.z.stb),
-                     self.mod.o.z.ack.eq(self.o.z.ack),
+                     self.o.z.o_valid.eq(self.mod.o.z.o_valid),
+                     self.mod.o.z.i_ready.eq(self.o.z.i_ready_test),
                     ]
 
         m.d.sync += self.add_stb.eq(add_stb)
         m.d.sync += self.add_ack.eq(0) # sets to zero when not in active state
-        m.d.sync += self.o.z.ack.eq(0) # likewise
+        m.d.sync += self.o.z.i_ready.eq(0) # likewise
         #m.d.sync += self.in_t.stb.eq(0)
 
         m.submodules.fpadd = self.mod
@@ -230,7 +230,7 @@ class FPADDBase(FPState):
             with m.Else():
                 m.d.sync += [self.add_ack.eq(0),
                              self.in_t.stb.eq(0),
-                             self.o.z.ack.eq(1),
+                             self.o.z.i_ready.eq(1),
                             ]
         with m.Else():
             # done: acknowledge, and write out id and value
@@ -288,8 +288,8 @@ class FPADD(FPID):
 
         rs = []
         for i in range(rs_sz):
-            in_a  = FPOp(width)
-            in_b  = FPOp(width)
+            in_a  = FPOpIn(width)
+            in_b  = FPOpIn(width)
             in_a.name = "in_a_%d" % i
             in_b.name = "in_b_%d" % i
             rs.append((in_a, in_b))
@@ -297,7 +297,7 @@ class FPADD(FPID):
 
         res = []
         for i in range(rs_sz):
-            out_z = FPOp(width)
+            out_z = FPOpOut(width)
             out_z.name = "out_z_%d" % i
             res.append(out_z)
         self.res = Array(res)
index b31ab21cb0b1d004e7b628e38dce79c764aa0659..c53cabbba555e2fd486acd62ba9106dffe36314c 100644 (file)
@@ -7,6 +7,7 @@ from math import log
 from operator import or_
 from functools import reduce
 
+from singlepipe import PrevControl, NextControl
 from pipeline import ObjectProxy
 
 
@@ -479,12 +480,12 @@ class Trigger:
         return [self.stb, self.ack]
 
 
-class FPOp(Trigger):
+class FPOpIn(PrevControl):
     def __init__(self, width):
-        Trigger.__init__(self)
+        PrevControl.__init__(self)
         self.width = width
-
-        self.v   = Signal(width)
+        self.v = Signal(width)
+        self.i_data = self.v
 
     def chain_inv(self, in_op, extra=None):
         stb = in_op.stb
@@ -504,14 +505,31 @@ class FPOp(Trigger):
                 in_op.ack.eq(self.ack), # send ACK
                ]
 
-    def eq(self, inp):
-        return [self.v.eq(inp.v),
-                self.stb.eq(inp.stb),
-                self.ack.eq(inp.ack)
+
+class FPOpOut(NextControl):
+    def __init__(self, width):
+        NextControl.__init__(self)
+        self.width = width
+        self.v = Signal(width)
+        self.o_data = self.v
+
+    def chain_inv(self, in_op, extra=None):
+        stb = in_op.stb
+        if extra is not None:
+            stb = stb & extra
+        return [self.v.eq(in_op.v),          # receive value
+                self.stb.eq(stb),      # receive STB
+                in_op.ack.eq(~self.ack), # send ACK
                ]
 
-    def ports(self):
-        return [self.v, self.stb, self.ack]
+    def chain_from(self, in_op, extra=None):
+        stb = in_op.stb
+        if extra is not None:
+            stb = stb & extra
+        return [self.v.eq(in_op.v),          # receive value
+                self.stb.eq(stb),      # receive STB
+                in_op.ack.eq(self.ack), # send ACK
+               ]
 
 
 class Overflow:
@@ -551,7 +569,7 @@ class FPBase:
         """
         res = v.decode2(m)
         ack = Signal()
-        with m.If((op.ack) & (op.stb)):
+        with m.If((op.o_ready) & (op.i_valid_test)):
             m.next = next_state
             # op is latched in from FPNumIn class on same ack/stb
             m.d.comb += ack.eq(0)
@@ -661,11 +679,11 @@ class FPBase:
         m.d.sync += [
           out_z.v.eq(z.v)
         ]
-        with m.If(out_z.stb & out_z.ack):
-            m.d.sync += out_z.stb.eq(0)
+        with m.If(out_z.o_valid & out_z.i_ready_test):
+            m.d.sync += out_z.o_valid.eq(0)
             m.next = next_state
         with m.Else():
-            m.d.sync += out_z.stb.eq(1)
+            m.d.sync += out_z.o_valid.eq(1)
 
 
 class FPState(FPBase):
index 8cf5e42166c1046a1a868ec0efc54d27e23c8437..e77563027bc95d358068898a8d8692eafe060d91 100644 (file)
@@ -7,7 +7,7 @@ from nmigen.lib.coding import PriorityEncoder
 from nmigen.cli import main, verilog
 from math import log
 
-from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase, FPNumBase
+from fpbase import FPNumIn, FPNumOut, FPOpIn, Overflow, FPBase, FPNumBase
 from fpbase import MultiShiftRMerge, Trigger
 from singlepipe import (ControlBase, StageChain, SimpleHandshake,
                         PassThroughStage)
@@ -19,13 +19,14 @@ from fpbase import FPState
 
 class FPGetOpMod:
     def __init__(self, width):
-        self.in_op = FPOp(width)
+        self.in_op = FPOpIn(width)
         self.out_op = Signal(width)
         self.out_decode = Signal(reset_less=True)
 
     def elaborate(self, platform):
         m = Module()
-        m.d.comb += self.out_decode.eq((self.in_op.ack) & (self.in_op.stb))
+        m.d.comb += self.out_decode.eq((self.in_op.o_ready) & \
+                                       (self.in_op.i_valid_test))
         m.submodules.get_op_in = self.in_op
         #m.submodules.get_op_out = self.out_op
         with m.If(self.out_decode):
@@ -58,11 +59,11 @@ class FPGetOp(FPState):
         with m.If(self.out_decode):
             m.next = self.out_state
             m.d.sync += [
-                self.in_op.ack.eq(0),
+                self.in_op.o_ready.eq(0),
                 self.out_op.eq(self.mod.out_op)
             ]
         with m.Else():
-            m.d.sync += self.in_op.ack.eq(1)
+            m.d.sync += self.in_op.o_ready.eq(1)
 
 
 class FPNumBase2Ops:
index 106fad9d90dd31d7f7ddcbbdee9d47033d7b806c..6b619ccbf1ac3dc4140dc46966011bcc15fcaa54 100644 (file)
@@ -25,11 +25,11 @@ class FPPutZ(FPState):
         m.d.sync += [
           self.out_z.z.v.eq(self.in_z)
         ]
-        with m.If(self.out_z.z.stb & self.out_z.z.ack):
-            m.d.sync += self.out_z.z.stb.eq(0)
+        with m.If(self.out_z.z.o_valid & self.out_z.z.i_ready_test):
+            m.d.sync += self.out_z.z.o_valid.eq(0)
             m.next = self.to_state
         with m.Else():
-            m.d.sync += self.out_z.z.stb.eq(1)
+            m.d.sync += self.out_z.z.o_valid.eq(1)
 
 
 class FPPutZIdx(FPState):
@@ -46,15 +46,15 @@ class FPPutZIdx(FPState):
     def action(self, m):
         outz_stb = Signal(reset_less=True)
         outz_ack = Signal(reset_less=True)
-        m.d.comb += [outz_stb.eq(self.out_zs[self.in_mid].stb),
-                     outz_ack.eq(self.out_zs[self.in_mid].ack),
+        m.d.comb += [outz_stb.eq(self.out_zs[self.in_mid].o_valid),
+                     outz_ack.eq(self.out_zs[self.in_mid].i_ready_test),
                     ]
         m.d.sync += [
           self.out_zs[self.in_mid].v.eq(self.in_z.v)
         ]
         with m.If(outz_stb & outz_ack):
-            m.d.sync += self.out_zs[self.in_mid].stb.eq(0)
+            m.d.sync += self.out_zs[self.in_mid].o_valid.eq(0)
             m.next = self.to_state
         with m.Else():
-            m.d.sync += self.out_zs[self.in_mid].stb.eq(1)
+            m.d.sync += self.out_zs[self.in_mid].o_valid.eq(1)
 
index ff0e54cba7b96d7e95c90318b3127cf97e693465..5dccecb50c350eeef5f1f9bc48922a43fcb0c0fb 100644 (file)
@@ -5,7 +5,7 @@
 from nmigen import Module, Signal, Const, Cat
 from nmigen.cli import main, verilog
 
-from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase, FPState
+from fpbase import FPNumIn, FPNumOut, FPOpIn, FPOpOut, Overflow, FPBase, FPState
 from singlepipe import eq
 
 class Div:
@@ -33,9 +33,9 @@ class FPDIV(FPBase):
         FPBase.__init__(self)
         self.width = width
 
-        self.in_a  = FPOp(width)
-        self.in_b  = FPOp(width)
-        self.out_z = FPOp(width)
+        self.in_a  = FPOpIn(width)
+        self.in_b  = FPOpIn(width)
+        self.out_z = FPOpOut(width)
 
         self.states = []
 
@@ -71,14 +71,14 @@ class FPDIV(FPBase):
 
             with m.State("get_a"):
                 res = self.get_op(m, self.in_a, a, "get_b")
-                m.d.sync += eq([a, self.in_a.ack], res)
+                m.d.sync += eq([a, self.in_a.o_ready], res)
 
             # ******
             # gets operand b
 
             with m.State("get_b"):
                 res = self.get_op(m, self.in_b, b, "special_cases")
-                m.d.sync += eq([b, self.in_b.ack], res)
+                m.d.sync += eq([b, self.in_b.o_ready], res)
 
             # ******
             # special cases: NaNs, infs, zeros, denormalised
index 6ee5afc6cf3e7063e65206adbd76f53a87a688a9..a977dfabce3d9c86946117f7a6de8b0434a36a3a 100644 (file)
@@ -214,6 +214,7 @@ class PrevControl:
         self.i_data = None # XXX MUST BE ADDED BY USER
         if stage_ctl:
             self.s_o_ready = Signal(name="p_s_o_rdy") # prev   <<out self
+        self.trigger = Signal(reset_less=True)
 
     @property
     def o_ready(self):
@@ -254,14 +255,13 @@ class PrevControl:
 
     def elaborate(self, platform):
         m = Module()
-        self.trigger = Signal(reset_less=True)
         m.d.comb += self.trigger.eq(self.i_valid_test & self.o_ready)
         return m
 
     def eq(self, i):
-        return [self.i_data.eq(inp.i_data),
-                self.o_ready.eq(inp.o_ready),
-                self.i_valid.eq(inp.i_valid)]
+        return [self.i_data.eq(i.i_data),
+                self.o_ready.eq(i.o_ready),
+                self.i_valid.eq(i.i_valid)]
 
     def ports(self):
         res = [self.i_valid, self.o_ready]
@@ -287,6 +287,7 @@ class NextControl:
         self.o_data = None # XXX MUST BE ADDED BY USER
         #if self.stage_ctl:
         self.d_valid = Signal(reset=1) # INTERNAL (data valid)
+        self.trigger = Signal(reset_less=True)
 
     @property
     def i_ready_test(self):
@@ -317,7 +318,6 @@ class NextControl:
 
     def elaborate(self, platform):
         m = Module()
-        self.trigger = Signal(reset_less=True)
         m.d.comb += self.trigger.eq(self.i_ready_test & self.o_valid)
         return m
 
index 51476ccf4be50d74b503c861085c1c67cc08fef7..d24afd7b84ab4b04bb9a5077cf707cb05e832ca0 100644 (file)
@@ -7,7 +7,7 @@ from nmigen.cli import main, verilog, rtlil
 from nmigen.compat.sim import run_simulation
 
 
-from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase, FPState
+from fpbase import FPNumIn, FPNumOut, FPOpIn, FPOpOut, FPBase, FPState
 from singlepipe import eq, SimpleHandshake, ControlBase
 from test_buf_pipe import data_chain2, Test5
 
@@ -18,9 +18,9 @@ class FPDIV(FPBase):
         FPBase.__init__(self)
         self.width = width
 
-        self.in_a  = FPOp(width)
-        self.in_b  = FPOp(width)
-        self.out_z = FPOp(width)
+        self.in_a  = FPOpIn(width)
+        self.in_b  = FPOpIn(width)
+        self.out_z = FPOpOut(width)
 
         self.states = []
 
@@ -49,7 +49,7 @@ class FPDIV(FPBase):
 
             with m.State("get_a"):
                 res = self.get_op(m, self.in_a, a, "add_1")
-                m.d.sync += eq([a, self.in_a.ack], res)
+                m.d.sync += eq([a, self.in_a.o_ready], res)
 
             with m.State("add_1"):
                 m.next = "pack"
@@ -98,11 +98,11 @@ class FPDIVPipe(ControlBase):
         m.submodules.fpdiv = self.fpdiv
 
         # see if connecting to stb/ack works
-        m.d.comb += self.p.o_ready.eq(self.fpdiv.in_a.ack)
-        m.d.comb += self.fpdiv.in_a.stb.eq(self.p.i_valid_test)
+        m.d.comb += self.p.o_ready.eq(self.fpdiv.in_a.o_ready)
+        m.d.comb += self.fpdiv.in_a.i_valid.eq(self.p.i_valid_test)
 
-        m.d.comb += self.n.o_valid.eq(self.fpdiv.out_z.stb)
-        m.d.comb += self.fpdiv.out_z.ack.eq(self.n.i_ready_test)
+        m.d.comb += self.n.o_valid.eq(self.fpdiv.out_z.o_valid)
+        m.d.comb += self.fpdiv.out_z.i_ready.eq(self.n.i_ready_test)
         m.d.comb += self.n.o_data.eq(self.fpdiv.out_z.v)
 
         return m
index 8def914aad5df17e5cd842b49364869d7d40683b..eff75f15d008bb79ab9de82168151d421832056d 100644 (file)
@@ -41,35 +41,35 @@ def get_rs_case(dut, a, b, mid):
     out_z = dut.res[0]
     yield dut.ids.in_mid.eq(mid)
     yield in_a.v.eq(a)
-    yield in_a.stb.eq(1)
+    yield in_a.i_valid.eq(1)
     yield
     yield
     yield
     yield
-    a_ack = (yield in_a.ack)
+    a_ack = (yield in_a.o_ready)
     assert a_ack == 0
 
-    yield in_a.stb.eq(0)
+    yield in_a.i_valid.eq(0)
 
     yield in_b.v.eq(b)
-    yield in_b.stb.eq(1)
+    yield in_b.i_valid.eq(1)
     yield
     yield
-    b_ack = (yield in_b.ack)
+    b_ack = (yield in_b.o_ready)
     assert b_ack == 0
 
-    yield in_b.stb.eq(0)
+    yield in_b.i_valid.eq(0)
 
-    yield out_z.ack.eq(1)
+    yield out_z.i_ready.eq(1)
 
     while True:
-        out_z_stb = (yield out_z.stb)
+        out_z_stb = (yield out_z.o_valid)
         if not out_z_stb:
             yield
             continue
         vout_z = yield out_z.v
         #out_mid = yield dut.ids.out_mid
-        yield out_z.ack.eq(0)
+        yield out_z.i_ready.eq(0)
         yield
         break
 
@@ -87,35 +87,35 @@ def check_rs_case(dut, a, b, z, mid=None):
 def get_case(dut, a, b, mid):
     #yield dut.in_mid.eq(mid)
     yield dut.in_a.v.eq(a)
-    yield dut.in_a.stb.eq(1)
+    yield dut.in_a.i_valid_test.eq(1)
     yield
     yield
     yield
     yield
-    a_ack = (yield dut.in_a.ack)
+    a_ack = (yield dut.in_a.o_ready)
     assert a_ack == 0
 
-    yield dut.in_a.stb.eq(0)
+    yield dut.in_a.i_valid.eq(0)
 
     yield dut.in_b.v.eq(b)
-    yield dut.in_b.stb.eq(1)
+    yield dut.in_b.i_valid.eq(1)
     yield
     yield
-    b_ack = (yield dut.in_b.ack)
+    b_ack = (yield dut.in_b.o_ready)
     assert b_ack == 0
 
-    yield dut.in_b.stb.eq(0)
+    yield dut.in_b.i_valid.eq(0)
 
-    yield dut.out_z.ack.eq(1)
+    yield dut.out_z.i_ready.eq(1)
 
     while True:
-        out_z_stb = (yield dut.out_z.stb)
+        out_z_stb = (yield dut.out_z.o_valid)
         if not out_z_stb:
             yield
             continue
         out_z = yield dut.out_z.v
         #out_mid = yield dut.out_mid
-        yield dut.out_z.ack.eq(0)
+        yield dut.out_z.i_ready.eq(0)
         yield
         break