From: Luke Kenneth Casson Leighton Date: Wed, 31 Jul 2019 12:15:32 +0000 (+0100) Subject: tidyup, use FPModBaseChain and FPModBase X-Git-Tag: ls180-24jan2020~633 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2cf4eb423fe183b573991b375b2292025b52b907;p=ieee754fpu.git tidyup, use FPModBaseChain and FPModBase --- diff --git a/src/ieee754/fpmul/specialcases.py b/src/ieee754/fpmul/specialcases.py index eb3fe50a..d4eb3c82 100644 --- a/src/ieee754/fpmul/specialcases.py +++ b/src/ieee754/fpmul/specialcases.py @@ -1,28 +1,25 @@ # IEEE Floating Point Multiplier -from nmigen import Module, Signal, Cat, Const, Elaboratable +from nmigen import Module, Signal, Cat, Const from nmigen.cli import main, verilog from math import log from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord -from nmutil.singlepipe import StageChain -from ieee754.pipeline import DynamicPipe +from ieee754.fpcommon.modbase import FPModBase, FPModBaseChain from ieee754.fpcommon.getop import FPADDBaseData from ieee754.fpcommon.denorm import (FPSCData, FPAddDeNormMod) from ieee754.fpmul.align import FPAlignModSingle -class FPMulSpecialCasesMod(Elaboratable): +class FPMulSpecialCasesMod(FPModBase): """ special cases: NaNs, infs, zeros, denormalised see "Special Operations" https://steve.hollasch.net/cgindex/coding/ieeefloat.html """ def __init__(self, pspec): - self.pspec = pspec - self.i = self.ispec() - self.o = self.ospec() + super().__init__(pspec, "specialcases") def ispec(self): return FPADDBaseData(self.pspec) @@ -30,19 +27,9 @@ class FPMulSpecialCasesMod(Elaboratable): def ospec(self): return FPSCData(self.pspec, False) - def setup(self, m, i): - """ links module to inputs and outputs - """ - m.submodules.specialcases = self - m.d.comb += self.i.eq(i) - - def process(self, i): - return self.o - def elaborate(self, platform): m = Module() - - #m.submodules.sc_out_z = self.o.z + comb = m.d.comb # decode: XXX really should move to separate stage width = self.pspec.width @@ -50,87 +37,67 @@ class FPMulSpecialCasesMod(Elaboratable): b1 = FPNumBaseRecord(width, False) m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1) m.submodules.sc_decode_b = b1 = FPNumDecode(None, b1) - m.d.comb += [a1.v.eq(self.i.a), + comb += [a1.v.eq(self.i.a), b1.v.eq(self.i.b), self.o.a.eq(a1), self.o.b.eq(b1) ] obz = Signal(reset_less=True) - m.d.comb += obz.eq(a1.is_zero | b1.is_zero) + comb += obz.eq(a1.is_zero | b1.is_zero) sabx = Signal(reset_less=True) # sign a xor b (sabx, get it?) - m.d.comb += sabx.eq(a1.s ^ b1.s) + comb += sabx.eq(a1.s ^ b1.s) abnan = Signal(reset_less=True) - m.d.comb += abnan.eq(a1.is_nan | b1.is_nan) + comb += abnan.eq(a1.is_nan | b1.is_nan) # if a is NaN or b is NaN return NaN with m.If(abnan): - m.d.comb += self.o.out_do_z.eq(1) - m.d.comb += self.o.z.nan(0) + comb += self.o.out_do_z.eq(1) + comb += self.o.z.nan(0) # if a is inf return inf (or NaN) with m.Elif(a1.is_inf): - m.d.comb += self.o.out_do_z.eq(1) - m.d.comb += self.o.z.inf(sabx) + comb += self.o.out_do_z.eq(1) + comb += self.o.z.inf(sabx) # b is zero return NaN with m.If(b1.is_zero): - m.d.comb += self.o.z.nan(0) + comb += self.o.z.nan(0) # if b is inf return inf (or NaN) with m.Elif(b1.is_inf): - m.d.comb += self.o.out_do_z.eq(1) - m.d.comb += self.o.z.inf(sabx) + comb += self.o.out_do_z.eq(1) + comb += self.o.z.inf(sabx) # a is zero return NaN with m.If(a1.is_zero): - m.d.comb += self.o.z.nan(0) + comb += self.o.z.nan(0) # if a is zero or b zero return signed-a/b with m.Elif(obz): - m.d.comb += self.o.out_do_z.eq(1) - m.d.comb += self.o.z.zero(sabx) + comb += self.o.out_do_z.eq(1) + comb += self.o.z.zero(sabx) # Denormalised Number checks next, so pass a/b data through with m.Else(): - m.d.comb += self.o.out_do_z.eq(0) + comb += self.o.out_do_z.eq(0) - m.d.comb += self.o.oz.eq(self.o.z.v) - m.d.comb += self.o.ctx.eq(self.i.ctx) + comb += self.o.oz.eq(self.o.z.v) + comb += self.o.ctx.eq(self.i.ctx) return m -class FPMulSpecialCasesDeNorm(DynamicPipe): +class FPMulSpecialCasesDeNorm(FPModBaseChain): """ special cases: NaNs, infs, zeros, denormalised """ - def __init__(self, pspec): - self.pspec = pspec - super().__init__(pspec) - self.out = self.ospec() - - def ispec(self): - return FPADDBaseData(self.pspec) - - def ospec(self): - return FPSCData(self.pspec, False) - - def setup(self, m, i): - """ links module to inputs and outputs + def get_chain(self): + """ gets chain of modules """ smod = FPMulSpecialCasesMod(self.pspec) dmod = FPAddDeNormMod(self.pspec, False) amod = FPAlignModSingle(self.pspec, False) - chain = StageChain([smod, dmod, amod]) - chain.setup(m, i) - - # only needed for break-out (early-out) - # self.out_do_z = smod.o.out_do_z - - self.o = amod.o # output is from last .o in the chain - - def process(self, i): - return self.o + return [smod, dmod, amod]