reorg / tidyup fcvt upsize.py
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 22:54:06 +0000 (23:54 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 22:54:06 +0000 (23:54 +0100)
src/ieee754/fcvt/upsize.py

index ec2813506dd75c8b9948b3ba05ce17ae51eb55e2..538db4950c3de2e076836698c9ac24376447b1ae 100644 (file)
@@ -31,16 +31,20 @@ class FPCVTUpConvertMod(PipeModBase):
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
+        print("in_width out", self.in_pspec.width, self.out_pspec.width)
 
-        #m.submodules.sc_out_z = self.o.z
+        # this is quite straightforward as there is plenty of space in
+        # the larger format to fit the smaller-bit-width exponent+mantissa
+        # the special cases are detecting Inf and NaN and de-normalised
+        # "tiny" numbers.  the "subnormal" numbers (ones at the limit of
+        # the smaller exponent range) need to be normalised to fit into
+        # the (larger) exponent.
 
-        # decode: XXX really should move to separate stage
-        print("in_width out", self.in_pspec.width,
-              self.out_pspec.width)
         a1 = FPNumBaseRecord(self.in_pspec.width, False)
         print("a1", a1.width, a1.rmw, a1.e_width, a1.e_start, a1.e_end)
         m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
         comb += a1.v.eq(self.i.a)
+
         z1 = self.o.z
         print("z1", z1.width, z1.rmw, z1.e_width, z1.e_start, z1.e_end)
 
@@ -54,13 +58,8 @@ class FPCVTUpConvertMod(PipeModBase):
         comb += self.o.z.m[ms:].eq(a1.m)
         comb += self.o.z.create(a1.s, a1.e, self.o.z.m) # ... here
 
-        # initialise rounding to all zeros (deactivate)
-        comb += self.o.of.guard.eq(0)
-        comb += self.o.of.round_bit.eq(0)
-        comb += self.o.of.sticky.eq(0)
-        comb += self.o.of.m0.eq(a1.m[0])
 
-        # most special cases active (except tiny-number normalisation, below)
+        # special cases active (except tiny-number normalisation, below)
         comb += self.o.out_do_z.eq(1)
 
         # detect NaN/Inf first
@@ -70,13 +69,17 @@ class FPCVTUpConvertMod(PipeModBase):
             with m.Else():
                 comb += self.o.z.inf(a1.s) # RISC-V wants signed INF
         with m.Else():
-            with m.If(a1.exp_n127):
+            # now check zero (or subnormal)
+            with m.If(a1.exp_n127): # subnormal number detected (or zero)
                 with m.If(~a1.m_zero):
+                    # non-zero mantissa: needs normalisation
                     comb += self.o.z.m[ms:].eq(Cat(0, a1.m))
+                    comb += self.o.of.m0.eq(a1.m[0]) # Overflow needs LSB
                     comb += self.o.out_do_z.eq(0) # activate normalisation
                 with m.Else():
                     # RISC-V zero needs actual zero
                     comb += self.o.z.zero(a1.s)
+            # anything else, amazingly, is fine as-is.
 
         # copy the context (muxid, operator)
         comb += self.o.oz.eq(self.o.z.v)