create module for FPNum
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 20 Feb 2019 02:30:03 +0000 (02:30 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 20 Feb 2019 02:30:03 +0000 (02:30 +0000)
src/add/fpbase.py
src/add/nmigen_add_experiment.py

index d6ac60ebe2e8680c3922bde37b8f4130ffce364f..fff9445048fbcc23885da9b5e5c51b0a6b9520c9 100644 (file)
@@ -99,6 +99,24 @@ class FPNum:
         self.N127 = Const(-(e_max-1), (e_width, True))
         self.N126 = Const(-(e_max-2), (e_width, True))
 
+        self.is_nan = Signal(reset_less=True)
+        self.is_zero = Signal(reset_less=True)
+        self.is_inf = Signal(reset_less=True)
+        self.is_overflowed = Signal(reset_less=True)
+        self.is_denormalised = Signal(reset_less=True)
+        self.exp_128 = Signal(reset_less=True)
+
+    def elaborate(self, platform):
+        m = Module()
+        m.d.comb += self.is_nan.eq(self._is_nan())
+        m.d.comb += self.is_zero.eq(self._is_zero())
+        m.d.comb += self.is_inf.eq(self._is_inf())
+        m.d.comb += self.is_overflowed.eq(self._is_overflowed())
+        m.d.comb += self.is_denormalised.eq(self._is_denormalised())
+        m.d.comb += self.exp_128.eq(self.e == self.P128)
+
+        return m
+
     def decode(self, v):
         """ decodes a latched value into sign / exponent / mantissa
 
@@ -181,19 +199,19 @@ class FPNum:
     def zero(self, s):
         return self.create(s, self.N127, 0)
 
-    def is_nan(self):
+    def _is_nan(self):
         return (self.e == self.P128) & (self.m != 0)
 
-    def is_inf(self):
+    def _is_inf(self):
         return (self.e == self.P128) & (self.m == 0)
 
-    def is_zero(self):
+    def _is_zero(self):
         return (self.e == self.N127) & (self.m == self.mzero)
 
-    def is_overflowed(self):
+    def _is_overflowed(self):
         return (self.e > self.P127)
 
-    def is_denormalised(self):
+    def _is_denormalised(self):
         return (self.e == self.N126) & (self.m[self.e_start] == 0)
 
 
@@ -320,7 +338,7 @@ class FPBase:
         """
         m.next = next_state
         # denormalised, correct exponent to zero
-        with m.If(z.is_denormalised()):
+        with m.If(z.is_denormalised):
             m.d.sync += z.e.eq(z.N127)
 
     def pack(self, m, z, next_state):
@@ -328,7 +346,7 @@ class FPBase:
         """
         m.next = next_state
         # if overflow occurs, return inf
-        with m.If(z.is_overflowed()):
+        with m.If(z.is_overflowed):
             m.d.sync += z.inf(z.s)
         with m.Else():
             m.d.sync += z.create(z.s, z.e, z.m)
index 97e2fdf99ca5dd68ce96fc73f0b6b0375902dcb4..1a28ba913ab9677f4d230dce6f2774b290284b7b 100644 (file)
@@ -29,6 +29,10 @@ class FPADD(FPBase):
         b = FPNum(self.width)
         z = FPNum(self.width, False)
 
+        m.submodules.fpnum_a = a
+        m.submodules.fpnum_b = b
+        m.submodules.fpnum_z = z
+
         w = z.m_width + 4
         tot = Signal(w, reset_less=True) # sticky/round/guard, {mantissa} result, 1 overflow
 
@@ -55,25 +59,6 @@ class FPADD(FPBase):
 
             with m.State("special_cases"):
 
-                a_nan = Signal()
-                a_zero = Signal()
-                a_inf = Signal()
-
-                b_nan = Signal()
-                b_zero = Signal()
-                b_inf = Signal()
-
-                m.d.comb += a_nan.eq(a.is_nan())
-                m.d.comb += a_zero.eq(a.is_zero())
-                m.d.comb += a_inf.eq(a.is_inf())
-
-                m.d.comb += b_nan.eq(b.is_nan())
-                m.d.comb += b_zero.eq(b.is_zero())
-                m.d.comb += b_inf.eq(b.is_inf())
-
-                b_eq_p128 = Signal()
-                m.d.comb += b_eq_p128.eq(b.e == b.P128)
-
                 s_nomatch = Signal()
                 m.d.comb += s_nomatch.eq(a.s != b.s)
 
@@ -81,7 +66,7 @@ class FPADD(FPBase):
                 m.d.comb += m_match.eq(a.m == b.m)
 
                 # if a is NaN or b is NaN return NaN
-                with m.If(a_nan | b_nan):
+                with m.If(a.is_nan | b.is_nan):
                     m.next = "put_z"
                     m.d.sync += z.nan(1)
 
@@ -89,50 +74,50 @@ class FPADD(FPBase):
                 # under review
 
                 ## if a is zero and b is NaN return -b
-                #with m.If(a_zero & (a.s==0) & b_nan):
+                #with m.If(a.is_zero & (a.s==0) & b.is_nan):
                 #    m.next = "put_z"
                 #    m.d.sync += z.create(b.s, b.e, Cat(b.m[3:-2], ~b.m[0]))
 
                 ## if b is zero and a is NaN return -a
-                #with m.Elif(b_zero & (b.s==0) & a_nan):
+                #with m.Elif(b.is_zero & (b.s==0) & a.is_nan):
                 #    m.next = "put_z"
                 #    m.d.sync += z.create(a.s, a.e, Cat(a.m[3:-2], ~a.m[0]))
 
                 ## if a is -zero and b is NaN return -b
-                #with m.Elif(a_zero & (a.s==1) & b_nan):
+                #with m.Elif(a.is_zero & (a.s==1) & b.is_nan):
                 #    m.next = "put_z"
                 #    m.d.sync += z.create(a.s & b.s, b.e, Cat(b.m[3:-2], 1))
 
                 ## if b is -zero and a is NaN return -a
-                #with m.Elif(b_zero & (b.s==1) & a_nan):
+                #with m.Elif(b.is_zero & (b.s==1) & a.is_nan):
                 #    m.next = "put_z"
                 #    m.d.sync += z.create(a.s & b.s, a.e, Cat(a.m[3:-2], 1))
 
                 # if a is inf return inf (or NaN)
-                with m.Elif(a_inf):
+                with m.Elif(a.is_inf):
                     m.next = "put_z"
                     m.d.sync += z.inf(a.s)
                     # if a is inf and signs don't match return NaN
-                    with m.If(b_eq_p128 & s_nomatch):
+                    with m.If(b.exp_128 & s_nomatch):
                         m.d.sync += z.nan(1)
 
                 # if b is inf return inf
-                with m.Elif(b_inf):
+                with m.Elif(b.is_inf):
                     m.next = "put_z"
                     m.d.sync += z.inf(b.s)
 
                 # if a is zero and b zero return signed-a/b
-                with m.Elif(a_zero & b_zero):
+                with m.Elif(a.is_zero & b.is_zero):
                     m.next = "put_z"
                     m.d.sync += z.create(a.s & b.s, b.e, b.m[3:-1])
 
                 # if a is zero return b
-                with m.Elif(a_zero):
+                with m.Elif(a.is_zero):
                     m.next = "put_z"
                     m.d.sync += z.create(b.s, b.e, b.m[3:-1])
 
                 # if b is zero return a
-                with m.Elif(b_zero):
+                with m.Elif(b.is_zero):
                     m.next = "put_z"
                     m.d.sync += z.create(a.s, a.e, a.m[3:-1])