From: Luke Kenneth Casson Leighton Date: Tue, 30 Jul 2019 10:53:14 +0000 (+0100) Subject: use specialcase fpdiv "switch" and use DP op X-Git-Tag: ls180-24jan2020~662 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c13d760d307d54b734019f524a266c37ee68704a;p=ieee754fpu.git use specialcase fpdiv "switch" and use DP op --- diff --git a/src/ieee754/fpdiv/specialcases.py b/src/ieee754/fpdiv/specialcases.py index f4410b6d..227eaab4 100644 --- a/src/ieee754/fpdiv/specialcases.py +++ b/src/ieee754/fpdiv/specialcases.py @@ -73,97 +73,99 @@ class FPDIVSpecialCasesMod(Elaboratable): abinf = Signal(reset_less=True) comb += abinf.eq(a1.is_inf & b1.is_inf) - with m.If(self.i.ctx.op == 0): # DIV - - # if a is NaN or b is NaN return NaN - with m.If(abnan): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.nan(0) - - # if a is inf and b is Inf return NaN - with m.Elif(abinf): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.nan(0) - - # if a is inf return inf - with m.Elif(a1.is_inf): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.inf(sabx) - - # if b is inf return zero - with m.Elif(b1.is_inf): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.zero(sabx) - - # if a is zero return zero (or NaN if b is zero) - with m.Elif(a1.is_zero): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.zero(sabx) - # b is zero return NaN - with m.If(b1.is_zero): + with m.Switch(self.i.ctx.op): + + with m.Case(int(DP.UDivRem)): # DIV + + # if a is NaN or b is NaN return NaN + with m.If(abnan): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.nan(0) + + # if a is inf and b is Inf return NaN + with m.Elif(abinf): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.nan(0) + + # if a is inf return inf + with m.Elif(a1.is_inf): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.inf(sabx) + + # if b is inf return zero + with m.Elif(b1.is_inf): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.zero(sabx) + + # if a is zero return zero (or NaN if b is zero) + with m.Elif(a1.is_zero): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.zero(sabx) + # b is zero return NaN + with m.If(b1.is_zero): + comb += self.o.z.nan(0) + + # if b is zero return Inf + with m.Elif(b1.is_zero): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.inf(sabx) + + # Denormalised Number checks next, so pass a/b data through + with m.Else(): + comb += self.o.out_do_z.eq(0) + + with m.Case(int(DP.SqrtRem)): # SQRT + + # if a is zero return zero + with m.If(a1.is_zero): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.zero(a1.s) + + # -ve number is NaN + with m.Elif(a1.s): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.nan(0) + + # if a is inf return inf + with m.Elif(a1.is_inf): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.inf(sabx) + + # if a is NaN return NaN + with m.Elif(a1.is_nan): + comb += self.o.out_do_z.eq(1) comb += self.o.z.nan(0) - # if b is zero return Inf - with m.Elif(b1.is_zero): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.inf(sabx) - - # Denormalised Number checks next, so pass a/b data through - with m.Else(): - comb += self.o.out_do_z.eq(0) - - with m.If(self.i.ctx.op == 1): # SQRT - - # if a is zero return zero - with m.If(a1.is_zero): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.zero(a1.s) - - # -ve number is NaN - with m.Elif(a1.s): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.nan(0) - - # if a is inf return inf - with m.Elif(a1.is_inf): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.inf(sabx) - - # if a is NaN return NaN - with m.Elif(a1.is_nan): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.nan(0) - - # Denormalised Number checks next, so pass a/b data through - with m.Else(): - comb += self.o.out_do_z.eq(0) - - with m.If(self.i.ctx.op == 2): # RSQRT - - # if a is NaN return canonical NaN - with m.If(a1.is_nan): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.nan(0) - - # if a is +/- zero return +/- INF - with m.Elif(a1.is_zero): - comb += self.o.out_do_z.eq(1) - # this includes the "weird" case 1/sqrt(-0) == -Inf - comb += self.o.z.inf(a1.s) - - # -ve number is canonical NaN - with m.Elif(a1.s): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.nan(0) - - # if a is inf return zero (-ve already excluded, above) - with m.Elif(a1.is_inf): - comb += self.o.out_do_z.eq(1) - comb += self.o.z.zero(0) - - # Denormalised Number checks next, so pass a/b data through - with m.Else(): - comb += self.o.out_do_z.eq(0) + # Denormalised Number checks next, so pass a/b data through + with m.Else(): + comb += self.o.out_do_z.eq(0) + + with m.Case(int(DP.RSqrtRem)): # RSQRT + + # if a is NaN return canonical NaN + with m.If(a1.is_nan): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.nan(0) + + # if a is +/- zero return +/- INF + with m.Elif(a1.is_zero): + comb += self.o.out_do_z.eq(1) + # this includes the "weird" case 1/sqrt(-0) == -Inf + comb += self.o.z.inf(a1.s) + + # -ve number is canonical NaN + with m.Elif(a1.s): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.nan(0) + + # if a is inf return zero (-ve already excluded, above) + with m.Elif(a1.is_inf): + comb += self.o.out_do_z.eq(1) + comb += self.o.z.zero(0) + + # Denormalised Number checks next, so pass a/b data through + with m.Else(): + comb += self.o.out_do_z.eq(0) comb += self.o.oz.eq(self.o.z.v) comb += self.o.ctx.eq(self.i.ctx)