CompressionTreeMultiplyAccumulate constructor

CompressionTreeMultiplyAccumulate(
  1. Logic a,
  2. Logic b,
  3. Logic c, {
  4. int radix = 4,
  5. Logic? clk,
  6. Logic? reset,
  7. Logic? enable,
  8. dynamic signedMultiplicand,
  9. dynamic signedMultiplier,
  10. dynamic signedAddend,
  11. Adder adderGen(
    1. Logic a,
    2. Logic b, {
    3. Logic? carryIn,
    }) = NativeAdder.new,
  12. PartialProductSignExtension seGen(
    1. PartialProductGeneratorBase pp, {
    2. String name,
    }) = CompactRectSignExtension.new,
  13. String name = 'compression_tree_mac',
  14. bool reserveName = false,
  15. bool reserveDefinitionName = false,
  16. String? definitionName,
})

Construct a compression tree integer multiply-add with a given radix and an Adder generator functor adderGen for the final adder.

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

Sign extension methodology is defined by the partial product generator supplied via seGen.

If clk is not null then a set of flops are used to latch the output after compression. reset and enable are optional inputs to control these flops when clk is provided. If clk is null, the Column Compressor is built as a combinational tree of compressors.

Implementation

CompressionTreeMultiplyAccumulate(super.a, super.b, super.c,
    {int radix = 4,
    Logic? clk,
    Logic? reset,
    Logic? enable,
    super.signedMultiplicand,
    super.signedMultiplier,
    super.signedAddend,
    Adder Function(Logic a, Logic b, {Logic? carryIn}) adderGen =
        NativeAdder.new,
    PartialProductSignExtension Function(PartialProductGeneratorBase pp,
            {String name})
        seGen = CompactRectSignExtension.new,
    super.name = 'compression_tree_mac',
    super.reserveName,
    super.reserveDefinitionName,
    String? definitionName})
    : super(
          definitionName: definitionName ??
              'CompressionTreeMAC_W${a.width}x${b.width}_Acc${c.width}_'
                  '${MultiplyAccumulate.signedAD(signedAddend)}') {
  final ppg = PartialProductGenerator(
    a,
    b,
    RadixEncoder(radix),
    selectSignedMultiplicand: selectSignedMultiplicand,
    signedMultiplicand: signedMultiplicand,
    selectSignedMultiplier: selectSignedMultiplier,
    signedMultiplier: signedMultiplier,
  );

  seGen(ppg).signExtend();

  final lastRowLen =
      ppg.partialProducts[ppg.partialProducts.length - 1].length +
          ppg.rowShift[ppg.partialProducts.length - 1];

  final additionalRowSign = mux(
      (selectSignedAddend != null)
          ? selectSignedAddend!
          : (signedAddend ? Const(1) : Const(0)),
      c[c.width - 1],
      Const(0));

  final additionalRow = [for (var i = 0; i < c.width; i++) c[i]];
  while (additionalRow.length < lastRowLen) {
    additionalRow.add(additionalRowSign);
  }
  additionalRow
    ..add(~additionalRowSign)
    ..add(Const(1));

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

  final ppgRows = [
    for (var row = 0; row < ppg.partialProducts.length; row++)
      ppg.partialProducts[row].rswizzle()
  ];

  final compressor = ColumnCompressor(ppgRows, ppg.rowShift,
      clk: clk, reset: reset, enable: enable);
  final adder = adderGen(compressor.add0, compressor.add1);
  accumulate <= adder.sum.slice(a.width + b.width - 1 + 1, 0);
}