instantiate 2 FPGetOp instances and use them. a little awkwardly.
[ieee754fpu.git] / src / add / nmigen_div_experiment.py
index f5adb9dbd63b9edaf81b35359b74e57d04f484f0..e074c5c66364462b058db06f91d0554c6f2d613c 100644 (file)
@@ -5,7 +5,8 @@
 from nmigen import Module, Signal, Const, Cat
 from nmigen.cli import main, verilog
 
-from fpbase import FPNum, FPOp, Overflow, FPBase
+from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase
+from nmigen_add_experiment import FPState, FPGetOp
 
 class Div:
     def __init__(self, width):
@@ -36,33 +37,55 @@ class FPDIV(FPBase):
         self.in_b  = FPOp(width)
         self.out_z = FPOp(width)
 
+        self.states = []
+
+    def add_state(self, state):
+        self.states.append(state)
+        return state
+
     def get_fragment(self, platform=None):
         """ creates the HDL code-fragment for FPDiv
         """
         m = Module()
 
         # Latches
-        a = FPNum(self.width, False)
-        b = FPNum(self.width, False)
-        z = FPNum(self.width, False)
+        a = FPNumIn(None, self.width, False)
+        b = FPNumIn(None, self.width, False)
+        z = FPNumOut(self.width, False)
 
         div = Div(a.m_width*2 + 3) # double the mantissa width plus g/r/sticky
 
         of = Overflow()
+        m.submodules.in_a = a
+        m.submodules.in_b = b
+        m.submodules.z = z
+        m.submodules.of = of
 
         with m.FSM() as fsm:
 
             # ******
             # gets operand a
 
+            geta = FPGetOp("get_a", "get_b", self.in_a, self.width)
+            geta.setup(m, self.in_a)
+
             with m.State("get_a"):
-                self.get_op(m, self.in_a, a, "get_b")
+                geta.action(m)
+                with m.If(geta.out_decode):
+                    m.d.sync += a.decode(self.in_a.v)
+                #self.get_op(m, self.in_a, a, "get_b")
 
             # ******
             # gets operand b
 
+            getb = FPGetOp("get_b", "special_cases", self.in_b, self.width)
+            getb.setup(m, self.in_b)
+
             with m.State("get_b"):
-                self.get_op(m, self.in_b, b, "special_cases")
+                getb.action(m)
+                with m.If(getb.out_decode):
+                    m.d.sync += b.decode(self.in_b.v)
+                #self.get_op(m, self.in_b, b, "special_cases")
 
             # ******
             # special cases: NaNs, infs, zeros, denormalised
@@ -72,36 +95,36 @@ class FPDIV(FPBase):
             with m.State("special_cases"):
 
                 # if a is NaN or b is NaN return NaN
-                with m.If(a.is_nan() | b.is_nan()):
+                with m.If(a.is_nan | b.is_nan):
                     m.next = "put_z"
                     m.d.sync += z.nan(1)
 
                 # if a is Inf and b is Inf return NaN
-                with m.Elif(a.is_inf() & b.is_inf()):
+                with m.Elif(a.is_inf & b.is_inf):
                     m.next = "put_z"
                     m.d.sync += z.nan(1)
 
                 # if a is inf return inf (or NaN if b is zero)
-                with m.Elif(a.is_inf()):
+                with m.Elif(a.is_inf):
                     m.next = "put_z"
                     m.d.sync += z.inf(a.s ^ b.s)
 
                 # if b is inf return zero
-                with m.Elif(b.is_inf()):
+                with m.Elif(b.is_inf):
                     m.next = "put_z"
                     m.d.sync += z.zero(a.s ^ b.s)
 
                 # if a is zero return zero (or NaN if b is zero)
-                with m.Elif(a.is_zero()):
+                with m.Elif(a.is_zero):
                     m.next = "put_z"
                     # if b is zero return NaN
-                    with m.If(b.is_zero()):
+                    with m.If(b.is_zero):
                         m.d.sync += z.nan(1)
                     with m.Else():
                         m.d.sync += z.zero(a.s ^ b.s)
 
                 # if b is zero return Inf
-                with m.Elif(b.is_zero()):
+                with m.Elif(b.is_zero):
                     m.next = "put_z"
                     m.d.sync += z.inf(a.s ^ b.s)
 
@@ -194,7 +217,8 @@ class FPDIV(FPBase):
             # rounding stage
 
             with m.State("round"):
-                self.roundz(m, z, of, "corrections")
+                self.roundz(m, z, of.roundz)
+                m.next = "corrections"
 
             # ******
             # correction stage