From: Luke Kenneth Casson Leighton Date: Sun, 21 Jul 2019 09:28:32 +0000 (+0100) Subject: split out EXP-High shifter to separate module X-Git-Tag: ls180-24jan2020~805 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7fcf350883ca3d3136d3b63878046ff0cf665813;p=ieee754fpu.git split out EXP-High shifter to separate module --- diff --git a/src/ieee754/fpcommon/exphigh.py b/src/ieee754/fpcommon/exphigh.py new file mode 100644 index 00000000..d9a07762 --- /dev/null +++ b/src/ieee754/fpcommon/exphigh.py @@ -0,0 +1,43 @@ +# IEEE Floating Point Adder (Single Precision) +# Copyright (C) Jonathan P Dawson 2013 +# 2013-12-12 + +from nmigen import Module, Signal, Elaboratable +from nmigen.cli import main, verilog + +from ieee754.fpcommon.fpbase import MultiShiftRMerge + + +class FPEXPHigh(Elaboratable): + + def __init__(self, m_width, e_width): + self.m_width = m_width + self.e_width = e_width + self.ediff = Signal((e_width, True), reset_less=True) + + self.m_in = Signal(m_width, reset_less=True) + self.e_in = Signal((e_width, True), reset_less=True) + self.m_out = Signal(m_width, reset_less=True) + self.e_out = Signal((e_width, True), reset_less=True) + + def elaborate(self, platform): + m = Module() + + espec = (self.e_width, True) + mwid = self.m_width + + msr = MultiShiftRMerge(mwid, espec) + m.submodules.multishift_r = msr + + m.d.comb += [ + # connect multi-shifter to inp/out mantissa (and ediff) + msr.inp.eq(self.m_in), + msr.diff.eq(self.ediff), + self.m_out.eq(msr.m), + self.e_out.eq(self.e_in + self.ediff), + ] + + + return m + + diff --git a/src/ieee754/fpcommon/postnormalise.py b/src/ieee754/fpcommon/postnormalise.py index 196d158a..25dca7ad 100644 --- a/src/ieee754/fpcommon/postnormalise.py +++ b/src/ieee754/fpcommon/postnormalise.py @@ -8,10 +8,10 @@ from math import log from ieee754.fpcommon.fpbase import (Overflow, OverflowMod, FPNumBase, FPNumBaseRecord) -from ieee754.fpcommon.fpbase import MultiShiftRMerge from ieee754.fpcommon.fpbase import FPState from ieee754.fpcommon.getop import FPPipeContext from ieee754.fpcommon.msbhigh import FPMSBHigh +from ieee754.fpcommon.exphigh import FPEXPHigh from .postcalc import FPAddStage1Data @@ -76,9 +76,8 @@ class FPNorm1ModSingle(Elaboratable): espec = (len(insel_z.e), True) mwid = self.o.z.m_width+2 - ediff_n126 = Signal(espec, reset_less=True) - msr = MultiShiftRMerge(mwid+2, espec) - m.submodules.multishift_r = msr + msr = FPEXPHigh(mwid+2, espec[0]) + m.submodules.norm_exp = msr msb = FPMSBHigh(mwid+1, espec[0], True) m.submodules.norm_msb = msb @@ -94,39 +93,49 @@ class FPNorm1ModSingle(Elaboratable): m.d.comb += increase.eq(insel_z.exp_lt_n126) # decrease exponent with m.If(~self.i.out_do_z): + # concatenate s/r/g with mantissa + temp_m = Signal(mwid+2, reset_less=True) + m.d.comb += temp_m.eq(Cat(i.of.sticky, i.of.round_bit, i.of.guard, + insel_z.m)), + with m.If(decrease): # make sure that the amount to decrease by does NOT # go below the minimum non-INF/NaN exponent m.d.comb += msb.limclz.eq(insel_z.exp_sub_n126) m.d.comb += [ - # cat round and guard bits back into the mantissa - msb.m_in.eq(Cat(i.of.sticky, i.of.round_bit, i.of.guard, - insel_z.m)), + # inputs: mantissa and exponent + msb.m_in.eq(temp_m), msb.e_in.eq(insel_z.e), - self.o.z.e.eq(msb.e_out), + + # outputs: mantissa first (s/r/g/m[3:]) self.o.z.m.eq(msb.m_out[3:]), # exclude bits 0&1 of.m0.eq(msb.m_out[3]), # copy of mantissa[0] # overflow in bits 0..1: got shifted too (leave sticky) of.guard.eq(msb.m_out[2]), # guard of.round_bit.eq(msb.m_out[1]), # round + # now exponent out + self.o.z.e.eq(msb.e_out), ] # increase exponent with m.Elif(increase): - temp_m = Signal(mwid+1, reset_less=True) + ediff_n126 = Signal(espec, reset_less=True) m.d.comb += [ - temp_m.eq(Cat(i.of.sticky, i.of.round_bit, i.of.guard, - insel_z.m)), + # concatenate ediff_n126.eq(insel_z.fp.N126 - insel_z.e), - # connect multi-shifter to inp/out mantissa (and ediff) - msr.inp.eq(temp_m), - msr.diff.eq(ediff_n126), - self.o.z.m.eq(msr.m[3:]), - of.m0.eq(msr.m[3]), # copy of mantissa[0] - # overflow in bits 0..1: got shifted too (leave sticky) - of.guard.eq(msr.m[2]), # guard - of.round_bit.eq(msr.m[1]), # round - of.sticky.eq(msr.m[0]), # sticky - self.o.z.e.eq(insel_z.e + ediff_n126), + # connect multi-shifter to inp/out m/e (and ediff) + msr.m_in.eq(temp_m), + msr.e_in.eq(insel_z.e), + msr.ediff.eq(ediff_n126), + + # outputs: mantissa first (s/r/g/m[3:]) + self.o.z.m.eq(msr.m_out[3:]), + of.m0.eq(msr.m_out[3]), # copy of mantissa[0] + # overflow in bits 0..2: got shifted too (leave sticky) + of.guard.eq(msr.m_out[2]), # guard + of.round_bit.eq(msr.m_out[1]), # round + of.sticky.eq(msr.m_out[0]), # sticky + # now exponent + self.o.z.e.eq(msr.e_out), ] m.d.comb += self.o.roundz.eq(of.roundz_out)