debug eq partition
[ieee754fpu.git] / src / ieee754 / part_cmp / equal.py
1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3
4 """
5 Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
6
7 dynamically-partitionable "comparison" class, directly equivalent
8 to Signal.__eq__ except SIMD-partitionable
9 """
10
11 from nmigen import Signal, Module, Elaboratable, Cat, C, Mux, Repl
12 from nmigen.cli import main
13
14 from ieee754.part_mul_add.partpoints import PartitionPoints
15
16 class PartitionedEq(Elaboratable):
17
18 def __init__(self, width, partition_points):
19 """Create a ``PartitionedEq`` operator
20 """
21 self.width = width
22 self.a = Signal(width, reset_less=True)
23 self.b = Signal(width, reset_less=True)
24 self.partition_points = PartitionPoints(partition_points)
25 self.mwidth = len(self.partition_points)+1
26 self.output = Signal(self.mwidth, reset_less=True)
27 if not self.partition_points.fits_in_width(width):
28 raise ValueError("partition_points doesn't fit in width")
29
30 def elaborate(self, platform):
31 m = Module()
32
33 # make a series of "eqs", splitting a and b into partition chunks
34 eqs = Signal(self.mwidth, reset_less=True)
35 eql = []
36 keys = list(self.partition_points.keys()) + [self.width]
37 start = 0
38 for i in range(len(keys)):
39 end = keys[i]
40 eql.append(self.a[start:end] == self.b[start:end])
41 start = end # for next time round loop
42 m.d.comb += eqs.eq(Cat(*eql))
43
44 # now, based on the partition points, create the (multi-)boolean result
45 eqsigs = []
46 for i in range(self.mwidth):
47 eqsig = Signal(self.mwidth, name="eqsig%d"%i, reset_less=True)
48 if i == 0:
49 m.d.comb += eqsig.eq(eqs[i])
50 else:
51 ppt = self.partition_points[keys[i-1]]
52 m.d.comb += eqsig.eq(eqs[i] & ppt & eqsigs[i-1])
53 eqsigs.append(eqsig)
54 print ("eqsigs", eqsigs, self.output.shape())
55 # XXX moo?? something going on here
56 for i in range(self.mwidth):
57 m.d.comb += self.output[i].eq(eqsigs[i])
58
59 return m