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 ieee754.fpcommon.fpbase import FPNumBaseRecord
 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):
@@ -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)
 
-        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)
@@ -81,5 +54,3 @@ class FPAddDeNormMod(PipeModBase):
         comb += self.o.oz.eq(self.i.oz)
 
         return m
-
-