22C:18, Lecture 5, Fall 1996

Douglas W. Jones
University of Iowa Department of Computer Science

Computer Architecture

In their seminal paper of 1946, Berks, Goldstein and Von Neumann proposed the following basic structure for a computer (ignoring the problem of input and output):

       _____           ________
      |     |         |        |
      | CPU |=========| Memory |
      |_____|         |________|
         
It is worth noting that modern computers have several types of memory; here, we are talking about the main memory of the system, used to store the program that is currently running and the data it is currently manipulating. Because much early development of computer architecture was done in Britan, it is worth keeping in mind that the British refer to memory as the computer's store, speaking of the main store and various secondary stores.

The CPU is the central processing unit of the computer. Most modern computer systems contain various other processors, sometimes referred to as peripheral processors or auxiliary processors. Some of these may actually be full-scale processors that could be used as central processors in their own right, and others are special purpose systems dedicated to single functions.

Main Memory

The memory is essentially passive, an array of storage locations or words. In the Hawk computer, each of these locations holds 32 bits and may be subdivided into 4 bytes or 2 halfwords.

In the original Von Neumann architecture, as it is usually described, the CPU may read values from or write values in any memory location; it is called a random-access memory (RAM) because reading and writing may be to any location, without regard to the history of what was accessed previously.

In modern computers, some parts of memory are typically read-only, so the CPU may not write values to those parts of the memory. In the version of the Hawk computer we will be using, locations 000000 through 00FFFF (hexadecimal) are read-only memory (ROM), while locations 010000 through 01FFFF are read-write (RAM). The Hawk architecture allows for 4 gigabytes of memory, but we only have 64K each of ROM and RAM. Attempts to access locations 020000 and up are considered to be in error.

The CPU

In the Von Neumann model of computer architecture, the CPU reads instructions from computer programs stored in memory, and following those instructions, reads variables from memory, operates on them, and stores results in memory. To do this, every Von Neumann CPU includes at least two special storage locations, called registers.

The program counter holds the address of the next instruction that the CPU should read from memory. After reading each instruction from memory, the CPU increments the program counter. The accumulator holds data that is being operated on. In the original Von Neumann machine, there was only one accumulator; modern computers typically have many. Typical CPU designs include a third register, the instruction register, used to hold the most recent instruction fetched from memory.

A simplified view of a computer very similar to that proposed by Berks Goldstein and Von Neumann can be described algorithmically as follows:

	main memory
	    m[4096]: an array of 4096 words, 40 bits each

	procedure cpu;
	    variables
		pc: the program counter, 13 bits
		ir: the instruction register, 20 bits
		ac: the accumulator, 40 bits
            code
		repeat
		    -- fetch the next instruction
		    if odd(pc)
		      then ir = bottom 20 bits of m[pc/2]
		      else ir = top 20 bits of m[pc/2]
		    pc = pc + 1;

		    -- fetch the next instruction
		    select based on the top 4 bits of ir:

		    0000: -- load
			ac = m[bottom 12 bits of ir]

		    0001: -- store
			m[bottom 12 bits of ir] = ac
     
		    0010: -- add
			ac = ac + m[bottom 12 bits of ir]

		    0011: -- sub
			ac = ac - m[bottom 12 bits of ir]

		    -- many instructions omitted

		    1000: -- jump high
			pc = (bottom 12 bits of ir)*2

		    1001: -- jump low
			pc = (bottom 12 bits of ir)*2 + 1

		    1010: -- jump high if zero
			if ac = 0
			  pc = (bottom 12 bits of ir)*2

		    1011: -- jump low if zero
			if ac = 0
			  pc = (bottom 12 bits of ir)*2 + 1
		end loop
	    end of cpu
One of the most awkward features of Von Neumann's design was the need for two sets of jump instructions, one used for jumping to even halfwords and one for jumping to odd halfwords. In modern architectures, there are three typical ways of avoiding this problem. Either all instructions are made one word long, jumps to odd halfwords are forbidden, requiring that unused halfwords be filled with instructions that do nothing, or the least significant bits of each memory addresses are used to indicate halfword and sometimes byte addresses.

When comparing the original Von Neumann architecture with moden architectures, it is obvious that many things have changed. The first few computers built in the late 1940's at universities and research laboratories did use 40 bit words, but IBM switched to a 36 bit word in 1951, with the IBM 701 computer, and introduced the 32 bit word in 1965, with the IBM System 360. CDC built sold the first commercial computer with a 12 bit word in 1960, Computer Control Corporation (later part of Honeywell) introduced the 16 bit word in 1964, and there have been machines with 24, 48, 60 and 64 bit words.

In addition, there have been machines with no clearly defined word size, where memory was viewed simply as a string of 6 bit bytes (the IBM 1401, from the 1960's, for example) or as a string of 8 bit bytes (the Intel 8008 and 8080, for example).

Nonetheless, all of the successful computer designs developed over the past half-century have been based on the Von Neumann model, in the sense that all have a fetch-execute cycle, with a program counter, and an instruction register. Furthermore, most computers have registers in the central processor that are equivalent to the accumulator of the Von Neumann design. Many machines with only one accumulator have been successful, including the earliest Intel microprocessors. Most machines built today, however, have multiple registers in the CPU, either general purpose registers, an idea that was first introduced by IBM with the System 360, or various special purpose registers, an idea that evolved through the 1950's and is still with us in in the Intel 80x86 family.

The Hawk CPU

The Hawk CPU is more complex than Von Neumann's original proposal, but it contains all of the same elements. Here is a display of the state of a Hawk CPU, using the output of the Hawk Emulator:

   PC:  00000000                R8: 00000000
   PSW: 00000000  R1: 00000000  R9: 00000000
   NZVC: 0 0 0 0  R2: 00000000  RA: 00000000
                  R3: 00000000  RB: 00000000
                  R4: 00000000  RC: 00000000
                  R5: 00000000  RD: 00000000
                  R6: 00000000  RE: 00000000
                  R7: 00000000  RF: 00000000
The CPU includes a program counter, PC, and instead of a single accumulator, it has an array of 15 so called general purpose registers named R1 through RF (in hexadecimal) or R1 through R15 (in decimal). In our emulator, the contents of these registers are always displayed in hexadecimal.

One register that was not included in Von Neumann's original proposal is the processor status word, or PSW. The most common use made of the PSW is based on the 4 least significant bits, labeled N, Z, V and C; these bits are picked out of the PSW and displayed separately by our emulator.

Considerably more detail on the structure of the HAWK CPU is contained in The Hawk computer architecture overview. Pay particular attention to the section on the CPU and to the section on the are broken into halfwords and bytes, and to the instruction execution cycle.

In looking at the Hawk instruction execution cycle, note that the cycle is has great similarities to the original Von Neumann instruction execution cycle, but that the instruction register has a far more complex structure because of the multiple registers. Nonetheless, the Hawk includes load and store instructions, arithmetic instructions and branch instructions that are quite analogous to the instructions in Von Neumann's original proposal.

In the Hawk, each memory address has two bits at the bottom end that are used only in byte and halfword addressing. This allows jumps to arbitrary instructions in memory with instructions that fill 16 bit halfwords.