SignMagnitudeAdder constructor
SignMagnitudeAdder constructor with an adder functor adderGen.
Inputs are (sign, magnitude) pairs: (aSign, a) and (bSign, b). If
the caller can guarantee that the larger magnitude value is provided first
in a, then they can set largestMagnitudeFirst to true to avoid
adding a comparator. Without the comparator, the sign may be wrong, but
magnitude will be correct.
- If
generateEndAroundCarryistrue, then the end-around carry is not performed and is provided as output endAroundCarry. IfgenerateEndAroundCarryisfalse, extra hardware takes care of adding the end-around carry to sum. generateEndAroundCarryavoids extra hardware to add the '1' in an end-around carry during subtraction. For subtractions that remain positive the endAroundCarry will hold that final +1 that needs to be added. For subtractions that go negative, the endAroundCarry will be '0'.carryIn, if provided, is injected as an additional carry into the internal magnitude computation (e.g. to inject a rounding increment computed from bits discarded prior to this addition).
Implementation
SignMagnitudeAdder(super.aSign, super.a, super.bSign, super.b,
{Adder Function(Logic a, Logic b, {Logic? carryIn}) adderGen =
NativeAdder.new,
this.largestMagnitudeFirst = false,
bool generateEndAroundCarry = false,
super.carryIn,
super.name = 'sign_magnitude_adder',
super.reserveName,
super.reserveDefinitionName,
String? definitionName})
: super(
definitionName:
definitionName ?? 'SignMagnitudeAdder_W${a.width}') {
if (generateEndAroundCarry) {
addOutput('endAroundCarry');
}
if (!largestMagnitudeFirst) {
final bLarger = a.lt(b) | (a.eq(b) & bSign.gt(aSign));
_sign <= mux(bLarger, bSign, aSign);
} else {
_sign <= aSign;
}
final sub = aSign ^ bSign;
final adder = OnesComplementAdder(
mux(_sign & sub, ~a, a), mux(_sign & sub, ~b, b),
generateEndAroundCarry: largestMagnitudeFirst & generateEndAroundCarry,
subtract: sub,
carryIn: carryIn,
adderGen: adderGen);
sum <= adder.sum;
if (generateEndAroundCarry) {
endAroundCarry! <=
(largestMagnitudeFirst ? adder.endAroundCarry! : Const(0));
}
}