rounding done in module
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 27 Feb 2019 10:04:06 +0000 (10:04 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 27 Feb 2019 10:04:06 +0000 (10:04 +0000)
src/add/fpbase.py
src/add/nmigen_add_experiment.py

index ec9f0bd09320a75c769d4a2e664e55898f71f956..9ee5092ba8dc308e0bf1853e47c9926e99deef95 100644 (file)
@@ -474,12 +474,11 @@ class FPBase:
         with m.Else():
             m.next = next_state
 
-    def roundz(self, m, z, out_z, of, next_state):
+    def roundz(self, m, z, out_z, roundz):
         """ performs rounding on the output.  TODO: different kinds of rounding
         """
-        m.next = next_state
         m.d.comb += out_z.copy(z) # copies input to output first
-        with m.If(of.roundz):
+        with m.If(roundz):
             m.d.comb += out_z.m.eq(z.m + 1) # mantissa rounds up
             with m.If(z.m == z.m1s): # all 1s
                 m.d.comb += out_z.e.eq(z.e + 1) # exponent rounds up
index 883ffbc1de2ac31648be6b7b67a0cc023b2f995e..6832ec198814d2c2274a5e16feeef1e90050096d 100644 (file)
@@ -241,12 +241,40 @@ class FPNorm2(FPState):
         self.normalise_2(m, self.z, self.of, "round")
 
 
+class FPRoundMod:
+
+    def __init__(self, width):
+        self.in_roundz = Signal(reset_less=True)
+        self.in_z = FPNumBase(width, False)
+        self.out_z = FPNumBase(width, False)
+
+    def setup(self, m, in_z, out_z, in_of):
+        """ links module to inputs and outputs
+        """
+        m.d.comb += self.in_z.copy(in_z)
+        m.d.comb += out_z.copy(self.out_z)
+        m.d.comb += self.in_roundz.eq(in_of.roundz)
+
+    def elaborate(self, platform):
+        m = Module()
+        m.d.comb += self.out_z.copy(self.in_z)
+        with m.If(self.in_roundz):
+            m.d.comb += self.out_z.m.eq(self.in_z.m + 1) # mantissa rounds up
+            with m.If(self.in_z.m == self.in_z.m1s): # all 1s
+                m.d.comb += self.out_z.e.eq(self.in_z.e + 1) # exponent up
+        return m
+
+
 class FPRound(FPState):
 
+    def __init__(self, width):
+        FPState.__init__(self, "round")
+        self.mod = FPRoundMod(width)
+        self.out_z = FPNumBase(width)
+
     def action(self, m):
-        out_z = FPNumBase(self.z.width)
-        self.roundz(m, self.z, out_z, self.of, "corrections")
-        m.d.sync += self.z.copy(out_z)
+        m.d.sync += self.z.copy(self.out_z)
+        m.next = "corrections"
 
 
 class FPCorrections(FPState):
@@ -345,9 +373,12 @@ class FPADD:
         n2.set_inputs({"z": z, "of": of})  # XXX Z as output
         n2.set_outputs({"z": z})  # XXX Z as output
 
-        rn = self.add_state(FPRound("round"))
+        rn = self.add_state(FPRound(self.width))
         rn.set_inputs({"z": z, "of": of})  # XXX Z as output
         rn.set_outputs({"z": z})  # XXX Z as output
+        rn.mod.setup(m, z, rn.out_z, of)
+
+        m.submodules.roundz = rn.mod
 
         cor = self.add_state(FPCorrections("corrections"))
         cor.set_inputs({"z": z})  # XXX Z as output