remove use of out_do_z, use Mux instead of m.If/Else
[ieee754fpu.git] / src / ieee754 / fpcommon / denorm.py
index 52bae10af1190e1c1d5bdc5d1e9ae4fdc1596055..350f413ede9858ae490059f6709b3454ea8a7f1e 100644 (file)
@@ -1,45 +1,16 @@
-# IEEE Floating Point Adder (Single Precision)
-# Copyright (C) Jonathan P Dawson 2013
-# 2013-12-12
+"""IEEE754 Floating Point Library
 
 
-from nmigen import Module, Signal
+Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+
+"""
+
+from nmigen import Module, Mux
 from nmigen.cli import main, verilog
 from math import log
 
 from nmutil.pipemodbase import PipeModBase
 from nmigen.cli import main, verilog
 from math import log
 
 from nmutil.pipemodbase import PipeModBase
-from ieee754.fpcommon.fpbase import FPNumBaseRecord
 from ieee754.fpcommon.fpbase import FPNumBase
 from ieee754.fpcommon.fpbase import FPNumBase
-from ieee754.fpcommon.getop import FPPipeContext
-
-
-class FPSCData:
-
-    def __init__(self, pspec, m_extra):
-        width = pspec.width
-        # NOTE: difference between z and oz is that oz is created by
-        # special-cases module(s) and will propagate, along with its
-        # "bypass" signal out_do_z, through the pipeline, *disabling*
-        # all processing of all subsequent stages.
-        self.a = FPNumBaseRecord(width, m_extra, name="a")   # operand a
-        self.b = FPNumBaseRecord(width, m_extra, name="b")   # operand b
-        self.z = FPNumBaseRecord(width, False, name="z")     # denormed result
-        self.oz = Signal(width, reset_less=True)   # "finished" (bypass) result
-        self.out_do_z = Signal(reset_less=True)    # "bypass" enabled
-        self.ctx = FPPipeContext(pspec)
-        self.muxid = self.ctx.muxid
-
-    def __iter__(self):
-        yield from self.a
-        yield from self.b
-        yield from self.z
-        yield self.oz
-        yield self.out_do_z
-        yield from self.ctx
-
-    def eq(self, i):
-        ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
-               self.a.eq(i.a), self.b.eq(i.b), self.ctx.eq(i.ctx)]
-        return ret
+from ieee754.fpcommon.pscdata import FPSCData
 
 
 class FPAddDeNormMod(PipeModBase):
 
 
 class FPAddDeNormMod(PipeModBase):
@@ -61,19 +32,21 @@ class FPAddDeNormMod(PipeModBase):
         m.submodules.denorm_in_a = in_a = FPNumBase(self.i.a)
         m.submodules.denorm_in_b = in_b = FPNumBase(self.i.b)
 
         m.submodules.denorm_in_a = in_a = FPNumBase(self.i.a)
         m.submodules.denorm_in_b = in_b = FPNumBase(self.i.b)
 
-        with m.If(~self.i.out_do_z):
-            # XXX hmmm, don't like repeating identical code
-            comb += self.o.a.eq(self.i.a)
-            with m.If(in_a.exp_n127):
-                comb += self.o.a.e.eq(self.i.a.N126)  # limit a exponent
-            with m.Else():
-                comb += self.o.a.m[-1].eq(1)  # set top mantissa bit
-
-            comb += self.o.b.eq(self.i.b)
-            with m.If(in_b.exp_n127):
-                comb += self.o.b.e.eq(self.i.b.N126)  # limit a exponent
-            with m.Else():
-                comb += self.o.b.m[-1].eq(1)  # set top mantissa bit
+        # XXX hmmm, don't like repeating identical code
+        comb += self.o.a.eq(self.i.a)
+        ae = self.i.a.e
+        am = self.i.a.m
+        # either limit exponent, or set top mantissa bit
+        comb += self.o.a.e.eq(Mux(in_a.exp_n127, self.i.a.N126, ae))
+        comb += self.o.a.m[-1].eq(Mux(in_a.exp_n127, am[-1], 1))
+
+        # XXX code now repeated for b
+        comb += self.o.b.eq(self.i.b)
+        be = self.i.b.e
+        bm = self.i.b.m
+        # either limit exponent, or set top mantissa bit
+        comb += self.o.b.e.eq(Mux(in_b.exp_n127, self.i.b.N126, be))
+        comb += self.o.b.m[-1].eq(Mux(in_b.exp_n127, bm[-1], 1))
 
         comb += self.o.ctx.eq(self.i.ctx)
         comb += self.o.z.eq(self.i.z)
 
         comb += self.o.ctx.eq(self.i.ctx)
         comb += self.o.z.eq(self.i.z)
@@ -81,5 +54,3 @@ class FPAddDeNormMod(PipeModBase):
         comb += self.o.oz.eq(self.i.oz)
 
         return m
         comb += self.o.oz.eq(self.i.oz)
 
         return m
-
-