CarrySelectOnesComplementCompoundAdder constructor
Constructs a CarrySelectCompoundAdder using a set of
OnesComplementAdder in a carry-select configuration.
Adds (or subtracts) a
and b
to produce sum and sumP1 (sum
plus 1).
adderGen
is the adder used inside the OnesComplementAdder.subtractIn
is an optional Logic control for subtraction.subtract
is a boolean control for subtraction. It must be false(default) if asubtractIn
Logic is provided.widthGen
is a function which produces a list for splitting the adder for the carry-select chain. The default is CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock,
Implementation
CarrySelectOnesComplementCompoundAdder(super.a, super.b,
{Adder Function(Logic, Logic, {Logic? carryIn}) adderGen =
ParallelPrefixAdder.new,
Logic? subtractIn,
Logic? carryOut,
Logic? carryOutP1,
bool subtract = false,
List<int> Function(int) widthGen =
CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock,
super.name})
: super(
definitionName:
'CarrySelectOnesComplementCompoundAdder_W${a.width}') {
subtractIn = (subtractIn != null)
? addInput('subtractIn', subtractIn, width: subtractIn.width)
: null;
if (carryOut != null) {
addOutput('carryOut');
carryOut <= this.carryOut!;
}
if (carryOutP1 != null) {
addOutput('carryOutP1');
carryOutP1 <= this.carryOutP1!;
}
final doSubtract = subtractIn ?? (subtract ? Const(subtract) : Const(0));
final csadder = CarrySelectCompoundAdder(a, b,
widthGen: widthGen,
subtractIn: subtractIn,
adderGen: (a, b, {carryIn, subtractIn, name = 'ones_complement'}) =>
OnesComplementAdder(a, b,
adderGen: adderGen,
carryIn: carryIn,
endAroundCarry: Logic(),
subtract: subtract,
chainable: true,
subtractIn: subtractIn));
addOutput('sign') <= mux(doSubtract, ~csadder.sum[-1], Const(0));
addOutput('signP1') <= mux(doSubtract, ~csadder.sumP1[-1], Const(0));
final sumPlus1 =
mux(doSubtract & csadder.sumP1[-1], ~csadder.sumP1, csadder.sumP1);
if (carryOutP1 != null) {
sumP1 <= sumPlus1;
this.carryOutP1! <= csadder.sumP1[-1];
} else {
final incrementer = ParallelPrefixIncr(sumPlus1);
sumP1 <= incrementer.out.named('sum_plus2');
}
if (carryOut != null) {
sum <= mux(doSubtract & csadder.sum[-1], ~csadder.sum, csadder.sum);
this.carryOut! <= csadder.sum[-1];
} else {
sum <= sumPlus1;
}
}