OnesComplementAdder constructor
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));
}