From 87043a84ae08849e855490d62ae8c948c7826633 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Sat, 8 Feb 2020 19:55:34 -0500 Subject: [PATCH] Add rudimentary test for partitioned add with carry --- src/ieee754/part/partsig.py | 13 +++++++++++++ src/ieee754/part/test/test_partsig.py | 25 ++++++++++++++++++------- src/ieee754/part_mul_add/adder.py | 3 ++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/ieee754/part/partsig.py b/src/ieee754/part/partsig.py index 5e34f60d..2c2da8a9 100644 --- a/src/ieee754/part/partsig.py +++ b/src/ieee754/part/partsig.py @@ -112,6 +112,19 @@ class PartitionedSignal: def __add__(self, other): return self.add_op(self, other) + def addc(self, other, carry): + shape = self.sig.shape() + pa = PartitionedAdder(shape[0], self.partpoints) + setattr(self.m.submodules, self.get_modname('add'), pa) + comb = self.m.d.comb + comb += pa.a.eq(self.sig) + comb += pa.carry_in.eq(carry) + if isinstance(other, PartitionedSignal): + comb += pa.b.eq(other.sig) + else: + comb += pa.b.eq(other) + return (pa.output, pa.carry_out) + def __radd__(self, other): return self.add_op(other, self) diff --git a/src/ieee754/part/test/test_partsig.py b/src/ieee754/part/test/test_partsig.py index bbb84b80..5e5f310b 100644 --- a/src/ieee754/part/test/test_partsig.py +++ b/src/ieee754/part/test/test_partsig.py @@ -44,6 +44,8 @@ class TestAddMod(Elaboratable): self.le_output = Signal(len(partpoints)+1) self.mux_sel = Signal(len(partpoints)+1) self.mux_out = Signal(width) + self.carry_in = Signal(len(partpoints)+1) + self.carry_out = Signal(len(partpoints)+1) def elaborate(self, platform): m = Module() @@ -55,7 +57,9 @@ class TestAddMod(Elaboratable): m.d.comb += self.gt_output.eq(self.a > self.b) m.d.comb += self.eq_output.eq(self.a == self.b) m.d.comb += self.ge_output.eq(self.a >= self.b) - m.d.comb += self.add_output.eq(self.a + self.b) + add_out, add_carry = self.a.addc(self.b, self.carry_in) + m.d.comb += self.add_output.eq(add_out) + m.d.comb += self.carry_out.eq(add_carry) ppts = self.partpoints m.d.comb += self.mux_out.eq(PMux(m, ppts, self.mux_sel, self.a, self.b)) @@ -76,7 +80,7 @@ class TestPartitionPoints(unittest.TestCase): module.eq_output], "part_sig_add") def async_process(): - def test_add(msg_prefix, *mask_list): + def test_add(msg_prefix, carry, *mask_list): for a, b in [(0x0000, 0x0000), (0x1234, 0x1234), (0xABCD, 0xABCD), @@ -86,20 +90,27 @@ class TestPartitionPoints(unittest.TestCase): (0x0000, 0xFFFF)]: yield module.a.eq(a) yield module.b.eq(b) + carry_sig = 0xf if carry else 0 + yield module.carry_in.eq(carry_sig) yield Delay(0.1e-6) y = 0 - for mask in mask_list: - y |= mask & ((a & mask) + (b & mask)) + for i, mask in enumerate(mask_list): + lsb = mask & ~(mask-1) if carry else 0 + y |= mask & ((a & mask) + (b & mask) + lsb) outval = (yield module.add_output) + print(a, b, outval, carry) msg = f"{msg_prefix}: 0x{a:X} + 0x{b:X}" + \ f" => 0x{y:X} != 0x{outval:X}" self.assertEqual(y, outval, msg) yield part_mask.eq(0) - yield from test_add("16-bit", 0xFFFF) + yield from test_add("16-bit", 1, 0xFFFF) + yield from test_add("16-bit", 0, 0xFFFF) yield part_mask.eq(0b10) - yield from test_add("8-bit", 0xFF00, 0x00FF) + yield from test_add("8-bit", 0, 0xFF00, 0x00FF) + yield from test_add("8-bit", 1, 0xFF00, 0x00FF) yield part_mask.eq(0b1111) - yield from test_add("4-bit", 0xF000, 0x0F00, 0x00F0, 0x000F) + yield from test_add("4-bit", 0, 0xF000, 0x0F00, 0x00F0, 0x000F) + yield from test_add("4-bit", 1, 0xF000, 0x0F00, 0x00F0, 0x000F) def test_ne_fn(a, b, mask): return (a & mask) != (b & mask) diff --git a/src/ieee754/part_mul_add/adder.py b/src/ieee754/part_mul_add/adder.py index 84d8d910..e07101ad 100644 --- a/src/ieee754/part_mul_add/adder.py +++ b/src/ieee754/part_mul_add/adder.py @@ -199,7 +199,8 @@ class PartitionedAdder(Elaboratable): ea.append(expanded_a[expanded_index]) al.append(a_bit) # add extra bit in a eb.append(expanded_b[expanded_index]) - bl.append(self.carry_in[carry_bit]) # yes, add a zero + bl.append(self.carry_in[carry_bit] & + self.partition_points[pi]) # yes, add a zero co.append(expanded_o[expanded_index]) cl.append(self.carry_out[carry_bit-1]) expanded_index += 1 # skip the extra point. NOT in the output -- 2.30.2