create separate modules for fpnum in and out
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 20 Feb 2019 04:26:31 +0000 (04:26 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 20 Feb 2019 04:26:31 +0000 (04:26 +0000)
src/add/fpbase.py
src/add/nmigen_add_experiment.py

index a680730c470432498a3683acb0daa7e5f57cf9cf..592a3f72a34cb7dd0a1163b0474971af17f66a8c 100644 (file)
@@ -56,17 +56,8 @@ class MultiShift:
         return res
 
 
-class FPNum:
-    """ Floating-point Number Class, variable-width TODO (currently 32-bit)
-
-        Contains signals for an incoming copy of the value, decoded into
-        sign / exponent / mantissa.
-        Also contains encoding functions, creation and recognition of
-        zero, NaN and inf (all signed)
-
-        Four extra bits are included in the mantissa: the top bit
-        (m[-1]) is effectively a carry-overflow.  The other three are
-        guard (m[2]), round (m[1]), and sticky (m[0])
+class FPNumBase:
+    """ Floating-point Base Number Class
     """
     def __init__(self, width, m_extra=True):
         self.width = width
@@ -117,6 +108,83 @@ class FPNum:
 
         return m
 
+    def _is_nan(self):
+        return (self.e == self.P128) & (self.m != 0)
+
+    def _is_inf(self):
+        return (self.e == self.P128) & (self.m == 0)
+
+    def _is_zero(self):
+        return (self.e == self.N127) & (self.m == self.mzero)
+
+    def _is_overflowed(self):
+        return (self.e > self.P127)
+
+    def _is_denormalised(self):
+        return (self.e == self.N126) & (self.m[self.e_start] == 0)
+
+
+class FPNumOut(FPNumBase):
+    """ Floating-point Number Class, variable-width TODO (currently 32-bit)
+
+        Contains signals for an incoming copy of the value, decoded into
+        sign / exponent / mantissa.
+        Also contains encoding functions, creation and recognition of
+        zero, NaN and inf (all signed)
+
+        Four extra bits are included in the mantissa: the top bit
+        (m[-1]) is effectively a carry-overflow.  The other three are
+        guard (m[2]), round (m[1]), and sticky (m[0])
+    """
+    def __init__(self, width, m_extra=True):
+        FPNumBase.__init__(self, width, m_extra)
+
+    def elaborate(self, platform):
+        m = FPNumBase.elaborate(self, platform)
+
+        return m
+
+    def create(self, s, e, m):
+        """ creates a value from sign / exponent / mantissa
+
+            bias is added here, to the exponent
+        """
+        return [
+          self.v[-1].eq(s),          # sign
+          self.v[self.e_start:self.e_end].eq(e + self.P127), # exp (add on bias)
+          self.v[0:self.e_start].eq(m)         # mantissa
+        ]
+
+    def nan(self, s):
+        return self.create(s, self.P128, 1<<(self.e_start-1))
+
+    def inf(self, s):
+        return self.create(s, self.P128, 0)
+
+    def zero(self, s):
+        return self.create(s, self.N127, 0)
+
+
+class FPNumIn(FPNumBase):
+    """ Floating-point Number Class, variable-width TODO (currently 32-bit)
+
+        Contains signals for an incoming copy of the value, decoded into
+        sign / exponent / mantissa.
+        Also contains encoding functions, creation and recognition of
+        zero, NaN and inf (all signed)
+
+        Four extra bits are included in the mantissa: the top bit
+        (m[-1]) is effectively a carry-overflow.  The other three are
+        guard (m[2]), round (m[1]), and sticky (m[0])
+    """
+    def __init__(self, width, m_extra=True):
+        FPNumBase.__init__(self, width, m_extra)
+
+    def elaborate(self, platform):
+        m = FPNumBase.elaborate(self, platform)
+
+        return m
+
     def decode(self, v):
         """ decodes a latched value into sign / exponent / mantissa
 
@@ -131,17 +199,6 @@ class FPNum:
                 self.s.eq(v[-1]),                 # sign
                 ]
 
-    def create(self, s, e, m):
-        """ creates a value from sign / exponent / mantissa
-
-            bias is added here, to the exponent
-        """
-        return [
-          self.v[-1].eq(s),          # sign
-          self.v[self.e_start:self.e_end].eq(e + self.P127), # exp (add on bias)
-          self.v[0:self.e_start].eq(m)         # mantissa
-        ]
-
     def shift_down(self):
         """ shifts a mantissa down by one. exponent is increased to compensate
 
@@ -190,31 +247,6 @@ class FPNum:
                 self.m.eq(sm.lshift(self.m, maxslen))
                ]
 
-    def nan(self, s):
-        return self.create(s, self.P128, 1<<(self.e_start-1))
-
-    def inf(self, s):
-        return self.create(s, self.P128, 0)
-
-    def zero(self, s):
-        return self.create(s, self.N127, 0)
-
-    def _is_nan(self):
-        return (self.e == self.P128) & (self.m != 0)
-
-    def _is_inf(self):
-        return (self.e == self.P128) & (self.m == 0)
-
-    def _is_zero(self):
-        return (self.e == self.N127) & (self.m == self.mzero)
-
-    def _is_overflowed(self):
-        return (self.e > self.P127)
-
-    def _is_denormalised(self):
-        return (self.e == self.N126) & (self.m[self.e_start] == 0)
-
-
 class FPOp:
     def __init__(self, width):
         self.width = width
index 9f172cc87e28f608ec23eb648f7a7f88d138b767..b1e633ebf79286952346a18aa49ec685ad563396 100644 (file)
@@ -5,7 +5,7 @@
 from nmigen import Module, Signal, Cat
 from nmigen.cli import main, verilog
 
-from fpbase import FPNum, FPOp, Overflow, FPBase
+from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase
 
 
 class FPADD(FPBase):
@@ -25,9 +25,9 @@ class FPADD(FPBase):
         m = Module()
 
         # Latches
-        a = FPNum(self.width)
-        b = FPNum(self.width)
-        z = FPNum(self.width, False)
+        a = FPNumIn(self.width)
+        b = FPNumIn(self.width)
+        z = FPNumOut(self.width, False)
 
         m.submodules.fpnum_a = a
         m.submodules.fpnum_b = b