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.