CompressionTreeMultiplyAccumulate constructor
- Logic a,
- Logic b,
- Logic c, {
- int radix = 4,
- Logic? clk,
- Logic? reset,
- Logic? enable,
- dynamic signedMultiplicand,
- dynamic signedMultiplier,
- dynamic signedAddend,
- Adder adderGen(}) = NativeAdder.new,
- PartialProductSignExtension seGen(
- PartialProductGeneratorBase pp, {
- String name,
- String name = 'compression_tree_mac',
- bool reserveName = false,
- bool reserveDefinitionName = false,
- 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);
}