Due: Friday, February 20 at the close of lab (just hand your writeup to a TA).
You are to do this lab alone
In this lab you will create some of the arithmetic and logical components of your R372 processor. Specifically, you will create a 16-bit ALU (complete with carry lookahead adder) and a 16-bit arithmetic/logical left/right barrel shifter. For this assigment you will use schematics only. As you should be somewhat more familiar with the Xilinx tools, you should be able to finish the assignment more quickly than you finished the previous one. In spite of this, don't procrastinate. The number of machines is limited as is TA time (you will still have to do demonstrations). Get started early.
Exercise 1: 16-bit MUX using two levels of logic and tri-state buffers (20 points)
Since both the ALU and the barrel shifter will internally contain multiple 16-bit functions, each will require an N-to-1 16-bit MUX. As we saw (and will see) in class, there are two ways to create MUXes. One way is to select among multiple 16-bit buses using a two-level AND/OR network.
1. Create a symbol and schematic AND/OR implementation of a 1-bit 2-to-1 MUX. Combine 16 of these symbols to create a 16-bit 2-to-1 MUX.
Another way is to route each 16-bit input through a tri-state buffer, and then connect the N buffered inputs directly to one output. It should be obvious how the first implementation works, but how does the tri-state implementation work? How is it possible to connect multiple input buses directly to one output bus? How does the selection take place?
The key is the tri-state device itself. A tri-state device is a non-inverting buffer with an additional control input. If the control is high (or low, there are both kinds of tri-state buffers just like there are both kinds of D-flip-flops) the output drives (i.e., is directly connected to power or ground and thus generates current) the value on the input. If the control input is low, the output is not connected to either power or ground, generates no current and is said to be in a "high-impedance" state (which symbolically is represented as "Z").
N tri-state buffered inputs connected to a single output act as an N-to-1 MUX if at any time only one of the inputs is not in the Z state. An M-bit N-to-1 MUX can therefore be created out of a lgN-to-N decoder and N M-bit tri-state buffers.
2. Create a symbol and a schematic for a 16-bit control-high (i.e., the output is driven if the control input is 1) tri-state buffer. Use the BUFE component.
3. Use four 16-bit tri-state buffers and the 2-to-4 decoder from your first assignment to create a symbol and a schematic implementation of a 16-bit 4-to-1 MUX.
4. Use five 16-bit tri-state buffers and the 3-to-8 decoder from your first assignment to create a symbol and schematic implementation of a 16-bit 5-to-1 MUX. The unused decoder outputs should be outputs 1, 2 and 3.
Turn in your schematics and a timing diagram for the 16-bit 2-to-1 MUX and the 16-bit 5-to-1 MUX showing all possible selections. The values on the input buses should be equal to the numbers of the buses (e.g., 0000, 0001, 0002, etc.).
Exercise 2: 16-bit ALU (50 points)
For this exercise, you will create a 16-bit ALU. The ALU has two 16-bit data inputs, A and B, and a 16-bit data output O. The ALU also has a 3-bit control input ALUOP that determines O as a function of A and B. The ALUOP definition is:
You should try to create this ALU efficiently and reuse as many calculations as possible. For instance, use a single adder to implement both addition and subtraction, use the fact that subtraction already requires the negation of the second input and reuse the negation circuit, use the fact that carry lookahead already requires the computation of A & B and A | B to avoid duplicating those gates as well.
Break this task down into a series of component tasks.
1. Create a symbol and schematic implementation of a 16-bit negation circuit.
2. Create a symbol and a schematic implementation of a 16-bit XOR circuit.
3. Create a symbol and a schematic implementation of a 16-bit AND circuit.
4. Create a symbol and a schematic implementation of a 16-bit OR circuit.
5. Create a symbol and a schematic implementation of a 4-bit carry lookahead block. The inputs to the block should be two 4-bit buses, g and p, and a 1-bit signal CARRYIN. The output should be two 1-bit signals, G and P, which are the generate and propagate signals for the group, and a 3-bit CARRYOUT bus which are the interior carries of the group.
6. Create a symbol and schematic implementation of a 16-bit carry lookahead/calculate block using five copies of the 4-bit carry lookahead block. The inputs to the block should be two 16-bit buses, g and p, and a 1-bit CARRYIN. The output should be one 16-bit bus, CARRYOUT, which is the carry out of each of the 16 bit individual additions.
7. Create a symbol and a schematic implementation of a 16-bit ALU using the 16-bit carry lookahead block, the 16-bit negation block, the 16-bit AND block, the 16-bit OR block, the 16-bit XOR block (you will need two of these), a 16-bit 2-to-1 MUX, a 1-bit 2-to-1 MUX, and the 16-bit 5-to-1 MUX.
Turn in your schematics and a timing diagram showing each one of your functions. For the logical functions, use 00FF and 0F0F as the values for A and B, respectively. For both addition and subtraction, use the following combinations of A and B to show that your design works properly on positive and negative numbers: 000F and 000F, FFF0 and FFF0, 000F and FF00, and FF00 and 000F. Demonstrate your design to the TA.
Exercise 3: 16-bit Barrel Shifter (25 points)
For this exercise, you will create a 16-bit barrel shifter. The shifter has two data inputs, a 16-bit A and a 4-bit SHAMT, and one 16-bit output C. It also has a 2-bit control input SHOP that determines C as a function of A and SHAMT. The SHOP defintion is:
Use the 16-bit 4-to-1 MUX from exercise and the barrel design shown in class to create a symbol and a schematic implementation of this component. Note, there are several ways to do this. You could create three different barrel shifters using 2-to-1 MUXes at each level of the barrel. You would then use a 4-to-1 MUX (with one duplicated input) to select between the at the end. A cleaner and more efficient implementation would use four copies of the 4-to-1 MUX to select between the three kinds of shifts and no shift at all at each "stage" of a single barrel. Do the second.
Turn in your schematics and a timing diagram showing each one of your shifts. Use the following combinations for values for A and SHAMT for each kind of shift: 0FF0 and 4, 0FF0 and 9, F00F and 4, F00F and 9. Demonstrate your design to the TA.
Exercise 4: 16-bit Incrementer (10 points)
A useful circuit in a processor is an incrementer, an adder which can only add one variable and one fixed constant (usually, this constant is a power of two). There are two ways to implement an incrementer. The first is to use a full adder and hardwire one of the inputs. The second is to optimize the adder knowing what one of the inputs is going to be. This is the smarter way. For this exercise, you will build a 16-bit two-level carry-lookahead +1 incrementer. (Hint: Think about how the carry-lookahead circuitry could be optimized if you knew that B was always 0 and C0 was always 1.)
Turn in your schematics and a timing diagram showing an increment for each of the following inputs: 0000, 0FF0, 00FF, FF00, and FFFF. Demonstrate your design to the TA.