X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fieee754%2Ffcvt%2Fint2float.py;h=fcf3e34cf3025b02995b76251d363834640b7deb;hb=247604ef2e548361cacccc66a38ff4314fdebdbf;hp=8c25cdb8699509584b2964d139e2980703827496;hpb=1286822ae701dbea9814c06a22af8f2706383e60;p=ieee754fpu.git diff --git a/src/ieee754/fcvt/int2float.py b/src/ieee754/fcvt/int2float.py index 8c25cdb8..fcf3e34c 100644 --- a/src/ieee754/fcvt/int2float.py +++ b/src/ieee754/fcvt/int2float.py @@ -1,15 +1,15 @@ # IEEE Floating Point Conversion # Copyright (C) 2019 Luke Kenneth Casson Leighton -from nmigen import Module, Signal, Cat +from nmigen import Module, Signal, Cat, Mux from nmigen.cli import main, verilog from nmutil.pipemodbase import PipeModBase -from ieee754.fpcommon.getop import FPADDBaseData +from ieee754.fpcommon.basedata import FPBaseData from ieee754.fpcommon.postcalc import FPPostCalcData from ieee754.fpcommon.msbhigh import FPMSBHigh -from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord +from ieee754.fpcommon.fpbase import FPNumBaseRecord class FPCVTIntToFloatMod(PipeModBase): @@ -24,7 +24,7 @@ class FPCVTIntToFloatMod(PipeModBase): super().__init__(in_pspec, "intconvert") def ispec(self): - return FPADDBaseData(self.in_pspec) + return FPBaseData(self.in_pspec) def ospec(self): return FPPostCalcData(self.out_pspec, e_extra=True) @@ -40,10 +40,11 @@ class FPCVTIntToFloatMod(PipeModBase): self.out_pspec.width) print("a1", self.in_pspec.width) z1 = self.o.z + a = self.i.a print("z1", z1.width, z1.rmw, z1.e_width, z1.e_start, z1.e_end) me = self.in_pspec.width - mz = self.o.z.rmw + mz = z1.rmw ms = mz - me print("ms-me", ms, me, mz) @@ -55,20 +56,17 @@ class FPCVTIntToFloatMod(PipeModBase): signed = Signal(reset_less=True) comb += signed.eq(self.i.ctx.op[0]) - # copy of mantissa (one less bit if signed) + # mantissa (one less bit if signed), and sign mantissa = Signal(me, reset_less=True) + sign = Signal(reset_less=True) # detect signed/unsigned. key case: -ve numbers need inversion # to +ve because the FP sign says if it's -ve or not. - with m.If(signed): - comb += z1.s.eq(self.i.a[-1]) # sign in top bit of a - with m.If(z1.s): - comb += mantissa.eq(-self.i.a) # invert input if sign -ve - with m.Else(): - comb += mantissa.eq(self.i.a) # leave as-is - with m.Else(): - comb += mantissa.eq(self.i.a) # unsigned, use full a - comb += z1.s.eq(0) + comb += sign.eq(Mux(signed, a[-1], 0)) # sign in top bit of a + comb += mantissa.eq(Mux(signed, + Mux(sign, -a, # invert input if sign -ve + a), # leave as-is + a)) # unsigned, use full a # set input from full INT comb += msb.m_in.eq(Cat(0, 0, 0, mantissa)) # g/r/s + input @@ -89,7 +87,12 @@ class FPCVTIntToFloatMod(PipeModBase): # smaller int to larger FP comb += z1.e.eq(msb.e_out) comb += z1.m[ms:].eq(msb.m_out[3:]) - comb += z1.create(z1.s, z1.e, z1.m) # ... here + + # XXX there is some weirdness involving the sign looping back + # see graphviz output + # http://bugs.libre-riscv.org/show_bug.cgi?id=135 + comb += z1.s.eq(sign) + comb += z1.create(sign, z1.e, z1.m) # ... here # note: post-normalisation actually appears to be capable of # detecting overflow to infinity (FPPackMod). so it's ok to @@ -115,17 +118,20 @@ class FPCVTIntToFloatMod(PipeModBase): comb += self.o.of.sticky.eq(msb.m_out[:1].bool()) comb += self.o.of.m0.eq(msb.m_out[3]) - # special cases active by default - comb += self.o.out_do_z.eq(1) + a_nonzero = Signal(reset_less=True) + comb += a_nonzero.eq(~a.bool()) + + # prepare zero + z_zero = FPNumBaseRecord(z1.width, False, name="z_zero") + comb += z_zero.zero(0) + + # special cases? + comb += self.o.out_do_z.eq(a_nonzero) # detect zero - with m.If(~self.i.a.bool()): - comb += self.o.z.zero(0) - with m.Else(): - comb += self.o.out_do_z.eq(0) # activate normalisation + comb += self.o.oz.eq(Mux(a_nonzero, z1.v, z_zero.v)) # copy the context (muxid, operator) - comb += self.o.oz.eq(self.o.z.v) comb += self.o.ctx.eq(self.i.ctx) return m