CompressionTreeMultiplyAccumulate constructor

CompressionTreeMultiplyAccumulate(
  1. Logic a,
  2. Logic b,
  3. Logic c,
  4. int radix, {
  5. Logic? clk,
  6. Logic? reset,
  7. Logic? enable,
  8. bool signedMultiplicand = false,
  9. bool signedMultiplier = false,
  10. bool signedAddend = false,
  11. Logic? selectSignedMultiplicand,
  12. Logic? selectSignedMultiplier,
  13. Logic? selectSignedAddend,
  14. ParallelPrefix ppTree(
    1. List<Logic>,
    2. Logic (
      1. Logic,
      2. Logic
      )
    ) = KoggeStone.new,
  15. PartialProductGenerator ppGen(
    1. Logic,
    2. Logic,
    3. RadixEncoder, {
    4. Logic? selectSignedMultiplicand,
    5. Logic? selectSignedMultiplier,
    6. required bool signedMultiplicand,
    7. required bool signedMultiplier,
    }) = PartialProductGeneratorCompactRectSignExtension.new,
  16. 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.

signedMultiplicand parameter configures the multiplicand a as always signed (default is unsigned).

signedMultiplier parameter configures the multiplier b as always signed (default is unsigned).

signedAddend parameter configures the addend c as always signed (default is unsigned).

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

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

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

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

Ifclk 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 ColumnCompressor is built as a combinational tree of compressors.

Implementation

CompressionTreeMultiplyAccumulate(super.a, super.b, super.c, int radix,
    {Logic? clk,
    Logic? reset,
    Logic? enable,
    super.signedMultiplicand = false,
    super.signedMultiplier = false,
    super.signedAddend = false,
    super.selectSignedMultiplicand,
    super.selectSignedMultiplier,
    super.selectSignedAddend,
    ParallelPrefix Function(List<Logic>, Logic Function(Logic, Logic))
        ppTree = KoggeStone.new,
    PartialProductGenerator Function(Logic, Logic, RadixEncoder,
            {required bool signedMultiplier,
            required bool signedMultiplicand,
            Logic? selectSignedMultiplier,
            Logic? selectSignedMultiplicand})
        ppGen = PartialProductGeneratorCompactRectSignExtension.new,
    super.name = 'compression_tree_mac'}) {
  clk = (clk != null) ? addInput('clk', clk) : null;
  reset = (reset != null) ? addInput('reset', reset) : null;
  enable = (enable != null) ? addInput('enable', enable) : null;

  final accumulate = addOutput('accumulate', width: a.width + b.width + 1);
  final pp = ppGen(
    a,
    b,
    RadixEncoder(radix),
    selectSignedMultiplicand: selectSignedMultiplicand,
    signedMultiplicand: signedMultiplicand,
    selectSignedMultiplier: selectSignedMultiplier,
    signedMultiplier: signedMultiplier,
  );

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

  final sign = mux(
      (selectSignedAddend != null)
          ? selectSignedAddend!
          : (signedAddend ? Const(1) : Const(0)),
      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(clk: clk, reset: reset, enable: enable, pp)
        ..compress();
  final adder = ParallelPrefixAdder(
      compressor.extractRow(0), compressor.extractRow(1),
      ppGen: ppTree);
  accumulate <= adder.sum.slice(a.width + b.width - 1 + 1, 0);
}