CarrySelectCompoundAdder constructor
Constructs a CarrySelectCompoundAdder.
Implementation
CarrySelectCompoundAdder(super.a, super.b,
{super.name = 'cs_compound_adder',
List<int> Function(int) widthGen =
splitSelectAdderAlgorithmSingleBlock}) {
// output bits lists
final sumList0 = <Logic>[];
final sumList1 = <Logic>[];
// carryout of previous ripple-carry adder block
// for sum and sum+1
Logic? carry0;
Logic? carry1;
// Get size of each ripple-carry adder block
final adderSplit = widthGen(a.width);
// 1st output bit index of each block
var blockStartIdx = 0;
for (var i = 0; i < adderSplit.length; ++i) {
// input width of current ripple-carry adder block
final blockWidth = adderSplit[i];
if (blockWidth <= 0) {
throw RohdHclException('non-positive ripple-carry adder block size.');
}
if (blockWidth + blockStartIdx > a.width) {
throw RohdHclException('oversized ripple-carry adders sequence.');
}
final blockA = Logic(name: 'block_${i}_a', width: blockWidth);
final blockB = Logic(name: 'block_${i}_b', width: blockWidth);
blockA <= a.getRange(blockStartIdx, blockStartIdx + blockWidth);
blockB <= b.getRange(blockStartIdx, blockStartIdx + blockWidth);
// Build ripple-carry adders for 0 and 1 carryin values
final fullAdder0 = RippleCarryAdder(blockA, blockB,
carryIn: Const(0), name: 'block0_$i');
final fullAdder1 = RippleCarryAdder(blockA, blockB,
carryIn: Const(1), name: 'block1_$i');
for (var bitIdx = 0; bitIdx < blockWidth; ++bitIdx) {
if (i == 0) {
// connect directly to respective sum output bit
sumList0.add(fullAdder0.sum[bitIdx]);
sumList1.add(fullAdder1.sum[bitIdx]);
} else {
final bitOut0 = Logic(name: 'bit0_${blockStartIdx + bitIdx}');
final bitOut1 = Logic(name: 'bit1_${blockStartIdx + bitIdx}');
// select adder output from adder matching carryin value
bitOut0 <=
mux(carry0!, fullAdder1.sum[bitIdx], fullAdder0.sum[bitIdx]);
bitOut1 <=
mux(carry1!, fullAdder1.sum[bitIdx], fullAdder0.sum[bitIdx]);
sumList0.add(bitOut0);
sumList1.add(bitOut1);
}
}
if (i == 0) {
// select carryout as a last bit of the adder
carry0 = fullAdder0.sum[blockWidth];
carry1 = fullAdder1.sum[blockWidth];
} else {
// select carryout depending on carryin (carryout of the previous block)
carry0 = mux(
carry0!, fullAdder1.sum[blockWidth], fullAdder0.sum[blockWidth]);
carry1 = mux(
carry1!, fullAdder1.sum[blockWidth], fullAdder0.sum[blockWidth]);
}
blockStartIdx += blockWidth;
}
// append carryout bit
sumList0.add(carry0!);
sumList1.add(carry1!);
sum <= sumList0.rswizzle();
sum1 <= sumList1.rswizzle();
}