OnesComplementAdder constructor

OnesComplementAdder(
  1. Logic a,
  2. Logic b, {
  3. Adder adderGen(
    1. Logic,
    2. Logic, {
    3. Logic? carryIn,
    }) = ParallelPrefixAdder.new,
  4. Logic? subtractIn,
  5. Logic? endAroundCarry,
  6. Logic? carryIn,
  7. bool subtract = false,
  8. bool chainable = false,
  9. String? definitionName,
  10. String name = 'ones_complement_adder',
})

OnesComplementAdder constructor with an adder functor adderGen.

  • A subtractor is created if subtract is set to true. Alternatively, if subtract configuration is false, and a Lgic control signal subtractIn is provided, then subtraction can be dynamically selected. Otherwise an adder is constructed.
  • If Logic endAroundCarry is provided, then the end-around carry is not performed and is provided as value on endAroundCarry. If endAroundCarry is null, extra hardware takes care of adding the end-around carry to sum.
  • carryIn allows for another adder to chain into this one.
  • chainable tells this adder to not store the endAroundCarry in the sign bit as well, but to zero that to allow adders to be chained such as for use in the CarrySelectCompoundAdder.

Implementation

OnesComplementAdder(super.a, super.b,
    {Adder Function(Logic, Logic, {Logic? carryIn}) adderGen =
        ParallelPrefixAdder.new,
    Logic? subtractIn,
    Logic? endAroundCarry,
    super.carryIn,
    bool subtract = false,
    bool chainable = false,
    String? definitionName,
    super.name = 'ones_complement_adder'})
    : super(
          definitionName:
              definitionName ?? 'OnesComplementAdder_W${a.width}') {
  if (endAroundCarry != null) {
    addOutput('endAroundCarry');
    endAroundCarry <= this.endAroundCarry!;
  }
  if ((subtractIn != null) & subtract) {
    throw RohdHclException(
        "either provide a Logic signal 'subtractIn' for runtime "
        " configuration, or a boolean parameter 'subtract' for "
        'generation time configuration, but not both.');
  }
  this.subtractIn =
      (subtractIn != null) ? addInput('subtractIn', subtractIn) : null;
  _sign = addOutput('sign');

  final doSubtract =
      (this.subtractIn ?? (subtract ? Const(subtract) : Const(0)))
          .named('dosubtract', naming: Naming.mergeable);

  final adderSum =
      adderGen(a, mux(doSubtract, ~b, b), carryIn: carryIn ?? Const(0))
          .sum
          .named('adderSum', naming: Naming.mergeable);

  if (this.endAroundCarry != null) {
    this.endAroundCarry! <= adderSum[-1];
  }
  final endAround = adderSum[-1].named('endaround');
  final magnitude = adderSum.slice(a.width - 1, 0).named('magnitude');
  final Logic magnitudep1;
  if (this.endAroundCarry == null) {
    final incrementer = ParallelPrefixIncr(magnitude);
    magnitudep1 = incrementer.out.named('magnitude_plus1');
  } else {
    magnitudep1 = Const(0);
  }
  sum <=
      mux(
          doSubtract,
          [
            if (chainable) endAround else Const(0),
            mux(
                [if (chainable) Const(0) else endAround].first,
                [if (this.endAroundCarry != null) magnitude else magnitudep1]
                    .first,
                ~magnitude)
          ].swizzle(),
          adderSum);
  _sign <= mux(doSubtract, ~endAround, Const(0));
}