From: Luke Kenneth Casson Leighton Date: Wed, 31 Jul 2019 21:05:43 +0000 (+0100) Subject: tidyup of FPAdd Align X-Git-Tag: ls180-24jan2020~596 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f7fe8d1a789d51feeadbf07114606d7817c8cbe3;p=ieee754fpu.git tidyup of FPAdd Align --- diff --git a/src/ieee754/fpadd/align.py b/src/ieee754/fpadd/align.py index 7bdf1605..c6071fe3 100644 --- a/src/ieee754/fpadd/align.py +++ b/src/ieee754/fpadd/align.py @@ -10,27 +10,12 @@ from ieee754.fpcommon.fpbase import FPNumBaseRecord from ieee754.fpcommon.fpbase import MultiShiftRMerge from ieee754.fpcommon.denorm import FPSCData from ieee754.fpcommon.getop import FPPipeContext - - -class FPNumIn2Ops: - - def __init__(self, pspec): - width = pspec.width - self.a = FPNumBaseRecord(width) - self.b = FPNumBaseRecord(width) - self.z = FPNumBaseRecord(width, False) - self.out_do_z = Signal(reset_less=True) - self.oz = Signal(width, reset_less=True) - self.ctx = FPPipeContext(pspec) - self.muxid = self.ctx.muxid - - def eq(self, i): - return [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)] +from ieee754.fpcommon.pscdata import FPSCData class FPAddAlignMultiMod: - + """Module to do mantissa alignment shift in multiple cycles + """ def __init__(self, width): self.in_a = FPNumBaseRecord(width) self.in_b = FPNumBaseRecord(width) @@ -39,35 +24,25 @@ class FPAddAlignMultiMod: self.exp_eq = Signal(reset_less=True) def elaborate(self, platform): - # This one however (single-cycle) will do the shift - # in one go. - m = Module() - - #m.submodules.align_in_a = self.in_a - #m.submodules.align_in_b = self.in_b - #m.submodules.align_out_a = self.out_a - #m.submodules.align_out_b = self.out_b - - # NOTE: this does *not* do single-cycle multi-shifting, - # it *STAYS* in the align state until exponents match + comb = m.d.comb # exponent of a greater than b: shift b down - m.d.comb += self.exp_eq.eq(0) - m.d.comb += self.out_a.eq(self.in_a) - m.d.comb += self.out_b.eq(self.in_b) + comb += self.exp_eq.eq(0) + comb += self.out_a.eq(self.in_a) + comb += self.out_b.eq(self.in_b) agtb = Signal(reset_less=True) altb = Signal(reset_less=True) - m.d.comb += agtb.eq(self.in_a.e > self.in_b.e) - m.d.comb += altb.eq(self.in_a.e < self.in_b.e) + comb += agtb.eq(self.in_a.e > self.in_b.e) + comb += altb.eq(self.in_a.e < self.in_b.e) with m.If(agtb): - m.d.comb += self.out_b.shift_down(self.in_b) + comb += self.out_b.shift_down(self.in_b) # exponent of b greater than a: shift a down with m.Elif(altb): - m.d.comb += self.out_a.shift_down(self.in_a) + comb += self.out_a.shift_down(self.in_a) # exponents equal: move to next stage. with m.Else(): - m.d.comb += self.exp_eq.eq(1) + comb += self.exp_eq.eq(1) return m @@ -80,7 +55,7 @@ class FPAddAlignSingleMod(PipeModBase): return FPSCData(self.pspec, True) def ospec(self): - return FPNumIn2Ops(self.pspec) + return FPSCData(self.pspec, True) def elaborate(self, platform): """ Aligns A against B or B against A, depending on which has the @@ -92,6 +67,7 @@ class FPAddAlignSingleMod(PipeModBase): needs to be aligned against the other """ m = Module() + comb = m.d.comb # temporary (muxed) input and output to be shifted width = self.pspec.width @@ -101,49 +77,50 @@ class FPAddAlignSingleMod(PipeModBase): msr = MultiShiftRMerge(self.i.a.m_width, espec) m.submodules.multishift_r = msr + # temporaries ediff = Signal(espec, reset_less=True) ediffr = Signal(espec, reset_less=True) tdiff = Signal(espec, reset_less=True) elz = Signal(reset_less=True) egz = Signal(reset_less=True) - # connect multi-shifter to t_inp/out mantissa (and tdiff) - m.d.comb += msr.inp.eq(t_inp.m) - m.d.comb += msr.diff.eq(tdiff) - m.d.comb += t_out.m.eq(msr.m) - m.d.comb += t_out.e.eq(t_inp.e + tdiff) - m.d.comb += t_out.s.eq(t_inp.s) - - m.d.comb += ediff.eq(self.i.a.e - self.i.b.e) - m.d.comb += ediffr.eq(self.i.b.e - self.i.a.e) - m.d.comb += elz.eq(self.i.a.e < self.i.b.e) - m.d.comb += egz.eq(self.i.a.e > self.i.b.e) - - # default: A-exp == B-exp, A and B untouched (fall through) - m.d.comb += self.o.a.eq(self.i.a) - m.d.comb += self.o.b.eq(self.i.b) - # only one shifter (muxed) - #m.d.comb += t_out.shift_down_multi(tdiff, t_inp) - # exponent of a greater than b: shift b down with m.If(~self.i.out_do_z): + # connect multi-shifter to t_inp/out mantissa (and tdiff) + # (only one: input/output is muxed) + comb += msr.inp.eq(t_inp.m) + comb += msr.diff.eq(tdiff) + comb += t_out.m.eq(msr.m) + comb += t_out.e.eq(t_inp.e + tdiff) + comb += t_out.s.eq(t_inp.s) + + comb += ediff.eq(self.i.a.e - self.i.b.e) # a - b + comb += ediffr.eq(self.i.b.e - self.i.a.e) # b - a + comb += elz.eq(self.i.a.e < self.i.b.e) # ae < be + comb += egz.eq(self.i.a.e > self.i.b.e) # ae > be + + # default: A-exp == B-exp, A and B untouched (fall through) + comb += self.o.a.eq(self.i.a) + comb += self.o.b.eq(self.i.b) + + # exponent of a greater than b: shift b down with m.If(egz): - m.d.comb += [t_inp.eq(self.i.b), + comb += [t_inp.eq(self.i.b), tdiff.eq(ediff), self.o.b.eq(t_out), self.o.b.s.eq(self.i.b.s), # whoops forgot sign ] # exponent of b greater than a: shift a down with m.Elif(elz): - m.d.comb += [t_inp.eq(self.i.a), + comb += [t_inp.eq(self.i.a), tdiff.eq(ediffr), self.o.a.eq(t_out), self.o.a.s.eq(self.i.a.s), # whoops forgot sign ] - m.d.comb += self.o.ctx.eq(self.i.ctx) - 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) + 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