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
generateEndAroundCarry
istrue
, then the end-around carry is not performed and is provided as output endAroundCarry. IfgenerateEndAroundCarry
isfalse
, extra hardware takes care of adding the end-around carry to sum. generateEndAroundCarry
avoids 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'.
Implementation
// TODO(desmonddak): this adder may need a carry-in for rounding
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.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,
subtractIn: sub,
adderGen: adderGen);
sum <= adder.sum;
if (generateEndAroundCarry) {
endAroundCarry! <=
(largestMagnitudeFirst ? adder.endAroundCarry! : Const(0));
}
}