From: Luke Kenneth Casson Leighton Date: Fri, 24 Jan 2020 13:31:12 +0000 (+0000) Subject: add beginnings of partitioned eq into unit test X-Git-Tag: ls180-24jan2020~344 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=50b043f4867c422bee10f4acee2e2f99b1c4636d;p=ieee754fpu.git add beginnings of partitioned eq into unit test --- diff --git a/src/ieee754/part/partsig.py b/src/ieee754/part/partsig.py index 1465e63e..25e90583 100644 --- a/src/ieee754/part/partsig.py +++ b/src/ieee754/part/partsig.py @@ -17,7 +17,9 @@ http://bugs.libre-riscv.org/show_bug.cgi?id=132 """ from ieee754.part_mul_add.adder import PartitionedAdder +from ieee754.part_cmp.equal import PartitionedEq from ieee754.part_mul_add.partpoints import make_partition + from nmigen import (Signal, ) @@ -27,7 +29,7 @@ class PartitionedSignal: width = self.sig.shape()[0] # get signal width self.partpoints = make_partition(mask, width) # create partition points self.modnames = {} - for name in ['add']: + for name in ['add', 'eq']: self.modnames[name] = 0 def set_module(self, m): @@ -56,3 +58,16 @@ class PartitionedSignal: else: comb += pa.b.eq(other) return pa.output + + def __eq__(self, other): + print ("eq", self, other) + shape = self.sig.shape() + pa = PartitionedEq(shape[0], self.partpoints) + setattr(self.m.submodules, self.get_modname('eq'), pa) + comb = self.m.d.comb + comb += pa.a.eq(self.sig) + if isinstance(other, PartitionedSignal): + comb += pa.b.eq(other.sig) + else: + comb += pa.b.eq(other) + return pa.output diff --git a/src/ieee754/part/test/test_partsig.py b/src/ieee754/part/test/test_partsig.py index 5d7b480f..32382117 100644 --- a/src/ieee754/part/test/test_partsig.py +++ b/src/ieee754/part/test/test_partsig.py @@ -2,11 +2,12 @@ # SPDX-License-Identifier: LGPL-2.1-or-later # See Notices.txt for copyright information -from ieee754.part.partsig import PartitionedSignal from nmigen import Signal, Module, Elaboratable from nmigen.back.pysim import Simulator, Delay, Tick, Passive from nmigen.cli import verilog, rtlil +from ieee754.part.partsig import PartitionedSignal + import unittest def create_ilang(dut, traces, test_name): @@ -27,11 +28,13 @@ class TestAddMod(Elaboratable): self.a = PartitionedSignal(partpoints, width) self.b = PartitionedSignal(partpoints, width) self.add_output = Signal(width) + self.eq_output = Signal(len(partpoints)) def elaborate(self, platform): m = Module() self.a.set_module(m) self.b.set_module(m) + m.d.comb += self.eq_output.eq(self.a == self.b) m.d.comb += self.add_output.eq(self.a + self.b) return m @@ -47,7 +50,8 @@ class TestPartitionPoints(unittest.TestCase): [part_mask, module.a.sig, module.b.sig, - module.add_output], + module.add_output, + module.eq_output], "part_sig_add") def async_process(): def test_add(msg_prefix, *mask_list): @@ -75,6 +79,31 @@ class TestPartitionPoints(unittest.TestCase): yield part_mask.eq(0b1111) yield from test_add("4-bit", 0xF000, 0x0F00, 0x00F0, 0x000F) + def test_eq(msg_prefix, *mask_list): + for a, b in [(0x0000, 0x0000), + (0x1234, 0x1234), + (0xABCD, 0xABCD), + (0xFFFF, 0x0000), + (0x0000, 0x0000), + (0xFFFF, 0xFFFF), + (0x0000, 0xFFFF)]: + yield module.a.eq(a) + yield module.b.eq(b) + yield Delay(0.1e-6) + y = 0 + for i, mask in enumerate(mask_list): + y |= ((a & mask) == (b & mask)) << i + outval = (yield module.eq_output) + 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_eq("16-bit", 0xFFFF) + yield part_mask.eq(0b10) + yield from test_eq("8-bit", 0xFF00, 0x00FF) + yield part_mask.eq(0b1111) + yield from test_eq("4-bit", 0xF000, 0x0F00, 0x00F0, 0x000F) + sim.add_process(async_process) sim.run() diff --git a/src/ieee754/part_cmp/equal.py b/src/ieee754/part_cmp/equal.py index 2fa1f0d2..e680015d 100644 --- a/src/ieee754/part_cmp/equal.py +++ b/src/ieee754/part_cmp/equal.py @@ -23,7 +23,7 @@ class PartitionedEq(Elaboratable): self.b = Signal(width, reset_less=True) self.partition_points = PartitionPoints(partition_points) self.mwidth = len(self.partition_points) - self.output = Signal(mwidth, reset_less=True) + self.output = Signal(self.mwidth, reset_less=True) if not self.partition_points.fits_in_width(width): raise ValueError("partition_points doesn't fit in width") @@ -31,14 +31,15 @@ class PartitionedEq(Elaboratable): m = Module() # make a series of "eqs", splitting a and b into partition chunks - chunks = self.width // self.mwidth eqs = Signal(self.mwidth, reset_less=True) eql = [] - keys = self.partition_points.keys() + keys = list(self.partition_points.keys()) for i in range(len(keys)-1): start, end = keys[i], keys[i+1] eql.append(self.a[start:end] == self.b[start:end]) - m.d.comb += eqs.eq(Cat(*l)) + m.d.comb += eqs.eq(Cat(*eql)) # now, based on the partition points, create the (multi-)boolean result - m.d.comb += self.out.eq(eqs) # TODO: respect partition points + m.d.comb += self.output.eq(eqs) # TODO: respect partition points + + return m