ENEE244: Combinational Logic
Array Multiplier
A circuit that involves calculating the partial products for multiplication and adding them all up in the end. To get each partial product, we take one bit in the multiplier & AND it with every bit in the multiplicand. For each new partial product, we shift the bit position left 1 (essentially multiplying by 2).
Tree Decoder
A decoder constructed from many smaller decoders. Ex: 6:64 decoder. Send 3 inputs to one 3:8 decoder, and send in the other three inputs to eight 3:8 decoders with an enable. Then, simply send one of the eight outputs of the "root" as the enable signal for its corresponding decoder. Convention is to send the MSBs of the encoded number to the root decoder so that the output wires go from 0 - 63.
Carry Select Adder (SCA)
A type of adder that uses "parallel computation" to speed up adding. Uses one 4-bit adder to add the 4 LSBs. The 4 MSBs are added using two 4-bit adders. One of those adders is fed in a carry of 0 and the other is fed in a carry of 1. The results of those two adders are passed into a 5-bit 2:1 MUX that takes in the carry from the LSBs as an input. Based on whether that carry was a 0 or a 1, it will choose which 4-bit sum+carry is valid and pass it through.
Booth Multiplication
A way of halving the number of partial products to perform more efficient addition. The goal is to take groups of 2 bits in the multiplier and recode them into a single number. Steps: Take the multiplier, and for every bit, compute the previous bit minus the current bit. Write that value below the current bit. Group the values into groups of 2 and multiply the leftmost bit in each group by 2. Sum the values in each group of 2 Ex. Recode 100101 100101 -1 0 1 -1 1 -1 -2 0 2 -1 2 -1 -2 1 1 Now, you simply perform the multiplication: For every partial product, make sure to shift over 2 places instead of 1. Whenever you see a 1, copy down the multiplicand. Whenever you see a 0, write all 0s Whenever you see a negative, 2's complement the result Whenever you see a 2, bitshift everything to the left (same as multiplying by 2)
Use Case for encoders and decoders
Accessing a memory address: Have a wire going to each memory address. To select an address, encode the binary value of the address and then decode that number later in the circuit
Look ahead Carry Adder (LCA)
An adder that relies on two different signals for addition: carry generate and carry propogate. Once these signals are generated for a given pair of bits, the results can be computed with at most 2 gate delays. Has the issue of fan-out where the gates get very big for large enough numbers (size of final OR gate = n+1)
Priority Encoder
An encoder in which only the highest value input digit is encoded and any other active input is ignored. Essentially, it can handle many inputs being HIGH. However, it will commonly have a valid output (V) that will only be high if all inputs are 0. The truth table is pretty simple. When you have all 0s, V is one and the other inputs are don't cares. When you have the highest bit, everything else is a don't care. When the highest bit is 0 and the next highest bit is 1, everything below is a don't care, etc. etc.
Adding two BCD Numbers
Because BCD numbers can only range from 0-9, you have to detect whenever the 4-bit sum is above 9. If we do get a sum above 9, we should add 6 to get to the next digit because BCD skips 6 binary codes (1001 - 1111). When to add 6: If the sum is from 0000 - 1001 (0-9), don't add 6. If the sum is from 1010 - 1111 (10-15), add 6 - This occurs when the MSB of the sum is 1 AND when either of the two middle bits are 1. If we get a carry, add 6 - This would occur if we do 9+9 for instance. Because 18>15, we need 5 bits to represent the number. If we don't add 6 after getting the carry, we get the number 0001 0010, which is 12, not 18. So we have to add the 6
Decoder with an Enable
Does the same job as an encoder except it returns all 0s if enable is 0. To implement it, simply add the enable signal as an additional input to each AND gate on a regular decoder.
Floating Point Addition Steps
Equalize Exponents Perform Mantissa addition (don't forget the hidden '1.') Re normalize the result
Designing Everything with Decoders
For a given expression, you can represent it with a decoder by taking in the given inputs and performing an OR on each minterm that can yeild a valid answer
Carry Formulas (LCA)
For the ith bit in series: c_i = g_i + p_i*c_(i-1) Logic: We either get a carry by generating it from the current bits or by propagating the previous carry. s_i = p_i XOR c_i Logic: A sum will appear if there was a carry that "stayed" or if there was no carry and only one bit was on.
Magnitude Comparator (signed)
How to compare two signed numbers? Ex. A < B? If A & B are both positive or both negative, our unsigned A < B algorithm works How do we deal with when A and B don't have the same sign? You can simply invert the MSB of A and B and run it through the old algorithm. To see why this works, test it! If A is negative and B is positive, reversing the MSB of A will make A
Overflow Detection
How to detect if you have arithmetic overflow: Unsigned addition: If your carry out is 1, you have overflow Signed Addition: If your carry out XOR the carry right before is true, you have overflow. This works on both overflow and underflow
Mutli-Bit Multiplexer
Like a regular multiplixer, except each input port is n-bits wide. Implementation: either use many single-bit MUX's or wider AND gates
Half LCA
Like an LCA, but you generate signals for an entire block of values. Ex: a 16-bit adder. For each 4-bit block, generate a propagate and a generate. Plug those into the regular LCA circuit and voila, you've added a 16-bit number!! Error: O(log_4(n)) P_0-3 = P0*P1*P2*P3 Logic: You will only propagate a carry if all bits propogate one G_0-3 = G3+G2*P3+G1*P2*P3+G0*P1*P2*P3 Logic: You will only generate a carry if the last bit generates a carry, or if a previous bit generates one and propogates it.
Floating Point Multiplication Steps
Multiply the mantissas (don't forget hidden '1.') Add exponenets (subtract 127 because they are stored in XS127) Renormalize
Comparator (unsigned)
Produce a less than output, a greater than output, and an equals ouput. Equals: A equals B if for all bits in A&B, A XNOR B = 1 Less than: Strategy for checking if A<B: Starting at the MSB, go through every bit. If A is a 0 when B is a 1, A < B. If you go through the whole number and that's not the case, A isn't < B. Ex. A & B are 3-bit numbers A<B = A2'B2 + (A2 XNOR B2)*A1'B1 + (A2 XNOR B2) (A2 XNOR B2)* A0'B0 Greater than: same as less than.
Subtractor for two signed ints
Strategy: Take the number being subtracted and 2's complement it. To do that, you can NOT each bit in the number being subtracted and add 1 as a carry. Then plug that all into an n-bit adder
Encoder
Take a bunch of inputs, where only a single value is 1, and produce the corresponding binary number A:B indicates that it takes in A inputs and produces B outputs B = log_2(A) PRECONDITION: We must be assured that ONLY 1 input is true, otherwise encoders won't work Implemented by looking at the truth table for a decoder. Find every possible minterm that turns each output into a 1, and OR them together.
General Circuit Design Procedure
Take in a desired function, represent it using truth tables/a boolean expression, simplify the expression, and implement using logic gates
Decoder
Takes in a small number of inputs representing a binary number, and selects a corresponding output to be 1. Really easy to implement: Just need to consider all possibilities for the inputs and have a corresponding AND gate for each minterm. Number of outputs = 2^(number of inputs) A:B indicates that you are taking A inputs and producing one of B outputs
Half Adder
Takes in only two bits and produces their sum and carry. Sum = A XOR B Carry = AB
Full Adder
Takes in two bits and a carry and produces the corresponding sum and a carry. Sum = A XOR B XOR C_in C_out = AC_in + AB + BC_in
Multiplexer
Takes many inputs and chooses one of them to be an output based on selection inputs. # of select inputs = log_2(data inputs) You can easily derive a boolean expression: Ex. 4:1 MUX 1-bit F=S1'*S0'*D0+S1'*S0*D1+S1*S0'*D2+S1*S0*D3 Decoder Implementation: Use a decoder on the selection inputs. AND the decoder outputs with the corresponding MUX input. OR the results together.
Multiplying Signed Integers
When the multiplier is negative: you must perform SIGN EXTENSION for each partial product (i.e., if the MSB is a 1, continue placing 1s to the left until you get to the the last digit in the largest partial product). Then, if the number you're multiplying by is negative, make sure to 2's complement the final partial product. Ex.
Adding Two XS3 Numbers
When you add two numbers in XS3, you're essentially computing (a+3)+(b+6) = a+b+6. This means that your result is actually in XS6. To go back to XS3, you have to subtract the result by three. Ex. To add A + B, where A & B are both in XS3, you would calculate A + B - 3.
Ripple Carry Adder (RCA)
When you chain together the outputs of many Full Adders to produce an n-bit adder. This has a propagation delay that is O(n).
Carry Propogate
Whether or not a carry coming into an LCA adder will produce a carry. p = A+B, although we typically use p = A XOR B because the carry generate already takes into account the case that AB = 1.
Carry Generate
Whether or not two input puts will produce a carry. g = AB