CarrySelectCompoundAdder constructor

CarrySelectCompoundAdder(
  1. Logic a,
  2. Logic b, {
  3. Logic? subtractIn,
  4. Logic? carryIn,
  5. Adder adderGen(
    1. Logic a,
    2. Logic b, {
    3. Logic? carryIn,
    4. String name,
    5. Logic? subtractIn,
    }) = _defaultBlockAdder,
  6. List<int> widthGen(
    1. int
    ) = splitSelectAdderAlgorithmSingleBlock,
  7. String name = 'cs_compound_adder',
  8. bool reserveName = false,
  9. bool reserveDefinitionName = false,
  10. String? definitionName,
})

Constructs a CarrySelectCompoundAdder.

  • carryIn is a carry Logic into the CarrySelectCompoundAdder
  • adderGen provides an adder Function which must supply optional carryIn and subtractIn Logic controls.
  • subtractIn This option is used by the CarrySelectOnesComplementCompoundAdder and should not be used directly as it requires ones-complement behavior from adderGen.
  • widthGen is the splitting Function for creating the different adder blocks. Decreasing the split width will increase speed but also increase area.

Implementation

CarrySelectCompoundAdder(
  super.a,
  super.b, {
  Logic? subtractIn,
  super.carryIn,
  Adder Function(Logic a, Logic b,
          {Logic? carryIn, Logic? subtractIn, String name})
      adderGen = _defaultBlockAdder,
  List<int> Function(int) widthGen = splitSelectAdderAlgorithmSingleBlock,
  super.name = 'cs_compound_adder',
  super.reserveName,
  super.reserveDefinitionName,
  String? definitionName,
}) : super(
          definitionName: definitionName ??
              'CarrySelectCompoundAdder_${adderGen(a, b).definitionName}') {
  subtractIn = (subtractIn != null)
      ? addInput('subtractIn', subtractIn, width: subtractIn.width)
      : null;
  // output bits lists
  final sumList0F = <Logic>[];
  final sumList1F = <Logic>[];
  // carryout of previous adder block
  // for sum and sum+1
  Logic carry0 = Const(0);
  Logic carry1 = Const(0);
  // Get size of each 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 adder block
    final blockWidth = adderSplit[i];
    final sum0Ary = Logic(width: blockWidth);
    final sum1Ary = Logic(width: blockWidth);
    if (blockWidth <= 0) {
      throw RohdHclException('non-positive adder block size.');
    }
    final blockEnd = blockStartIdx + blockWidth;
    if (blockEnd > a.width) {
      throw RohdHclException('oversized adders sequence.');
    }
    // Build sub adders for carryIn=0 and carryIn=1
    final fullAdder0 = adderGen(a.getRange(blockStartIdx, blockEnd),
        b.getRange(blockStartIdx, blockEnd),
        subtractIn: subtractIn, carryIn: Const(0), name: 'block0_$i');
    final fullAdder1 = adderGen(a.getRange(blockStartIdx, blockEnd),
        b.getRange(blockStartIdx, blockEnd),
        subtractIn: subtractIn, carryIn: Const(1), name: 'block1_$i');
    sum0Ary <=
        ((i == 0)
                ? fullAdder0.sum
                : mux(carry0, fullAdder1.sum, fullAdder0.sum))
            .slice(0, blockWidth - 1)
            .named('block_${i}_sum0Ary');

    sum1Ary <=
        ((i == 0)
                ? fullAdder1.sum
                : mux(carry1, fullAdder1.sum, fullAdder0.sum))
            .slice(0, blockWidth - 1)
            .named('block_${i}_sum1Ary');

    sumList0F.add(sum0Ary);
    sumList1F.add(sum1Ary);
    if (i == 0) {
      // select carryout as a last bit of the adder
      carry0 = fullAdder0.sum[blockWidth].named('block_${i}_adder0Msb');
      carry1 = fullAdder1.sum[blockWidth].named('block_${i}_adder1Msb');
    } else {
      // select carryout depending on carryin (carryout of the previous block)
      carry0 =
          mux(carry0, fullAdder1.sum[blockWidth], fullAdder0.sum[blockWidth])
              .named('block_${i}_carry0');
      carry1 =
          mux(carry1, fullAdder1.sum[blockWidth], fullAdder0.sum[blockWidth])
              .named('block_${i}_carry1');
    }

    blockStartIdx += blockWidth;
  }

  sum <= [sumList0F.swizzle(), carry0].swizzle().named('sum_inner').reversed;
  sumP1 <=
      [sumList1F.swizzle(), carry1].swizzle().named('sumP1_inner').reversed;
}