CompressionTreeMultiplyAccumulate constructor

CompressionTreeMultiplyAccumulate(
  1. Logic a,
  2. Logic b,
  3. Logic c,
  4. int radix, {
  5. required bool signed,
  6. Logic? selectSigned,
  7. ParallelPrefix ppTree(
    1. List<Logic>,
    2. Logic (
      1. Logic,
      2. Logic
      )
    ) = KoggeStone.new,
  8. String name = 'compression_tree_mac',
})

Construct a compression tree integer multiply-add with a given radix and prefix tree functor ppTree for the compressor and final adder.

a and b are the product terms, c is the accumulate term which must be the sum of the widths plus 1.

signed parameter configures the multiplier as a signed multiplier (default is unsigned).

Optional selectSigned allows for runtime configuration of signed or unsigned operation, overriding the signed static configuration.

Implementation

CompressionTreeMultiplyAccumulate(super.a, super.b, super.c, int radix,
    {required super.signed,
    Logic? selectSigned,
    ParallelPrefix Function(List<Logic>, Logic Function(Logic, Logic))
        ppTree = KoggeStone.new,
    super.name = 'compression_tree_mac'}) {
  if (selectSigned != null) {
    selectSigned = addInput('selectSigned', selectSigned);
  }
  final accumulate = addOutput('accumulate', width: a.width + b.width + 1);
  final pp = PartialProductGeneratorCompactRectSignExtension(
      a, b, RadixEncoder(radix),
      selectSigned: selectSigned, signed: signed);

  // TODO(desmonddak): This sign extension method for the additional
  //  addend may only work with CompactRectSignExtension

  final lastLength =
      pp.partialProducts[pp.rows - 1].length + pp.rowShift[pp.rows - 1];

  final sign = signed ? c[c.width - 1] : Const(0);
  final l = [for (var i = 0; i < c.width; i++) c[i]];
  while (l.length < lastLength) {
    l.add(sign);
  }
  l
    ..add(~sign)
    ..add(Const(1));

  // For online evaluate in _ColumnCompressor to work, we need to
  // insert the row rather than append it.
  pp.partialProducts.insert(0, l);
  pp.rowShift.insert(0, 0);

  final compressor = ColumnCompressor(pp)..compress();
  final adder = ParallelPrefixAdder(
      compressor.extractRow(0), compressor.extractRow(1),
      ppGen: ppTree);
  accumulate <= adder.sum.slice(a.width + b.width - 1 + 1, 0);
}