+class AddReduceInternal:
+ """Iteratively Add list of numbers together.
+
+ :attribute inputs: input ``Signal``s to be summed. Modification not
+ supported, except for by ``Signal.eq``.
+ :attribute register_levels: List of nesting levels that should have
+ pipeline registers.
+ :attribute output: output sum.
+ :attribute partition_points: the input partition points. Modification not
+ supported, except for by ``Signal.eq``.
+ """
+
+ def __init__(self, pspec, n_inputs, part_pts, partition_step=1):
+ """Create an ``AddReduce``.
+
+ :param inputs: input ``Signal``s to be summed.
+ :param output_width: bit-width of ``output``.
+ :param partition_points: the input partition points.
+ """
+ self.pspec = pspec
+ self.n_inputs = n_inputs
+ self.output_width = pspec.width * 2
+ self.partition_points = part_pts
+ self.partition_step = partition_step
+
+ self.create_levels()
+
+ def create_levels(self):
+ """creates reduction levels"""
+
+ mods = []
+ partition_points = self.partition_points
+ ilen = self.n_inputs
+ while True:
+ groups = AddReduceSingle.full_adder_groups(ilen)
+ if len(groups) == 0:
+ break
+ lidx = len(mods)
+ next_level = AddReduceSingle(self.pspec, lidx, ilen,
+ partition_points,
+ self.partition_step)
+ mods.append(next_level)
+ partition_points = next_level.i.part_pts
+ ilen = len(next_level.o.terms)
+
+ lidx = len(mods)
+ next_level = FinalAdd(self.pspec, lidx, ilen,
+ partition_points, self.partition_step)
+ mods.append(next_level)
+
+ self.levels = mods
+
+
+class AddReduce(AddReduceInternal, Elaboratable):