move fpcvt downsize to separate module
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 28 Jul 2019 20:23:51 +0000 (21:23 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 28 Jul 2019 20:23:51 +0000 (21:23 +0100)
src/ieee754/fcvt/downsize.py [new file with mode: 0644]
src/ieee754/fcvt/pipeline.py

diff --git a/src/ieee754/fcvt/downsize.py b/src/ieee754/fcvt/downsize.py
new file mode 100644 (file)
index 0000000..64fd096
--- /dev/null
@@ -0,0 +1,150 @@
+# IEEE754 Floating Point Conversion
+# Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+
+
+import sys
+import functools
+
+from nmigen import Module, Signal, Cat, Const, Mux, Elaboratable
+from nmigen.cli import main, verilog
+
+from nmutil.singlepipe import ControlBase
+from nmutil.concurrentunit import ReservationStations, num_bits
+
+from ieee754.fpcommon.fpbase import Overflow
+from ieee754.fpcommon.getop import FPADDBaseData
+from ieee754.fpcommon.pack import FPPackData
+from ieee754.fpcommon.normtopack import FPNormToPack
+from ieee754.fpcommon.postcalc import FPAddStage1Data
+from ieee754.fpcommon.msbhigh import FPMSBHigh
+from ieee754.fpcommon.exphigh import FPEXPHigh
+
+
+from nmigen import Module, Signal, Elaboratable
+from math import log
+
+from ieee754.fpcommon.fpbase import FPNumIn, FPNumOut, FPNumBaseRecord
+from ieee754.fpcommon.fpbase import FPState, FPNumBase
+from ieee754.fpcommon.getop import FPPipeContext
+
+from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord
+from nmutil.singlepipe import SimpleHandshake, StageChain
+
+from ieee754.fpcommon.fpbase import FPState
+from ieee754.pipeline import PipelineSpec
+
+
+class FPCVTDownConvertMod(Elaboratable):
+    """ FP down-conversion (higher to lower bitwidth)
+    """
+    def __init__(self, in_pspec, out_pspec):
+        self.in_pspec = in_pspec
+        self.out_pspec = out_pspec
+        self.i = self.ispec()
+        self.o = self.ospec()
+
+    def ispec(self):
+        return FPADDBaseData(self.in_pspec)
+
+    def ospec(self):
+        return FPAddStage1Data(self.out_pspec, e_extra=True)
+
+    def setup(self, m, i):
+        """ links module to inputs and outputs
+        """
+        m.submodules.downconvert = self
+        m.d.comb += self.i.eq(i)
+
+    def process(self, i):
+        return self.o
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+
+        #m.submodules.sc_out_z = self.o.z
+
+        # decode: XXX really should move to separate stage
+        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)
+        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)
+
+        me = a1.rmw
+        ms = a1.rmw - self.o.z.rmw
+        print("ms-me", ms, me)
+
+        # intermediaries
+        exp_sub_n126 = Signal((a1.e_width, True), reset_less=True)
+        exp_gt127 = Signal(reset_less=True)
+        # constants from z1, at the bit-width of a1.
+        N126 = Const(z1.fp.N126.value, (a1.e_width, True))
+        P127 = Const(z1.fp.P127.value, (a1.e_width, True))
+        comb += exp_sub_n126.eq(a1.e - N126)
+        comb += exp_gt127.eq(a1.e > P127)
+
+        # if a zero, return zero (signed)
+        with m.If(a1.exp_n127):
+            comb += self.o.z.zero(a1.s)
+            comb += self.o.out_do_z.eq(1)
+
+        # if a range outside z's min range (-126)
+        with m.Elif(exp_sub_n126 < 0):
+            comb += self.o.of.guard.eq(a1.m[ms-1])
+            comb += self.o.of.round_bit.eq(a1.m[ms-2])
+            comb += self.o.of.sticky.eq(a1.m[:ms-2].bool())
+            comb += self.o.of.m0.eq(a1.m[ms])  # bit of a1
+
+            comb += self.o.z.s.eq(a1.s)
+            comb += self.o.z.e.eq(a1.e)
+            comb += self.o.z.m.eq(a1.m[-self.o.z.rmw-1:])
+            comb += self.o.z.m[-1].eq(1)
+
+        # if a is inf return inf
+        with m.Elif(a1.is_inf):
+            comb += self.o.z.inf(a1.s)
+            comb += self.o.out_do_z.eq(1)
+
+        # if a is NaN return NaN
+        with m.Elif(a1.is_nan):
+            comb += self.o.z.nan(0)
+            comb += self.o.out_do_z.eq(1)
+
+        # if a mantissa greater than 127, return inf
+        with m.Elif(exp_gt127):
+            print("inf", self.o.z.inf(a1.s))
+            comb += self.o.z.inf(a1.s)
+            comb += self.o.out_do_z.eq(1)
+
+        # ok after all that, anything else should fit fine (whew)
+        with m.Else():
+            comb += self.o.of.guard.eq(a1.m[ms-1])
+            comb += self.o.of.round_bit.eq(a1.m[ms-2])
+            comb += self.o.of.sticky.eq(a1.m[:ms-2].bool())
+            comb += self.o.of.m0.eq(a1.m[ms])  # bit of a1
+
+            # XXX TODO: this is basically duplicating FPRoundMod. hmmm...
+            print("alen", a1.e_start, z1.fp.N126, N126)
+            print("m1", self.o.z.rmw, a1.m[-self.o.z.rmw-1:])
+            mo = Signal(self.o.z.m_width-1)
+            comb += mo.eq(a1.m[ms:me])
+            with m.If(self.o.of.roundz):
+                with m.If((~mo == 0)):  # all 1s
+                    comb += self.o.z.create(a1.s, a1.e+1, mo+1)
+                with m.Else():
+                    comb += self.o.z.create(a1.s, a1.e, mo+1)
+            with m.Else():
+                comb += self.o.z.create(a1.s, a1.e, a1.m[-self.o.z.rmw-1:])
+            comb += self.o.out_do_z.eq(1)
+
+        # copy the context (muxid, operator)
+        comb += self.o.oz.eq(self.o.z.v)
+        comb += self.o.ctx.eq(self.i.ctx)
+
+        return m
+
+
index cc5fdbc23bb7ecd1b44e22dd92be6debd91895e6..13e3e61a1b374b17341eee41f3ffda832c884020 100644 (file)
@@ -36,6 +36,7 @@ from ieee754.pipeline import PipelineSpec
 from ieee754.fcvt.float2int import FPCVTFloatToIntMod
 from ieee754.fcvt.int2float import FPCVTIntToFloatMod
 from ieee754.fcvt.upsize import FPCVTUpConvertMod
+from ieee754.fcvt.downsize import FPCVTDownConvertMod
 
 
 class SignedOp:
@@ -46,120 +47,6 @@ class SignedOp:
         return [self.signed.eq(i)]
 
 
-class FPCVTDownConvertMod(Elaboratable):
-    """ FP down-conversion (higher to lower bitwidth)
-    """
-    def __init__(self, in_pspec, out_pspec):
-        self.in_pspec = in_pspec
-        self.out_pspec = out_pspec
-        self.i = self.ispec()
-        self.o = self.ospec()
-
-    def ispec(self):
-        return FPADDBaseData(self.in_pspec)
-
-    def ospec(self):
-        return FPAddStage1Data(self.out_pspec, e_extra=True)
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        m.submodules.downconvert = self
-        comb += self.i.eq(i)
-
-    def process(self, i):
-        return self.o
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-
-        #m.submodules.sc_out_z = self.o.z
-
-        # decode: XXX really should move to separate stage
-        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)
-        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)
-
-        me = a1.rmw
-        ms = a1.rmw - self.o.z.rmw
-        print("ms-me", ms, me)
-
-        # intermediaries
-        exp_sub_n126 = Signal((a1.e_width, True), reset_less=True)
-        exp_gt127 = Signal(reset_less=True)
-        # constants from z1, at the bit-width of a1.
-        N126 = Const(z1.fp.N126.value, (a1.e_width, True))
-        P127 = Const(z1.fp.P127.value, (a1.e_width, True))
-        comb += exp_sub_n126.eq(a1.e - N126)
-        comb += exp_gt127.eq(a1.e > P127)
-
-        # if a zero, return zero (signed)
-        with m.If(a1.exp_n127):
-            comb += self.o.z.zero(a1.s)
-            comb += self.o.out_do_z.eq(1)
-
-        # if a range outside z's min range (-126)
-        with m.Elif(exp_sub_n126 < 0):
-            comb += self.o.of.guard.eq(a1.m[ms-1])
-            comb += self.o.of.round_bit.eq(a1.m[ms-2])
-            comb += self.o.of.sticky.eq(a1.m[:ms-2].bool())
-            comb += self.o.of.m0.eq(a1.m[ms])  # bit of a1
-
-            comb += self.o.z.s.eq(a1.s)
-            comb += self.o.z.e.eq(a1.e)
-            comb += self.o.z.m.eq(a1.m[-self.o.z.rmw-1:])
-            comb += self.o.z.m[-1].eq(1)
-
-        # if a is inf return inf
-        with m.Elif(a1.is_inf):
-            comb += self.o.z.inf(a1.s)
-            comb += self.o.out_do_z.eq(1)
-
-        # if a is NaN return NaN
-        with m.Elif(a1.is_nan):
-            comb += self.o.z.nan(0)
-            comb += self.o.out_do_z.eq(1)
-
-        # if a mantissa greater than 127, return inf
-        with m.Elif(exp_gt127):
-            print("inf", self.o.z.inf(a1.s))
-            comb += self.o.z.inf(a1.s)
-            comb += self.o.out_do_z.eq(1)
-
-        # ok after all that, anything else should fit fine (whew)
-        with m.Else():
-            comb += self.o.of.guard.eq(a1.m[ms-1])
-            comb += self.o.of.round_bit.eq(a1.m[ms-2])
-            comb += self.o.of.sticky.eq(a1.m[:ms-2].bool())
-            comb += self.o.of.m0.eq(a1.m[ms])  # bit of a1
-
-            # XXX TODO: this is basically duplicating FPRoundMod. hmmm...
-            print("alen", a1.e_start, z1.fp.N126, N126)
-            print("m1", self.o.z.rmw, a1.m[-self.o.z.rmw-1:])
-            mo = Signal(self.o.z.m_width-1)
-            comb += mo.eq(a1.m[ms:me])
-            with m.If(self.o.of.roundz):
-                with m.If((~mo == 0)):  # all 1s
-                    comb += self.o.z.create(a1.s, a1.e+1, mo+1)
-                with m.Else():
-                    comb += self.o.z.create(a1.s, a1.e, mo+1)
-            with m.Else():
-                comb += self.o.z.create(a1.s, a1.e, a1.m[-self.o.z.rmw-1:])
-            comb += self.o.out_do_z.eq(1)
-
-        # copy the context (muxid, operator)
-        comb += self.o.oz.eq(self.o.z.v)
-        comb += self.o.ctx.eq(self.i.ctx)
-
-        return m
-
-
 class FPCVTConvertDeNorm(FPState, SimpleHandshake):
     """ FPConversion and De-norm
     """