CompressionTreeMultiplyAccumulate constructor
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);
}