add beginnings of partitioned eq into unit test
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 24 Jan 2020 13:31:12 +0000 (13:31 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 24 Jan 2020 13:31:12 +0000 (13:31 +0000)
src/ieee754/part/partsig.py
src/ieee754/part/test/test_partsig.py
src/ieee754/part_cmp/equal.py

index 1465e63ef26c6e7365a05974240803e7f40a5efb..25e90583197cca7aec995dde97a80d197007c671 100644 (file)
@@ -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
index 5d7b480f7a0ecc4e20f6a985174c560dcb1ad6f0..32382117cb007705ce943edf4bcb84ed87ed89d7 100644 (file)
@@ -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()
 
index 2fa1f0d2daf68170305406cadf71b855a8817752..e680015dfab68acc3f0637af07362b478d18270c 100644 (file)
@@ -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