From: Luke Kenneth Casson Leighton Date: Wed, 20 Feb 2019 04:26:31 +0000 (+0000) Subject: create separate modules for fpnum in and out X-Git-Tag: ls180-24jan2020~1858 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ad854557f228ce234a0bfa41e8b315f2a54f8f4d;p=ieee754fpu.git create separate modules for fpnum in and out --- diff --git a/src/add/fpbase.py b/src/add/fpbase.py index a680730c..592a3f72 100644 --- a/src/add/fpbase.py +++ b/src/add/fpbase.py @@ -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 diff --git a/src/add/nmigen_add_experiment.py b/src/add/nmigen_add_experiment.py index 9f172cc8..b1e633eb 100644 --- a/src/add/nmigen_add_experiment.py +++ b/src/add/nmigen_add_experiment.py @@ -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