OnesComplementAdder constructor

OnesComplementAdder(
  1. Logic a,
  2. Logic b, {
  3. Adder adderGen(
    1. Logic,
    2. Logic
    ) = ParallelPrefixAdder.new,
  4. Logic? subtractIn,
  5. Logic? carryOut,
  6. bool subtract = false,
  7. String name = 'ones_complement_adder',
})

OnesComplementAdder constructor with an adder functor adderGen Either a Logic subtractIn or a boolean subtract can enable subtraction, with subtractIn overriding subtract. If Logic carryOut is provided as not null, then the end-around carry is not performed and is left to the caller via the output carryOut.

Implementation

OnesComplementAdder(super.a, super.b,
    {Adder Function(Logic, Logic) adderGen = ParallelPrefixAdder.new,
    Logic? subtractIn,
    Logic? carryOut,
    bool subtract = false,
    super.name = 'ones_complement_adder'}) {
  if (subtractIn != null) {
    subtractIn = addInput('subtractIn', subtractIn);
  }
  _sign = addOutput('sign');
  if (carryOut != null) {
    addOutput('carryOut');
    carryOut <= this.carryOut!;
  }
  if ((subtractIn != null) & subtract) {
    throw RohdHclException(
        'Subtraction is controlled by a non-null subtractIn: '
        'subtract boolean is ignored');
  }
  final doSubtract = subtractIn ?? (subtract ? Const(1) : Const(0));

  final ax = a.zeroExtend(a.width);
  final bx = b.zeroExtend(b.width);

  final adder = adderGen(ax, mux(doSubtract, ~bx, bx));

  if (this.carryOut != null) {
    this.carryOut! <= adder.sum[-1];
  }
  final endAround = mux(doSubtract, adder.sum[-1], Const(0));
  final magnitude = adder.sum.slice(a.width - 1, 0);

  sum <=
      mux(
          doSubtract,
          mux(
                  endAround,
                  [if (this.carryOut != null) magnitude else magnitude + 1]
                      .first,
                  ~magnitude)
              .zeroExtend(sum.width),
          adder.sum);
  _sign <= mux(doSubtract, ~endAround, Const(0));
}