From: Luke Kenneth Casson Leighton Date: Sun, 25 Aug 2019 11:44:22 +0000 (+0100) Subject: remove out_do_z, update comments (whitespace) X-Git-Tag: ls180-24jan2020~381 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5ac3d0b81f9e454e657e3ceca5d0b267bae901cd;p=ieee754fpu.git remove out_do_z, update comments (whitespace) --- diff --git a/src/ieee754/fpdiv/div0.py b/src/ieee754/fpdiv/div0.py index 1ccc6e23..971224be 100644 --- a/src/ieee754/fpdiv/div0.py +++ b/src/ieee754/fpdiv/div0.py @@ -1,4 +1,4 @@ -"""IEEE754 Floating Point Divider +"""IEEE754 Floating Point Divider / Square-Root / Reciprocal-Square-Root Copyright (C) 2019 Luke Kenneth Casson Leighton Copyright (C) 2019 Jacob Lifshay @@ -76,30 +76,31 @@ class FPDivPreFPAdjust(PipeModBase): self.o.divisor_radicand.eq(divr_rad), ] - with m.If(~self.i.out_do_z): - # DIV - with m.If(self.i.ctx.op == int(DPCOp.UDivRem)): - # DIV: subtract exponents, XOR sign - comb += [self.o.z.e.eq(self.i.a.e - self.i.b.e), - self.o.z.s.eq(self.i.a.s ^ self.i.b.s), - self.o.operation.eq(int(DPCOp.UDivRem)) - ] - # SQRT - with m.Elif(self.i.ctx.op == int(DPCOp.SqrtRem)): - # SQRT: sign is the same, [adjusted] exponent is halved - comb += [self.o.z.e.eq(adj_a_e >> 1), # halve - self.o.z.s.eq(self.i.a.s), - self.o.operation.eq(int(DPCOp.SqrtRem)) - ] - # RSQRT - with m.Elif(self.i.ctx.op == int(DPCOp.RSqrtRem)): - # RSQRT: sign same, [adjusted] exponent halved and inverted - comb += [self.o.z.e.eq(-(adj_a_e >> 1)), # NEGATE and halve - self.o.z.s.eq(self.i.a.s), - self.o.operation.eq(int(DPCOp.RSqrtRem)) - ] - - # these are required and must not be touched + ############# DIV ############# + with m.If(self.i.ctx.op == int(DPCOp.UDivRem)): + # DIV: subtract exponents, XOR sign + comb += [self.o.z.e.eq(self.i.a.e - self.i.b.e), + self.o.z.s.eq(self.i.a.s ^ self.i.b.s), + self.o.operation.eq(int(DPCOp.UDivRem)) + ] + + ############# SQRT ############# + with m.Elif(self.i.ctx.op == int(DPCOp.SqrtRem)): + # SQRT: sign is the same, [adjusted] exponent is halved + comb += [self.o.z.e.eq(adj_a_e >> 1), # halve + self.o.z.s.eq(self.i.a.s), + self.o.operation.eq(int(DPCOp.SqrtRem)) + ] + + ############# RSQRT ############# + with m.Elif(self.i.ctx.op == int(DPCOp.RSqrtRem)): + # RSQRT: sign same, [adjusted] exponent halved and inverted + comb += [self.o.z.e.eq(-(adj_a_e >> 1)), # NEGATE and halve + self.o.z.s.eq(self.i.a.s), + self.o.operation.eq(int(DPCOp.RSqrtRem)) + ] + + # pass through context comb += self.o.oz.eq(self.i.oz) comb += self.o.out_do_z.eq(self.i.out_do_z) comb += self.o.ctx.eq(self.i.ctx) diff --git a/src/ieee754/fpdiv/div2.py b/src/ieee754/fpdiv/div2.py index d21ab848..a2bb36c0 100644 --- a/src/ieee754/fpdiv/div2.py +++ b/src/ieee754/fpdiv/div2.py @@ -57,48 +57,48 @@ class FPDivPostToFPFormat(PipeModBase): # radicand [1.0, 4.0) # result (0.5, 1.0] - with m.If(~self.i.out_do_z): - # following section partially normalizes result to range [1.0, 2.0) - fw = self.pspec.core_config.fract_width - qr_int_part = Signal(2, reset_less=True) - comb += qr_int_part.eq(self.i.quotient_root[fw:][:2]) - - need_shift = Signal(reset_less=True) - - # shift left when result is less than 2.0 since result_m has 1 more - # fraction bit, making assigning to it the equivalent of - # dividing by 2. - # this all comes out to: - # if quotient_root < 2.0: - # # div by 2 from assign; mul by 2 from shift left - # result = (quotient_root * 2) / 2 - # else: - # # div by 2 from assign - # result = quotient_root / 2 - comb += need_shift.eq(qr_int_part < 2) - - # one extra fraction bit to accommodate the result when not - # shifting and for effective div by 2 - result_m_fract_width = fw + 1 - # 1 integer bit since the numbers are less than 2.0 - result_m = Signal(1 + result_m_fract_width, reset_less=True) - result_e = Signal(len(self.i.z.e), reset_less=True) - - comb += [ - result_m.eq(self.i.quotient_root << need_shift), - result_e.eq(self.i.z.e + (1 - need_shift)) - ] - - # result_m is now in the range [1.0, 2.0) - comb += [ - self.o.z.m.eq(result_m[3:]), # mantissa - self.o.of.m0.eq(result_m[3]), # copy of mantissa LSB - self.o.of.guard.eq(result_m[2]), # guard - self.o.of.round_bit.eq(result_m[1]), # round - self.o.of.sticky.eq(result_m[0] | self.i.remainder.bool()), - self.o.z.e.eq(result_e), - ] - + # following section partially normalizes result to range [1.0, 2.0) + fw = self.pspec.core_config.fract_width + qr_int_part = Signal(2, reset_less=True) + comb += qr_int_part.eq(self.i.quotient_root[fw:][:2]) + + need_shift = Signal(reset_less=True) + + # shift left when result is less than 2.0 since result_m has 1 more + # fraction bit, making assigning to it the equivalent of + # dividing by 2. + # this all comes out to: + # if quotient_root < 2.0: + # # div by 2 from assign; mul by 2 from shift left + # result = (quotient_root * 2) / 2 + # else: + # # div by 2 from assign + # result = quotient_root / 2 + comb += need_shift.eq(qr_int_part < 2) + + # one extra fraction bit to accommodate the result when not + # shifting and for effective div by 2 + result_m_fract_width = fw + 1 + # 1 integer bit since the numbers are less than 2.0 + result_m = Signal(1 + result_m_fract_width, reset_less=True) + result_e = Signal(len(self.i.z.e), reset_less=True) + + comb += [ + result_m.eq(self.i.quotient_root << need_shift), + result_e.eq(self.i.z.e + (1 - need_shift)) + ] + + # result_m is now in the range [1.0, 2.0) + comb += [ + self.o.z.m.eq(result_m[3:]), # mantissa + self.o.of.m0.eq(result_m[3]), # copy of mantissa LSB + self.o.of.guard.eq(result_m[2]), # guard + self.o.of.round_bit.eq(result_m[1]), # round + self.o.of.sticky.eq(result_m[0] | self.i.remainder.bool()), + self.o.z.e.eq(result_e), + ] + + # pass through context comb += self.o.out_do_z.eq(self.i.out_do_z) comb += self.o.oz.eq(self.i.oz) comb += self.o.ctx.eq(self.i.ctx) diff --git a/src/ieee754/fpdiv/specialcases.py b/src/ieee754/fpdiv/specialcases.py index 701bb998..92eec062 100644 --- a/src/ieee754/fpdiv/specialcases.py +++ b/src/ieee754/fpdiv/specialcases.py @@ -66,7 +66,8 @@ class FPDIVSpecialCasesMod(PipeModBase): # select one of 3 different sets of specialcases (DIV, SQRT, RSQRT) with m.Switch(self.i.ctx.op): - with m.Case(int(DP.UDivRem)): # DIV + ########## DIV ############ + with m.Case(int(DP.UDivRem)): # if a is NaN or b is NaN return NaN with m.If(abnan): @@ -99,7 +100,8 @@ class FPDIVSpecialCasesMod(PipeModBase): with m.Else(): comb += self.o.out_do_z.eq(0) - with m.Case(int(DP.SqrtRem)): # SQRT + ########## SQRT ############ + with m.Case(int(DP.SqrtRem)): # if a is zero return zero with m.If(a1.is_zero): @@ -121,7 +123,8 @@ class FPDIVSpecialCasesMod(PipeModBase): with m.Else(): comb += self.o.out_do_z.eq(0) - with m.Case(int(DP.RSqrtRem)): # RSQRT + ########## RSQRT ############ + with m.Case(int(DP.RSqrtRem)): # if a is NaN return canonical NaN with m.If(a1.is_nan): @@ -144,6 +147,7 @@ class FPDIVSpecialCasesMod(PipeModBase): with m.Else(): comb += self.o.out_do_z.eq(0) + # pass through context comb += self.o.oz.eq(self.o.z.v) comb += self.o.ctx.eq(self.i.ctx)