Arithmetic Circuits
10.3 Negative Numbers and Subtraction
With n−bit binary numbers, using Equation (10.2), we can represent only non-negative integers up to a maximum value of 2n− 1. We often refer to binary
numbers that represent only positive integers as unsigned numbers (because they don’t have a + or− sign). In this section we will see how to use binary numbers to represent both positive and negative integers, often referred to as signed numbers. To represent signed numbers, we have three main choices: 2’s complement, 1’s complement, and sign-magnitude.
The simplest system conceptually is sign-magnitude. Here we simply add a sign bit, s to the number with the convention that if s = 0 the number is positive and if s = 1 the number is negative. By convention we place the sign bit in the left-most (MSB) position. Consider the numbers +2310 and−2310. In sign-magnitude representation, +2310 = 0101112and−2310 = 1101112SM. All that changes between the two numbers is the sign bit. Our value function becomes:
v =−1s×
n−1
i=0
ai2i. (10.7)
To negate a 1’s complement number, we complement all of the bits of the number. So to negate our example number, +2310= 0101112, we get−2310= 1010002OC. The value function becomes:
v =−an−1∗ (2n−1− 1) +n−2
i=0
ai2i. (10.8)
Here the sign bit, an−1, is weighted, but by−(2n−1− 1) (a number that is all 1s in binary representation - hence the name 1’s complement).
Finally to negate a 2’s complement number, we complement all of the bits of the number and then add one. For our example number, +2310= 0101112,
−2310= 1010012. The value function becomes:
v =−an−1∗ 2n−1+
n−2
i=0
ai2i. (10.9)
Compared to one’s complement, the weight on the sign bit has been decreased by one to−2n−1.
So which of these three formats should we use in a given system? The answer depends on the system. However, the vast majority of digital systems use a 2’s complement number system because it simplifies addition and subtraction. We can add positive or negative 2’s complement numbers directly, using binary addition and get the correct answer. The same is not true of sign/magnitude or 1’s complement.
Consider for example adding +4 and −3 to get a result of +1 represented as 4-bit signed binary numbers. The inputs and outputs of this computation are shown for the three number systems below. For 2’s complement adding +4
(0100) to−3 (1101) gives +1 (10001) - the correct answer if we ignore the carry (more on carry and overflow below). In contrast, just adding the 1’s complement numbers gives 100001, and adding the sign-magnitude numbers gives 11112.
2’s comp 1’s comp sign-mag
+4 0100 0100 0100
−3 1101 1100 1011
+1 0001 0001 0001
To see why 2’s complement numbers make adding negative numbers easy, it is instructive to review how we generate a two’s complement integer. We complement the bits and add one. Complementing the bits of a number x gives 2n− 1 − x (15-x for 4-bit integers). For example, 15 − 3 = 12 which is 1100 in binary (the 1’s complement of 3). The 2’s complement of x is one more than this or 2n− x (16 − x for 4-bit integers). For example, 16 − 3 = 13 which is 1101 in binary (the 2’s complement of 3). Because all addition is performed mod 2n, the 2’s complement of a number, 2n− x is the same as −x. Hence we get the correct result. Returning to our example we have
4− 3 = 4 + (16 − 3) (mod 16)
= 17 (mod 16)
= 1
(10.10)
It is often helpful when thinking about 1’s complement or 2’s complement arithmetic to visualize the numbers on a wheel as shown in Figure 10.9. Here we show the four bit numbers from 0000 (at the 12 o’clock position) to 1111 incrementing in a clockwise direction around a circle. In Figure 10.9(a), (b), and (c) we show the values assigned to these bit patterns by the 2’s complement, 1’s complement, and sign-magnitude number systems respectively.
One thing that becomes immediately apparent from the figure is that 1’s complement and sign-magnitude do not have a unique representation for zero.
In 1’s complement for example, both 0000 and 1111 represent the value 0. This makes comparison difficult. An equality comparator (Section 8.5) cannot by itself determine if two 1’s complement or sign-magnitude numbers are equal because one may be +0 and the other−0 which is equivalent.
More importantly the circle lets us see the effect of modular arithmetic.
Adding−x to a number has the effect of moving 16 − x steps clockwise around the circle which is exactly the same as moving x steps counterclockwise around the circle. For example, −3 is equivalent to moving 13 steps clockwise or 3 steps counterclocwise, so adding−3 to any value between −5 and +7 gives the correct result. (Adding−3 to a value between −6 and −8 results in an overflow because we cannot represent results less than−8.)
1In Exercise 10–9 we see how a 1’s complement adder can be built by using an end-around carry.
2Sign-magnitude addition of negative numbers is performed by first converting to 1’s com-plement or 2’s comcom-plement
0
(a) 2's complement 0 (b) 1's complement
0000
Figure 10.9: Number wheel showing three encodings of negative numbers (a) 2’s complement, (b) 1’s complement, and (c) sign-magnitude.
Adder
Figure 10.10: A 2’s complement add/subtract unit.
How do we detect overflow when adding 2’s complement numbers? We saw above that we may generate a carry as a result of modular arithmetic and get the correct answer? However, we can still generate results that are out of range.
For example what happens when we add−3 to −6 or +4 to +4? We get +7 and
−7 respectively - both incorrect. How do we detect this to signal an overflow?
The key thing to observe here is that the signs changed. We can always add a positive number to a negative number (or vice-versa) and get a result that is in range. An overflow will only occur if we add two numbers of the same sign and get a result of the opposite sign. Thus we can detect overflows by comparing the signs of the inputs and outputs. 3
Now that we can add negative numbers, we can build a circuit to subtract. A subtractor accepts two 2’s complement numbers, a and b, as input and outputs q = a− b. A circuit to both add and subtract is shown in Figure 10.10. In add mode, the sub input is low, so the XORs pass the b input unchanged and the adder generates a + b. When the sub input is high, the XORs complement the b input and the carry into the adder is high, so the adder generates a+¯b+1 = a−b.
Figure 10.11 shows how we can augment our add/subtract circuit to detect overflow with three gates. The first XOR gate detects if the two input signs are different (sid) the second XOR determines if an input sign is different than the output sign (siod). The AND gate checks if the two input signs are the same (sid = 0) and different than the output sign (siod = 1). If so, then overflow has occured.
We can simplify the overflow detection to a single XOR gate as shown in Figure 10.12. This simplification is based on an observation about the carries into and out of the sign bit. Table 10.3 enumerates the six cases - inputs positive, different, or negative and carry in 0 or 1. When the input signs are different, (p = 1, g = 0) and the carry into the sign bit will propagate. Thus the carry in and out are the same in this case. When the inputs are both positive, (p = 0, g = 0) a carry into the sign bit indicates an overflow and will not propagate.
Finally, if the inputs are both negative (g = 1), an overflow will occur unless there is a carry into the sign bit. Thus, we see that overflow occurs iff the carry into the sign bit (cis) and the carry out of the sign bit (cos) are different.
Verilog code for the add/subtract unit is shown in Figure 10.13. This code instantiates a 1-bit adder to add the sign bits and an n− 1 bit adder to add the
3We shall see below that we can accomplish the same function by comparing the carry into the last bit with the carry out of the last bit.
ovf
Figure 10.11: A 2’s complement add/subtract unit with overflow detection based on comparison of sign bits.
as bs cis qs cos ovf comment
0 0 0 0 0 0 Both inputs positive, both carrys 0, no overflow 0 0 1 1 0 1 Both inputs positive, carry in 1, overflow 0 1 0 1 0 0 Input signs different, carry in 0, no overflow 0 1 1 0 1 0 Input signs different, carry in 1, no overflow 1 1 0 0 1 1 Both inputs negative, carry in 0, overflow 1 1 1 1 1 0 Both inputs negative, carry in 1, no overflow
Table 10.3: Cases for inputs and carry into sign bit of adder to detect overflow.
Columns show sign bit of a and b (as and bs) carry into and out of sign bit (cis and cos) and output of sign bit (qs). Overflow only occurs if the carrys into and out of the sign bit are different.
ovf
Figure 10.12: A 2’s complement add/subtract unit with overflow detection based on carry in and out of the last bit.
// add a+b or subtract a-b, check for overflow module AddSub(a,b,sub,s,ovf) ;
parameter n = 8 ; input [n-1:0] a, b ;
input sub ; // subtract if sub=1, otherwise add output [n-1:0] s ;
output ovf ; // 1 if overflow
wire c1, c2 ; // carry out of last two bits wire ovf = c1 ^ c2 ; // overflow if signs don’t match // add non sign bits
Adder1 #(n-1) ai(a[n-2:0],b[n-2:0]^{n-1{sub}},sub,c1,s[n-2:0]) ; // add sign bits
Adder1 #(1) as(a[n-1],b[n-1]^sub,c1,c2,s[n-1]) ; endmodule
Figure 10.13: Structural Verilog code for add/subtract unit with overflow dec-tion. This implementation instantiates adder modules.
remaining bits. The XOR of the b input with the sub input is performed in the argument list for each adder.
An alternative Verilog implementation is shown in Figure 10.14. This code uses assign statements with the “+” operator in place of instantiating pre-defined adders. It still performs an explicit XOR on the b input before the add.
One might be tempted to avoid the explicit XOR and instead code an add/subtract unit (ignoring overflow) using a statement like:
assign {c, s} = sub ? (a - b) : (a + b) ;
Don’t do this! Almost all synthesis systems will generate two separate adders for this code: one to do the “+” and a second to do the “-”. While this code is quite clear and easy to read, it does not synthesize well - generating twice the logic of the alternative version.
Once we have a subtractor, then, with the addition of a zero-checker on the output, we also have a comparator. If we subtract, computing s = a− b, then if s = 0 then a = b and if the sign bit of s is true, then (a− b) < 0, so a < b.
When adding 2’s complement signed numbers of different lengths, one must first sign extend the shorter number. It is required that the sign bits - which have negative weight - be in the same position. If the numbers are added without sign extension the negative weight sign bit of the shorter number will be incorrectly added to a positive weight bit of the longer number. For example, if we add 1010, a four-bit representation of−610, to 001000, a six-bit representation of +810, we get 010010 = 1810. This is because 1010 is misinterpreted as 1010.