#
# 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