1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3 """Integer Multiplication."""
5 from nmigen
import Signal
, Value
, Cat
, C
8 class PartitionPoints(dict):
9 """Partition points and corresponding ``Value``s.
11 The points at where an ALU is partitioned along with ``Value``s that
12 specify if the corresponding partition points are enabled.
14 For example: ``{1: True, 5: True, 10: True}`` with
15 ``width == 16`` specifies that the ALU is split into 4 sections:
18 * bits 5 <= ``i`` < 10
19 * bits 10 <= ``i`` < 16
21 If the partition_points were instead ``{1: True, 5: a, 10: True}``
22 where ``a`` is a 1-bit ``Signal``:
23 * If ``a`` is asserted:
26 * bits 5 <= ``i`` < 10
27 * bits 10 <= ``i`` < 16
30 * bits 1 <= ``i`` < 10
31 * bits 10 <= ``i`` < 16
34 def __init__(self
, partition_points
=None):
35 """Create a new ``PartitionPoints``.
37 :param partition_points: the input partition points to values mapping.
40 if partition_points
is not None:
41 for point
, enabled
in partition_points
.items():
42 if not isinstance(point
, int):
43 raise TypeError("point must be a non-negative integer")
45 raise ValueError("point must be a non-negative integer")
46 self
[point
] = Value
.wrap(enabled
)
48 def like(self
, name
=None, src_loc_at
=0, mul
=1):
49 """Create a new ``PartitionPoints`` with ``Signal``s for all values.
51 :param name: the base name for the new ``Signal``s.
52 :param mul: a multiplication factor on the indices
55 name
= Signal(src_loc_at
=1+src_loc_at
).name
# get variable name
56 retval
= PartitionPoints()
57 for point
, enabled
in self
.items():
59 retval
[point
] = Signal(enabled
.shape(), name
=f
"{name}_{point}")
63 """Assign ``PartitionPoints`` using ``Signal.eq``."""
64 if set(self
.keys()) != set(rhs
.keys()):
65 raise ValueError("incompatible point set")
66 for point
, enabled
in self
.items():
67 yield enabled
.eq(rhs
[point
])
69 def as_mask(self
, width
, mul
=1):
70 """Create a bit-mask from `self`.
72 Each bit in the returned mask is clear only if the partition point at
73 the same bit-index is enabled.
75 :param width: the bit width of the resulting mask
76 :param mul: a "multiplier" which in-place expands the partition points
77 typically set to "2" when used for multipliers
80 for i
in range(width
):
82 if i
.is_integer() and int(i
) in self
:
88 def get_max_partition_count(self
, width
):
89 """Get the maximum number of partitions.
91 Gets the number of partitions when all partition points are enabled.
94 for point
in self
.keys():
99 def fits_in_width(self
, width
):
100 """Check if all partition points are smaller than `width`."""
101 for point
in self
.keys():
106 def part_byte(self
, index
, mfactor
=1): # mfactor used for "expanding"
107 if index
== -1 or index
== 7:
109 assert index
>= 0 and index
< 8
110 return self
[(index
* 8 + 8)*mfactor
]