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)