From: Luke Kenneth Casson Leighton Date: Thu, 14 Mar 2019 04:16:28 +0000 (+0000) Subject: add new FPNormaliseSingleMod, not tested X-Git-Tag: ls180-24jan2020~1670 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=38452d7fb64752a897b26e1da96a27d3a5979a76;p=ieee754fpu.git add new FPNormaliseSingleMod, not tested --- diff --git a/src/add/nmigen_add_experiment.py b/src/add/nmigen_add_experiment.py index 1c795fc2..dc81329b 100644 --- a/src/add/nmigen_add_experiment.py +++ b/src/add/nmigen_add_experiment.py @@ -871,6 +871,69 @@ class FPAddStage1(FPState, FPID): m.next = "normalise_1" +class FPNormaliseModSingle: + + def __init__(self, width): + self.width = width + self.in_z = FPNumBase(width, False) + self.out_z = FPNumBase(width, False) + + def setup(self, m, in_z, out_z, modname): + """ links module to inputs and outputs + """ + m.submodules.normalise = self + m.d.comb += self.in_z.copy(in_z) + m.d.comb += out_z.copy(self.out_z) + + def elaborate(self, platform): + m = Module() + + mwid = self.out_z.m_width+2 + pe = PriorityEncoder(mwid) + m.submodules.norm_pe = pe + + m.submodules.norm1_out_z = self.out_z + m.submodules.norm1_in_z = self.in_z + + in_z = FPNumBase(self.width, False) + in_of = Overflow() + m.submodules.norm1_insel_z = in_z + m.submodules.norm1_insel_overflow = in_of + + espec = (len(in_z.e), True) + ediff_n126 = Signal(espec, reset_less=True) + msr = MultiShiftRMerge(mwid, espec) + m.submodules.multishift_r = msr + + m.d.comb += in_z.copy(self.in_z) + m.d.comb += in_of.copy(self.in_of) + # initialise out from in (overridden below) + m.d.comb += self.out_z.copy(in_z) + m.d.comb += self.out_of.copy(in_of) + # normalisation increase/decrease conditions + decrease = Signal(reset_less=True) + m.d.comb += decrease.eq(in_z.m_msbzero) + # decrease exponent + with m.If(decrease): + # *sigh* not entirely obvious: count leading zeros (clz) + # with a PriorityEncoder: to find from the MSB + # we reverse the order of the bits. + temp_m = Signal(mwid, reset_less=True) + temp_s = Signal(mwid+1, reset_less=True) + clz = Signal((len(in_z.e), True), reset_less=True) + m.d.comb += [ + # cat round and guard bits back into the mantissa + temp_m.eq(Cat(in_of.round_bit, in_of.guard, in_z.m)), + pe.i.eq(temp_m[::-1]), # inverted + clz.eq(pe.o), # count zeros from MSB down + temp_s.eq(temp_m << clz), # shift mantissa UP + self.out_z.e.eq(in_z.e - clz), # DECREASE exponent + self.out_z.m.eq(temp_s[2:]), # exclude bits 0&1 + ] + + return m + + class FPNorm1ModSingle: def __init__(self, width):