† A few extended topics images from CD Rom for Mitra, Sanjit Kumar, and Yonghong Kuo. Digital signal processing: a computer-based approach. Vol. 2. New York: McGraw-Hill, 2006.
Signed Interpretation (MSB used for representing Negative Numbers)
−2n−1xn−1+i=0∑n−2(2ixi)
Two's complement uses the msb to weight/contribute a large negative number instead of a large positive value
Ex: 1001 is -8 + 1=-7
4-bit signed range is 0+4+2+1 =7 to -8+0+0+0 =-8
4-bit unsigned Range is 8+4+2+1=15 to 0+0+0+0 =0
If MSB, xN−1, is 0 the interpretation is the same
unsigned: X<=2N−1−1
signed: X positive , X<=2N−1−1
If MSB, xN−1 , is 1, the interpretation is different
unsigned: X>=2N−1
signed: X negative, X>=−1×2N−1
When the MSB is 1, the adjustment from one interpretation to the other is an offset of 2 times the most significant weight, 2×2N−1, which is 2N.
Subtract 2N to go from unsigned to signed
Add 2N to go from signed to unsigned
Ex: Receive bits from a UART 10000010
as unsigned this appears to be 130, but detecting that it is >=128 and then
subtracting 256 gives results in -126
Negative Numbers in Two's Complement (2N−X)
It is also useful to think about negative twos-complement values complement in this way:
for a N-bit X, if the msb is 1 the value is the following difference: 2N - $unsigned(X)
for a 16-bit bit-vector X, if the msb is 1, the value is the distance from 216 to the value from unsigned interpretation of X
Ex:
16'b1111_1111_1111_1101 = -3 ; X+2+1 overflows to 216
16'b1111_1110_1111_1101 = -259 ; X+256+2+1 overflows to 216
Two's Complement Wheel
Helps visualize
bit interpretation
modular arithmetic
e.g. (X+Y)%24
overflow
image src:https://stackoverflow.com/questions/55145028/binary-ones-complement-in-python-3, though origin uncertain
adding (and subtracting) signed and unsigned numbers is no different at the bit/hardware level, represented as modular arithmetic
Conversion Arithmetic
The following assumes word sizes are sufficient for the conversion arithmetic, e.g. working with 12-bit words in a 16-bit architecture
Interpreting unsigned as signed:
To reinterpret (1)2N−1 as −(1)2N−1, subtract 2N
If reading bits from a data stream, the subtraction by be necessary in software
Example: a 12-bit two's complement ADC value is read from a 16-bit I/O port as 12'b0000_1000_0000_0001. Using a default interpretation in C, printf("%d",X) displays the result as 2049. What is the actual value? Ans: -2047
Interpreting signed as unsigned:
To reinterpret −(1)2N−1 as (1)2N−1, add 2N
Ex: if we print -2047 as unsigned, we get 2049
Conversion for 4-bit Data
Bits x3x2x1x0
Unsigned
relation
Signed
1111
15
−16+16
−1=24−15
1110
14
−16+16
−2=24−14
1101
13
−16+16
−3=24−13
1100
12
−16+16
−4=24−12
1011
11
−16+16
−5=24−11
1010
10
−16+16
−6=24−10
1001
9
−16+16
−7=24−9
1000
8
−16+16
−8=24−8
0111
7
=
+7
0110
6
=
+6
0101
5
=
+5
0100
4
=
+4
0011
3
=
+3
0010
2
=
+2
0001
1
=
+1
0000
0
=
+0
Visual Example: Sine Wave transmitted using 5-bit data:
Two's Complement as Complement-and-Increment
A two-step process can represent negation, without requiring extending the number of bits for the numerical symbols.
Steps:
Bit-Wise Complement
Increment
Let X and Y represent bits in hardware expressed as an unsigned interpretation, though they may store a two's complement representation
First, recall that addition and subtraction with signed and unsigned numbers are exactly the same in hardware: (let N⊞N⊟ be modular addition and subtraction)
X⊞Y is (X+Y)%2N where X and Y are the vector of bits undergoing modular addition
Negating in two’s complement:
-X: (2N⊟X) is (2N−X)%2N=−X
2N cannot be represented with N bits, and we might like to represent operations using symbols in the same domain, that of N-bit numbers.
2N−X can be represented in two operations
Let H satisfy 2N=H+1
so that H=(2N−1)=Nbits111....112
Then define negation by the following function N⊟X:(HN⊞1)N⊟X=(HN⊟X)N⊞1
Which in modular arithmetic is ((H−X)%2N+1)%2N=−X
Ex: 4-bit negation of 3
x→−x is x−24, where the magnitude of the negative number is 24−x,
but 24 has no 4-bit representation
Ones complement representation represents negative numbers by just bit-complement
Ones complement is inverting bits:
‘‘allones"HN⊟X , can be arithmetically described as ‘‘allones"(2N−1)N⊟X
in modular arithmetic is ((2N−1)−X)%2N=−1−X
Therefore, to generate a twos complement negative from a ones complement negation, just add 1 (2N−1)N⊟XN⊞1=2N–X
which as modular arithmetic is ((2N−1)−X+1)%2N=(2N–X)%2N=−X
Sign-Magnitude
For Sign-Magnitude representation, bit N-1 is the sign and the remaining bits are the magnitude
xN−1xN−2xN−3
both ones complement and sign-magnitude suffer from 0 have two representations
data streams with typically small values on either side of zero involve less bit flipping between which can be valuable for power or digital compression applied along the bit columns
In C, if a mix of signed and unsigned operands of the same rank are provided to an operator, operands are first cast to be unsigned (dumb conversion (e.g. -1→big number)).
Signed/Unsigned Casting may be followed by length adjustment.
Extension/truncation of signed value:
Truncation
Assignment to a shorter type is always just bit truncation
no Python-like smart rounding such as unsigned(-1) → 0
(Left) Truncation Errors:
For unsigned, truncation is not a problem as long as all the truncated bits are 0
ex: 0000101 (5) , can truncate at most 3 bits
For signed, truncation is no problem as long as all the bits truncated are the sameAND they match the surviving msb
ex: 1111100 (-4) , can truncate at most 4 bits
Signed and Unsigned Integral Extension
Assignment to a longer type is done with either zero or sign extension depending on the source type:
Unsigned types use zero extension
Signed types use sign extension
Long/short unsigned/signed Conversion Rules
(C/C++) Combinations of (dest type) = (source type) to consider
LHS( unsigned long)( unsigned long)( signed long)( signed long)(unsigned short)(unsigned short)( signed short)( signed short)( unsigned long)( unsigned long)( signed long)( signed long)(unsigned short)(unsigned short)( signed short)( signed short)=RHS=(unsigned long)=( signed long)=(unsigned long)=( signed long)=(unsigned long)=( signed long)=(unsigned long)=( signed long)=(unsigned short)=( signed short)=(unsigned short)=( signed short)=(unsigned short)=( signed short)=(unsigned short)=( signed short)
The C rules are simple and used in Verilog:
extend or truncate source
Going from longer to shorter, upper bits are truncated
Going from shorter to longer, zero or sign extension is done depending on source type being unsigned or signed respectively
bit copy
To/From signed/unsigned is just bit copying, no other smart manipulation/conversion/rounding is done
Twos-complement addition of two N-bit numbers can require up to N+1 bits to store a full result including the overflow
If one operand is shorter, take N to be the maximum of the two lengths
Two’s complement addition can only overflow if signs of operands are the same (likewise for subtraction the signs must be different)
Result of N-bit addition with overflow is dropping of MSBits’s: A+B = (A+B) mod (2^N)
For multiplication, multiplying two N-bit numbers requires up to 2N bits to store the operand. Multiplying a N-bit with a M-bit requires up to N+M bits.
Not All Adder Structures are Alike
Knowing the options for implementation of addition on a given platform in the context of algorithm implementation is important. There are tradeoffs for size and speed. An overview of adders is provided in a later lecture.
Verilog: Sign Extension along with Addition
Review
Sign Extension (extention of signed values) involves repeating the msb
Truncation is safe as long as alls truncated bit are the same as the surviving msb
Verilog Extention/Truncation Might be performed implicitly or explicitly
wiresigned[7:0] x,y,s;wire flagOverflow;assign s = x+y;//context determined // 8-bit addition//overflow case is when the sign of the // input operands are the same and// sign of result does not matchassign flagOverflow =(x[7]== y[7])&&(y[7]~= s[7])
Note, typically you can use an available overflow flag (e.g. V), but for software-only manipulation, or when using a language that doesn't support access to hardware flags, or if the flags are not preserved you must resort to software techniques
If possible convert data to native words (e.g. perform sign extension) to use hardware flags
Takeaway
Addition overflow possible only if input signs are same, in which case is indicated by the result is a different sign after the operation is performed
If native word-size is used, may be able to use hardware overflow flag
Otherwise, might sign-extention first or otherwise need to provide software to check appropriate bits
A pre-overflow operation check on the input operands is give by example for SIGNED INT: ((a>0) && (b>(INT_MAX-a))) | ((a<0) && (b<(INT_MIN+a)))
Run-time Overflow Detection for Subtraction
Two's complement subtraction can only under/overflow if the signs of the operands are different, otherwise the magnitude of the result must be smaller than the maximum magnitude of the two operands.
a-b, overflow is colored
Overflow check: sign bits of the input operands are different and resulting sign bit does not match the first operand
Otherwise stated: sign bit of the second operand and the result are the same and not equal to that of the first
Otherwise stated: invert the sign bit of the second operand and perform the bit test for addition overflow or negate (two's complement) second operand and perform the addition overflow test for operarands