From faf8b3134e6a445ba721f8c3a2117462ed509eba Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 5 Jul 2019 23:53:21 +0100 Subject: [PATCH] sorting out fcvt --- src/ieee754/fcvt/pipeline.py | 40 +++++++++++++++--------------- src/ieee754/fpcommon/fpbase.py | 13 +++++++--- src/ieee754/fpcommon/postcalc.py | 4 +-- src/ieee754/fpcommon/test/fpmux.py | 3 +++ 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/ieee754/fcvt/pipeline.py b/src/ieee754/fcvt/pipeline.py index 7926be9a..b5323f7a 100644 --- a/src/ieee754/fcvt/pipeline.py +++ b/src/ieee754/fcvt/pipeline.py @@ -47,7 +47,7 @@ class FPCVTSpecialCasesMod(Elaboratable): return FPADDBaseData(self.in_pspec) def ospec(self): - return FPAddStage1Data(self.out_pspec) + return FPAddStage1Data(self.out_pspec, e_extra=True) def setup(self, m, i): """ links module to inputs and outputs @@ -67,9 +67,11 @@ class FPCVTSpecialCasesMod(Elaboratable): print ("in_width out", self.in_pspec['width'], self.out_pspec['width']) a1 = FPNumBaseRecord(self.in_pspec['width'], False) + print ("a1", a1.width, a1.rmw, a1.e_width, a1.e_start, a1.e_end) m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1) m.d.comb += a1.v.eq(self.i.a) z1 = self.o.z + print ("z1", z1.width, z1.rmw, z1.e_width, z1.e_start, z1.e_end) # set sign m.d.comb += self.o.z.s.eq(a1.s) @@ -85,44 +87,42 @@ class FPCVTSpecialCasesMod(Elaboratable): # if a zero, return zero (signed) with m.If(a1.exp_n127): - _, ze, zm = self.o.z._zero(a1.s) - m.d.comb += self.o.z.e.eq(ze) - m.d.comb += self.o.z.m.eq(zm) + m.d.comb += self.o.z.zero(a1.s) + m.d.comb += self.o.out_do_z.eq(1) - # if a range within z min range (-126) + # if a range outside z's min range (-126) with m.Elif(exp_sub_n126 < 0): m.d.comb += self.o.z.e.eq(a1.e) - m.d.comb += self.o.z.m.eq(a1.m[-self.o.z.rmw:]) - m.d.comb += self.o.of.guard.eq(a1.m[-self.o.z.rmw-1]) - m.d.comb += self.o.of.round_bit.eq(a1.m[-self.o.z.rmw-2]) - m.d.comb += self.o.of.sticky.eq(a1.m[:-self.o.z.rmw-2] != 0) + m.d.comb += self.o.z.m.eq(a1.m[-self.o.z.rmw-1:]) + m.d.comb += self.o.of.guard.eq(a1.m[-self.o.z.rmw-2]) + m.d.comb += self.o.of.round_bit.eq(a1.m[-self.o.z.rmw-3]) + m.d.comb += self.o.of.sticky.eq(a1.m[:-self.o.z.rmw-3] != 0) # if a is inf return inf with m.Elif(a1.is_inf): - _, ze, zm = self.o.z._inf(a1.s) - m.d.comb += self.o.z.e.eq(ze) - m.d.comb += self.o.z.m.eq(zm) + m.d.comb += self.o.z.inf(a1.s) + m.d.comb += self.o.out_do_z.eq(1) # if a is NaN return NaN with m.Elif(a1.is_nan): - _, ze, zm = self.o.z._nan(a1.s) - m.d.comb += self.o.z.e.eq(ze) - m.d.comb += self.o.z.m.eq(zm) + m.d.comb += self.o.z.nan(a1.s) + m.d.comb += self.o.out_do_z.eq(1) # if a mantissa greater than 127, return inf with m.Elif(exp_gt127): - _, ze, zm = self.o.z._inf(a1.s) - m.d.comb += self.o.z.e.eq(ze) - m.d.comb += self.o.z.m.eq(zm) + m.d.comb += self.o.z.inf(a1.s) + m.d.comb += self.o.out_do_z.eq(1) # ok after all that, anything else should fit fine (whew) with m.Else(): m.d.comb += self.o.z.e.eq(a1.e) print ("alen", a1.e_start, z1.fp.N126, N126) - print ("m1", self.o.z.rmw, a1.m[-self.o.z.rmw:]) - m.d.comb += self.o.z.m.eq(a1.m[-self.o.z.rmw:]) + print ("m1", self.o.z.rmw, a1.m[-self.o.z.rmw-1:]) + m.d.comb += self.o.z.create(a1.s, a1.e, a1.m[-self.o.z.rmw-1:]) + m.d.comb += self.o.out_do_z.eq(1) # copy the context (muxid, operator) + m.d.comb += self.o.oz.eq(self.o.z.v) m.d.comb += self.o.ctx.eq(self.i.ctx) return m diff --git a/src/ieee754/fpcommon/fpbase.py b/src/ieee754/fpcommon/fpbase.py index f25264fa..ca889918 100644 --- a/src/ieee754/fpcommon/fpbase.py +++ b/src/ieee754/fpcommon/fpbase.py @@ -63,12 +63,12 @@ class MultiShift: class FPNumBaseRecord: """ Floating-point Base Number Class """ - def __init__(self, width, m_extra=True): + def __init__(self, width, m_extra=True, e_extra=False): self.width = width m_width = {16: 11, 32: 24, 64: 53}[width] # 1 extra bit (overflow) e_width = {16: 7, 32: 10, 64: 13}[width] # 2 extra bits (overflow) e_max = 1<<(e_width-3) - self.rmw = m_width # real mantissa width (not including extras) + self.rmw = m_width - 1 # real mantissa width (not including extras) self.e_max = e_max if m_extra: # mantissa extra bits (top,guard,round) @@ -76,11 +76,16 @@ class FPNumBaseRecord: m_width += self.m_extra else: self.m_extra = 0 + if e_extra: + self.e_extra = 3 + e_width += self.e_extra + else: + self.e_extra = 0 #print (m_width, e_width, e_max, self.rmw, self.m_extra) self.m_width = m_width self.e_width = e_width - self.e_start = self.rmw - 1 - self.e_end = self.rmw + self.e_width - 3 # for decoding + self.e_start = self.rmw + self.e_end = self.rmw + self.e_width - 2 # for decoding self.v = Signal(width, reset_less=True) # Latched copy of value self.m = Signal(m_width, reset_less=True) # Mantissa diff --git a/src/ieee754/fpcommon/postcalc.py b/src/ieee754/fpcommon/postcalc.py index c8a0090e..47c7d8d5 100644 --- a/src/ieee754/fpcommon/postcalc.py +++ b/src/ieee754/fpcommon/postcalc.py @@ -8,9 +8,9 @@ from ieee754.fpcommon.getop import FPPipeContext class FPAddStage1Data: - def __init__(self, pspec): + def __init__(self, pspec, e_extra=False): width = pspec['width'] - self.z = FPNumBaseRecord(width, False) + self.z = FPNumBaseRecord(width, False, e_extra) self.out_do_z = Signal(reset_less=True) self.oz = Signal(width, reset_less=True) self.of = Overflow() diff --git a/src/ieee754/fpcommon/test/fpmux.py b/src/ieee754/fpcommon/test/fpmux.py index 5cbdf23d..63871dad 100644 --- a/src/ieee754/fpcommon/test/fpmux.py +++ b/src/ieee754/fpcommon/test/fpmux.py @@ -126,6 +126,9 @@ class InputTestRandom(InputTest): for i in range(n_vals): if single_op: op1 = randint(0, (1<