switch EqualLeadingZeroCount to use bitwise logic rather than Switch
authorJacob Lifshay <programmerjake@gmail.com>
Thu, 7 Apr 2022 03:26:41 +0000 (20:26 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Thu, 7 Apr 2022 03:26:41 +0000 (20:26 -0700)
src/nmigen_gf/hdl/cldivrem.py

index c63ad605c072a02520df65e2b620708ecfd677bf..ae631c84c93bf70956cbcbd007bbc81ac000c83b 100644 (file)
@@ -74,25 +74,26 @@ class EqualLeadingZeroCount(Elaboratable):
         addend1 = Signal(self.width)
         addend2 = Signal(self.width)
         for i in range(self.width):
-            with m.Switch(Cat(self.a[i], self.b[i])):
-                with m.Case('11'):
-                    # both have no leading zeros so far, so set carry
-                    m.d.comb += [
-                        addend1[i].eq(1),
-                        addend2[i].eq(1),
-                    ]
-                with m.Case('01', '10'):
-                    # different number of leading zeros, so clear carry
-                    m.d.comb += [
-                        addend1[i].eq(0),
-                        addend2[i].eq(0),
-                    ]
-                with m.Case('00'):
-                    # propagate results from lower bits
-                    m.d.comb += [
-                        addend1[i].eq(1),
-                        addend2[i].eq(0),
-                    ]
+            # `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)
         carry_in = 1  # both have no leading zeros so far, so set carry
         m.d.comb += sum.eq(addend1 + addend2 + carry_in)