X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fieee754%2Ffpcommon%2Fdenorm.py;h=350f413ede9858ae490059f6709b3454ea8a7f1e;hb=c5e45c972dfdbbb9a32e69528d03177093d7c88f;hp=cea8e2b78e8f8796a3699d224d915e92ee71aa86;hpb=a7d0eedd5131906af7e63ea8f64f8a49b827bb48;p=ieee754fpu.git diff --git a/src/ieee754/fpcommon/denorm.py b/src/ieee754/fpcommon/denorm.py index cea8e2b7..350f413e 100644 --- a/src/ieee754/fpcommon/denorm.py +++ b/src/ieee754/fpcommon/denorm.py @@ -1,125 +1,56 @@ -# IEEE Floating Point Adder (Single Precision) -# Copyright (C) Jonathan P Dawson 2013 -# 2013-12-12 +"""IEEE754 Floating Point Library -from nmigen import Module, Signal, Elaboratable -from nmigen.cli import main, verilog -from math import log - -from ieee754.fpcommon.fpbase import FPNumIn, FPNumOut, FPNumBaseRecord -from ieee754.fpcommon.fpbase import FPState, FPNumBase - - -class FPSCData: - - def __init__(self, width, id_wid, m_extra=True, op_wid=None): +Copyright (C) 2019 Luke Kenneth Casson Leighton - # 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) # operand a - self.b = FPNumBaseRecord(width, m_extra) # operand b - self.z = FPNumBaseRecord(width, False) # denormed result - self.oz = Signal(width, reset_less=True) # "finished" (bypass) result - self.out_do_z = Signal(reset_less=True) # "bypass" enabled - self.mid = Signal(id_wid, reset_less=True) # multiplexer ID - self.op_wid = op_wid - if op_wid: - self.op = Signal(op_wid, reset_less=True) # operand +""" +from nmigen import Module, Mux +from nmigen.cli import main, verilog +from math import log - def __iter__(self): - yield from self.a - yield from self.b - yield from self.z - yield self.oz - yield self.out_do_z - yield self.mid - if op_wid: - yield self.op - - 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.mid.eq(i.mid)] - if self.op_wid: - ret.append(self.op.eq(i.op)) - return ret +from nmutil.pipemodbase import PipeModBase +from ieee754.fpcommon.fpbase import FPNumBase +from ieee754.fpcommon.pscdata import FPSCData -class FPAddDeNormMod(FPState, Elaboratable): +class FPAddDeNormMod(PipeModBase): - def __init__(self, width, id_wid, m_extra=True, op_wid=None): - self.width = width - self.id_wid = id_wid + def __init__(self, pspec, m_extra): self.m_extra = m_extra - self.op_wid = op_wid - self.i = self.ispec() - self.o = self.ospec() + super().__init__(pspec, "denormalise") def ispec(self): - return FPSCData(self.width, self.id_wid, self.m_extra, self.op_wid) + return FPSCData(self.pspec, self.m_extra) def ospec(self): - return FPSCData(self.width, self.id_wid, self.m_extra, self.op_wid) - - def process(self, i): - return self.o - - def setup(self, m, i): - """ links module to inputs and outputs - """ - m.submodules.denormalise = self - m.d.comb += self.i.eq(i) + return FPSCData(self.pspec, self.m_extra) def elaborate(self, platform): m = Module() + comb = m.d.comb + 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_out_a = self.o.a - #m.submodules.denorm_out_b = self.o.b - #m.submodules.denorm_out_z = self.o.z - - with m.If(~self.i.out_do_z): - # XXX hmmm, don't like repeating identical code - m.d.comb += self.o.a.eq(self.i.a) - with m.If(in_a.exp_n127): - m.d.comb += self.o.a.e.eq(self.i.a.N126) # limit a exponent - with m.Else(): - m.d.comb += self.o.a.m[-1].eq(1) # set top mantissa bit - - m.d.comb += self.o.b.eq(self.i.b) - with m.If(in_b.exp_n127): - m.d.comb += self.o.b.e.eq(self.i.b.N126) # limit a exponent - with m.Else(): - m.d.comb += self.o.b.m[-1].eq(1) # set top mantissa bit - m.d.comb += self.o.mid.eq(self.i.mid) - m.d.comb += self.o.z.eq(self.i.z) - m.d.comb += self.o.out_do_z.eq(self.i.out_do_z) - m.d.comb += self.o.oz.eq(self.i.oz) + # 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.out_do_z.eq(self.i.out_do_z) + comb += self.o.oz.eq(self.i.oz) return m - - -class FPAddDeNorm(FPState): - - def __init__(self, width, id_wid): - FPState.__init__(self, "denormalise") - self.mod = FPAddDeNormMod(width) - self.out_a = FPNumBaseRecord(width) - self.out_b = FPNumBaseRecord(width) - - def setup(self, m, i): - """ links module to inputs and outputs - """ - self.mod.setup(m, i) - - m.d.sync += self.out_a.eq(self.mod.out_a) - m.d.sync += self.out_b.eq(self.mod.out_b) - - def action(self, m): - # Denormalised Number checks - m.next = "align" - -