From d90811b3495ae02da1f1eb854faa48d2b3b7ef9c Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 7 Apr 2022 11:27:43 +0100 Subject: [PATCH] simplify code by removing for-loop and commenting why it was removed --- src/nmigen_gf/hdl/cldivrem.py | 48 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/nmigen_gf/hdl/cldivrem.py b/src/nmigen_gf/hdl/cldivrem.py index 4ce94ce..973e0c9 100644 --- a/src/nmigen_gf/hdl/cldivrem.py +++ b/src/nmigen_gf/hdl/cldivrem.py @@ -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 -- 2.30.2