simplify code by removing for-loop and commenting why it was removed
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 7 Apr 2022 10:27:43 +0000 (11:27 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 7 Apr 2022 10:27:43 +0000 (11:27 +0100)
src/nmigen_gf/hdl/cldivrem.py

index 4ce94ce7618b826ff0641c73bee187a4f2f1aa95..973e0c98cbc332951f4727495a513c79ecf78d25 100644 (file)
@@ -70,34 +70,36 @@ class EqualLeadingZeroCount(Elaboratable):
         #
         # see `equal_leading_zero_count_reference` for a Python version of
         # the algorithm, but without conversion to carry-propagation.
+        # note that it's possible to do all the bits at once: a for-loop
+        # (unlike in the reference-code) is not necessary
+
         m = Module()
         addend1 = Signal(self.width)
         addend2 = Signal(self.width)
-        for i in range(self.width):
-            # `both_ones` is set if both have no leading zeros so far
-            both_ones = self.a[i] & self.b[i]
-            # `different` is set if there are a different number of leading
-            # zeros so far
-            different = self.a[i] != self.b[i]
-
-            # build addend1 and addend2 such that:
-            # * if both_ones is set, then addend1[i] and addend2[i] are both
-            #   ones in order to set the carry bit out.
-            # * if different is set, then addend1[i] and addend2[i] are both
-            #   zeros in order to clear the carry bit out.
-            # * otherwise exactly one of addend1[i] and addend2[i] are set and
-            #   the other is clear in order to propagate the carry bit from
-            #   less significant bits.
-            m.d.comb += [
-                addend1[i].eq(both_ones),
-                # different is zero when both_ones is set, so we don't need to
-                # OR-in both_ones
-                addend2[i].eq(~different),
-            ]
-        sum = Signal(self.width + 1)
+
+        # `both_ones` is set if both have no leading zeros so far
+        both_ones = self.a & self.b
+        # `different` is set if there are a different number of leading
+        # zeros so far
+        different = self.a ^ self.b
+
+        # build addend1 and addend2 such that:
+        # * if both_ones is set, then addend1[i] and addend2[i] are both
+        #   ones in order to set the carry bit out.
+        # * if different is set, then addend1[i] and addend2[i] are both
+        #   zeros in order to clear the carry bit out.
+        # * otherwise exactly one of addend1[i] and addend2[i] are set and
+        #   the other is clear in order to propagate the carry bit from
+        #   less significant bits.
+        m.d.comb += addend1.eq(both_ones)
+        # different is zero when both_ones is set, so we don't need to
+        # OR-in both_ones
+        m.d.comb += addend2.eq(~different)
+
+        csum = Signal(self.width + 1)
         carry_in = 1  # both have no leading zeros so far, so set carry
         m.d.comb += sum.eq(addend1 + addend2 + carry_in)
-        m.d.comb += self.out.eq(sum[self.width])  # out is carry-out
+        m.d.comb += self.out.eq(csum[self.width])  # out is carry-out
         return m
 
 # TODO: add CLDivRem