CS 220 - Final Project
Due 9am December 17, 2001
This project asks you to revisit the levels of architecture you have explored
this semester, with special attention to either the Instruction Set Architecture
level or the Digital Logic level (your choice). So you should
complete either Part I (individually, with no collaboration) or
Part II (as a team, with full collaboration) to complete this project.
Part I
Labs 7 and 8 are particularly useful here, along with the related sections
of Chapter 5 and the on-line manual describing the
full JVM instruction set
,. You may refer to this manual as a JVM supplement to your text while
you are completing this project.
Integer division and remainder instructions in the JVM are called IDIV and
IREM, respectively. For example, if we have pushed a =145 and b = 11
onto the stack, then issuing IDIV will leave their integer quotient (13)
on the stack. If we issue IREM instead, their integer remainder (2)
will be left on the stack.
The quotient q = a/b can be computed by counting the number of times b
can be subtracted from a, assuming b is nonnegative. (If b is negative,
then complementing both a and b allows us to use the same algorithm.)
In this case, the remainder is simply the integer left over after the last
subtraction is performed. Here is an algorithm that models the IDIV
instruction, assuming that a, b, and q are 32-bit positive binary integers.
q = a;
a = 0;
for (int i=0; i<32; i++)
{ shift a and q left 1 bit,
moving the leftmost bit of q into the
rightmost bit of a
while (a >= b)
{ subtract b from a
add 1 to q
}
}
Here is an example:
let a = 145 = 0...010010001
and b = 11 = 0...000001011
Here is the initial configuration, given by the first two lines of the
algorithm:
a
q
b
0...000000000 0...010010001
0...000001011
Notice that the while loop doesn't execute until a becomes >= b, leaving
a series of zero shifts from q into a until we reach the following configuration:
a
q
b
0...000010010 00100000...00
0...000001011
Now we can subtract b from a as long as a>=b, and keep count of our
subtractions in q. Only one subtraction is possible in this case, leaving
the following configuration:
a
q
b
0...000000111 00100000...01
0...000001011
The next opportunity to do subtraction like this comes after the next shift,
which leaves the first line shown below. Subsequent subtractions and
shifts after that are given on the succeeding lines below:
a
q
b
0...000001110 0100000...010
0...000001011
0...000000011 0100000...011
subtract and increment
0...000000110 100000...0110
shift
0...000001101 00000...01100
shift
0...000000010 00000...01101
subtract and increment
When the algorithm completes, the quotient (13) is in the q register and
the remainder (2) is in a.
Hand in:
1. Implement IDIV in Mic-1 microcode. It should assume the same
operands on the stack as does IADD, and should replace them by their 32-bit
quotient as the top word on the stack when it is done. Test your implementation
using a similar strategy to the one you used for IMUL.
For details on the syntax of the Mic-1 microprogramming assembly language,
see the on-line Micro-Assembly Language (MAL) Specification
. To implement a new microprogram, you need to add it to all the microprograms
for the other IJVM instructions that are in the file
mic1ijvm.mal
in the Mic-1 folder, and then reassemble that file using the assembler
mic1asm. To assemble a test IJVM program that contains the
IDIV instruction, you need to alter the file
ijvm.conf
in the ijvmasm folder so that this instruction and its hex
opcode are added to the others already in that file.
2. a. Division, as well as addition and multiplication, of
32-bit 2s complement integers can cause overflow. How do you define
overflow when a division takes place?
b. What other exceptional event(s) can occur when dividing two arbitrary
32-bit integers, and how can they be detected?
c. Can the "while" in the above sketch of an integer division algorithm
be replaced by an "if" without changing the effectiveness of the algorithm?
Explain.
3. a. What impact would the presence of IDIV in the IJVM instruction
set have on your implementation of the IOUT instruction in lab 8.
b. Show how IOUT can be implemented using IDIV.
4. The conversion of an expression to Polish notation is a simple
algorithm, as discussed in Chapter 5. It is also an essential part of
a compiler, which takes Java expressions like
x = a * ( b + (c -d^2 * e)) / 2
and convert them to reverse Polish notation. With these types of
expressions, ^ has highest precedence and = has lowest, compared with that
of +, -, *, and /. That is, the operators in the above expression are
evaluated in the following order: ^ * - + * / =
a. Discuss how the algorithm on page 340 of your text could be modified
to accommodate expressions with = and ^ operators, along with the others
already given. Assume that the operator = has lower precedence than
any of the others, and ^, meaning exponentiation, has highest precedence.
b. With this new algorithm, show how the Polish expression is developed
for the above statement.
c. Discuss the implementation of the algorithm on page 340 of your
text in IJVM assembly language. That is, assuming that expressions like
the one above are typed by the user into the Mic-1 simulator, what is needed
to design an IJVM program that displays it in reverse Polish notation?
Part II
This part revisits Lab 5
, which is on the Web site and the accompanying documents
Design of a Complete CPU and Memory System
and Fetch/Execute Cycles for the MINIJVM
Instruction Set
. A partially-correct CPU design is provided as a circuit in
the CS220 (Tucker) server, along with a device library containing
an Instruction Decoder and an ALU, thanks to your team work in earlier labs.
The goal of this part is to complete this design so that it correctly executes
all instructions in the sample program that appears at the end of
the document Design
of a Complete CPU and Memory System
(and which is preloaded into the memory of the CPU design. Reaching
this goal means that we have a working logic design of a complete CPU...
a very impressive accomplishment.
Attached to this document is a printout of the timing diagram for
the fetch/execute cycles when they are run on this particular CPU. As
you can see, the CPU is not quite working correctly, due to a number of issues:
1. The Fetch/execute cycles are pretty clean overall, but there are
a couple of minor bugs remaining.
2. The D bus, and later the B and C buses, contain the 8-bit hex number
10, which is the Op Code of the first instruction in memory of the sample
program. Thus, memory read is working okay, and so is the transfer
of data in and out of the registers.
3. The ALU probably needs to be revisited to be sure that it is correct
for all switch settings. I worry especially about N and Z, which don't
seem to be giving anything coherent in the timing diagram.
4. As we discovered later, the N and Z switches need to be attached
to a D-flip flop in order to save their settings for the next clock cycle.
That is, the results of an ALU operation can't be tested in the same
clock cycle in which they are generated. Along with this, we need to
review the fetch-execute cycles to be sure that they're not testing these
results until the next clock cycle.
So the following steps are needed to complete this project:
1. Divide the above problems among team members, to be solved individually
in the first four days.
2. Individually test the revised ALU before re-attaching it to the
CPU design.
3. Individually test the revised Instruction Decoder before reattaching
it to the CPU design.
4. Rerun the revised CPU design to get a revised timing diagram
for each MINIJVM instruction.
5. When all of this checks out, attach the Op register in place of
the hex keyboards in the CPU design, and attach hex displays on the PC, Op,
and other registers so that it looks like a primitive Mic-1. This should
be saved as the LogicWorks file CPU testbench. Those displays
will help you view the action while you single-step the clock through the
program that is in the memory.
6. Now single step the CPU as it runs the sample program and
check each step against what you expect to happen (knowing the fetch/execute
cycles and the details of the program itself).
I will be available to assist you with any of these tasks, as needed.
Hand in:
1. Your revised CPU design, revised device library, and
revised timing diagram that result from completing steps 1-4 above.
2. Your CPU testbench that you used in steps 5 and 6 above.
3. A brief document describing the results of this work, no matter
how complete it is by the due date. This document should identify which
team member(s) completed each task, as well as any comments you'd like to
make about any specific or general aspects of this project that might be
helpful in the future.