From 39be660b8a61d2af1348f4fedf507f2c492529c4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 20 Feb 2019 02:30:03 +0000 Subject: [PATCH] create module for FPNum --- src/add/fpbase.py | 32 ++++++++++++++++++----- src/add/nmigen_add_experiment.py | 45 +++++++++++--------------------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/add/fpbase.py b/src/add/fpbase.py index d6ac60eb..fff94450 100644 --- a/src/add/fpbase.py +++ b/src/add/fpbase.py @@ -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) diff --git a/src/add/nmigen_add_experiment.py b/src/add/nmigen_add_experiment.py index 97e2fdf9..1a28ba91 100644 --- a/src/add/nmigen_add_experiment.py +++ b/src/add/nmigen_add_experiment.py @@ -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]) -- 2.30.2