Computer Organization: ISA Design

Collaborative ISA Design Project


Architectural-syle proposal due: Monday, November 11

Instruction sets and example code due: Thursday, November 21

In-class demonstrations: Thursday, December 5

Final project due: Tuesday, December 10


Goal

To work as a team to design and simulate a simple instruction-set architecture.


What you need to do

  1. read this document in its entirety
  2. work with your assigned partners to design the relevant instruction set in terms of both an assembly language and machine code
  3. work with your partners to implement your architecture in circuit-simulation software
  4. thoroughly document your architecture
  5. as a group, demonstrate your architecture and simulation to the rest of the class.
  6. submit documentation and circuit-design files via email

Details

Your task is to design a simple architecture both in terms of the instruction set and circuit schematic. You should be able to simulate the circuit using JLS. You will need to submit a well-documented schematic design and well-written description of the instruction-set architecture including at least two sample programs (presented in both your assembly language and machine code).

All four architectures are 16-bit meaning that buses and memory addresses are 16-bit. Memory (data memory for those architectures where there is a distinction from instruction memory) should be byte-addressable, and instruction length will depend on the architecture and possibly the specific instruction (see below).

You may or may not need a variety of internal registers to facilitate processing instructions and implementing control.

You should use subcircuits wherever possible to keep the design hierarchical and the schematics relatively easy to follow. Any given level of your circuit should fit in within a 1200x800 JLS window.

–> include text within your subcircuits when it will provide clarity. (for instance, if you have a subcircuit representing how control lines are determined, add text reminding the viewer the role of each control line)

Your architecture needs to be robust enough to compute the equivalent of these two examples expressed in C-like pseudocode:

    /* assume n is some input */
    x = 0;
    while (n > 1) {
        if (n is even) {
            n = n / 2;
        }
        else {
            n = 3*n + 1;
        }
        x++;
    }


   /* assume a is an array of integers of length n */
   i = 0;
   for (i = 0; i < n; i++) {
       a[i] = a[i] + 1;
   }

These fragments demonstrate arithmetic and logic operations, conditionals, loops, and memory access.

You should have at one other example ready to demonstrate by the time of your in-class presentation.

You should not implement multiplication or division.

Whether you provide explicit support for procedures (e.g., jal and jr in MIPS), will depend on the architecture you choose and the design decisions you make.

You can use any of the premade circuits provided by JLS. (However, if you think your approach is not what I had in mind, check with me early on in the process.) You


Details about the four architectural styles

  1. Multicycle Mini-MIPS (MMM): a load-store, RISC architecture. Most unique feature: multicycle meaning that some (likely all!) instructions take more than one clock cycle to fully execute. The advantage of such a system is that the critical path length through the CPU can be shortened (and, therefore, so can the clock cycle time); this means that otherwise shorter instructions do not need to “wait” the way they would in a single-cycle implementation. Furthermore, some components of the CPU can be reused in different cycles for different purposes which provides opportunities for making the CPU hardware simpler; on the other hand, extra hardware is required to implement the multicycle behavior: in particular at least one state element (i.e., a register) to remember which stage of an instruction is currently being executed plus the combinational logic to determine whether an instruction is complete or whether to move to the next stage. (Those two parts of the CPU form a finite state machine.)

    Your CPU must work with a single memory (rather than having separate instruction and data memories).

  2. Accumulator. The accumulator is the one general-purpose register for the machine. An eight-bit example instruction format might be a three-bit opcode plus a five-bit immediate for instructions like this:

        000XXXXX    CLEAR        A = 0
        001IIIII    ADD ...      A += I
        010IIIII    STORE ...    M[I] = A
        011IIIII    LOADA ...    A += M[I]
        100IIIII    BEQ ...      if A==0 then PC += I

    where the PC is always incremented by 1. For load and store, the immediate is an absolute address in RAM; for add and branch it is in two’s complement, sign extended. Here is an example that sums the first five numbers (optimized in a few places where we know that the accumulator will be 0):

    instr addr    assembly     machine     comment
    ----------------------------------------------
     0             CLEAR       000
     1             ADD 5       001 00101
     2             STORE n     010 00100   n = 5  (n's address is 4)
     3             CLEAR       000
     4             STORE s     010 00101   s = 0  (s's address is 0)
    
     5       loop: CLEAR       000
     6             LOADA n     011 00100
     7             BEQ end     100 01000   skip to end (+8) if n = 0
     8             LOADA s     011 00101
     9             STORE s     010 00101   s += n
    10             CLEAR       000
    11             LOADA n     011 00100
    12             ADD -1      001 11111
    13             STORE n     010 00100   n--
    14             CLEAR       000
    15             BEQ loop    100 10101   jump to loop (-11)
    16      end:   LOADA s     011 00101

    If you choose this project, you should aim to have variable-length instructions: some are eight-bit, some are 16-bit - the latter are any instructions that refers to a memory address. It might also be useful to have a special-purpose register called a condition register that keeps track of the last comparison.

  3. Stack.

    The stack should be its own module.There are several ways you might design the stack interface. One idea is to have two 16-bit outputs - the top two elements of the stack (which may or may not be well defined depending on how many things are on the stack at the time); a 16-bit input; a one-bit push enable - to indicate the 16-bit input is being pushed onto the stack; a two-bit pop enable to indicate whether zero, one, or two items are being removed from the stack. But you can design this is as you see fit.

    Like the accumulator style, it might be worth having variable length instructions: some are eight bit, some are sixteen bit - the latter are those few instructions that refers to a memory address, namely push and pop.

    Here is example code to compute the absolute value of a number stored in memory address X and to place it in address Y might look like:

         pushi 0   # push 0 onto stack
         push  X   # push mem[X] on stack
         slt       # replace top two elements of stack with result mem[X]<0
                   #  that is stack now has one element on it:
                   #    which is 1 if mem[X] < 0
                   #             0 otherwise
         bz    L   # if top item is 0 (meaning mem[X] >= 0), branch to L
                   # (and pop item off)
         push  X   # push mem[X] on stack
         pushi 0   # push 0 onto stack
         subtract  # replace top two items with 0 - mem[X]
         jump  L2  # jump to L2
    L:   push  X   # push mem[X] on stack
    L2:  pop   Y   # mem[Y] = top of stack
  4. mini-ARM. ARM (as we will learn) is a family of RISC architectures that has much in common with MIPS. ARM CPUs, thanks to mobile devices, are now the most common in the world. If you choose this project, you will be simulating an ARM-like architecture, but it should by no means attempt to implement all of ARM’s features. Your implementation should be fully single cycle - each instruction will take exactly one clock cycle; so, as we did for everything but the MMM above, you will need to have separate instruction and data memories. You will have a register file (you can choose how many registers to have but at least 4 and no more than 16 and certainly a power of 2!). Instructions will, like for MMM, be uniformly 16 bit. There are some special features you must implement:


Extra credit

This assignment is plenty challenging enough so there is no official “extra credit”. That said, the assignment is fairly open ended. Your design can be made more streamlined, cleaner, better documented. And you can add features. If you really want to add fancy features (for example, a cache; or implementing an assembler), discuss me with me first.