Von Neumann Architecture

Before we construct the CPU as the final part of our computer, let's get an overview of how each part of the computer connect and function with each other. Most modern computers use a structure called the Von Neumann Architecture invented by the famous Hungarian-American mathematician and computer scientist John Von Neumann. To get a basic understanding of the architecture, watch the following Crash Course Computer Science video below:

Computer Architecture

For our computer, we use the Von Neumann Architecture with a little twist. Instead of putting both data and instruction memory in one RAM, we separate them into two memory locations. Since our computer shouldn't meddle with the instruction memory, we store it in a read-only memory or ROM. ROM is not some new fancy storage unit that we need to construct. It is just our good old friend RAM without a writing input pin so you can't modify the values stored in the RAM. Since we need to modify the data, we store it in a regular RAM. This type of architecture which separates data and instruction memories is called the Harvard Architecture. Specifically, below is how our computer looks like:

If you look closer at the inside of the CPU, you will see three registers called A, M, and D:

A stands for Address. The A register stores the address in the RAM where we want to read or write data to.

M stands for Memory. The M register stores the value of the RAM at the address specified by the A register. This is how we read a value from the RAM. When we set the value of the A register, the M register is automatically loaded with the RAM value that A addresses to.

D stands for Data. The D register can store any 32-bit number. It's often used to save temporary result of a computation.

Peripheral Devices

Our computer is now complete. However, that's not how users or you in fact typically see and interact with a computer. When I was young, I thought that the monitor contains the whole computer. However, later on I learned that there's actually a separate host machine that connects to the monitor and controls what to display. This shows just how important peripheral devices like screen and keyboard are to the user experience of a computer. For our computer, we will target a 320px by 240px screen with 8-bit coloring. Our computer will also connect to a standard keyboard.

Screen

The way we interact with the peripheral devices is very simple. Let's look at the screen first. One way to look at the screen is to count the pixels it contains:

Our screen is a big matrix or rectangle made up of 240 rows of 320 pixels. We usually say that this kind of screen contains 320 pixels per row and 240 pixels per column. So how do we store the pixels in the memory? If you are familiar with printed media and painting, you may know that a lot of colors can be composed by mixing just three primary colors - cyan, magenta, and yellow. Colors used in print are also called subtractive colors because they absorb lights of other colors and reflect lights in their colors. Another way to think about subtractive colors is by thinking of them as semi-transparent filters that blocks lights in other colors and only allow lights in their colors to pass through.

We have a different set of primary colors for screens that emit lights instead of filtering them. They are red, green and blue, also called additive colors.

Now that we know that each pixel is represented by a mixture of red, green, and blue, let's take a look at a pixel on a real monitor:

Notice how each pixel conveniently packs one red, one green, and one blue light source together. Let's dive deeper into how the mixture of the three colors works. Play around with the color picker below and think about how might we store a color as a number in the compute.

Notice that each color has an intensity value from 0 to 255. 0 means no color and 255 means full color. Each color has 256 possible intensity levels. If we combine red, green, and blue, we got256 * 256 * 256 = 16777216 possible colors represented. That's a lot of colors! Let's see how we can store these wonderful colors in the memory:

As you can see, it's very straight forward. Each color accounts for 8 bits and we string three 8 bits together to form a 24 bit binary number. This is how most computers store a color but our machine has less memory available so we are gonna compress these 24 bits into 8 bits. Again, play with the 8-bit color picker first and think about how we can store an 8-bit color in the memory:

Hopefully you noticed that the red and green color now ranges from 0 to 7 while the blue color ranges from 0 to 3.

You might notice immediately that the bits for red, green, and blue are imbalanced. Red and Green are given 3 bits each but blue only has 2 bits. This is because 8 deosn't divides evenly into 3 so one of the colors has to have 1 bit fewer than the others. Even though the computer will happily accept a color encoded in this way, this representation is problametic because we have fewer intensity options for blue. That means we get more colors tinted with red and green than colors tinted with blue. A simple way to restore the balance is to treat an 8-bit color as a palette instead of splitting the bits between the three colors:

Since there are only 256 possible colors, we just hardcode each one of them to a number from 0 to 255. Try the new palette color picker to get a feel:

Since our computer is 32 bit, all registers in the RAM are 32 bit. Because one colored pixel takes up 8 bit, we can put 4 pixels in one register.

Since the screen is 320px by 240px, we have 320 * 240 = 76800 pixels to store. Because each register can store 4 pixels, we need 76800 / 4 = 19200 registers in our RAM to store all pixels in our screen. This section of the RAM is called the screen memory map because the pixel data stored in the registers directly map to the pixels displayed on the screen. If we want to change the color of any pixel on the screen, all we need to do is to change the value of it in the screen memory map.

Keyboard

The keyboard also works like this. We have a keyboard memory map is connected to the physical keyboard and listens to any key presses. The only difference though is that we can't write to the keyboard memory map like we do to the screen memory map because keyboard is strictly a one-way user input device. It doesn't make sense to "output" a key press from the computer. You don't need to worry about how each key maps to a number to store in the computer because there's already a standard agreed by most computers out there. Try pressing any key below and find out its name and key code (You need to click on the blank area to get focus first before pressing any keys):

Memory Layout

Now if we review the architecture of our computer specified earlier:

We said earlier that we will figure out the CPU later and we just finished specifying the screen and keyboard memory map. The only parts left are the ROM and the RAM. We already made a bunch of RAMs of different sizes in the previous chapter so now we need to figure out how much RAM do we need. For the data memory, we decided when designing this course to be 2 ^ 16 = 65536 registers. We know that the screen memory map takes up 19200 registers and the keyboard memory map takes up 1 register. All together our RAM looks like:

Memory addresses from 0 to 65535 are the data memory. Memory addresses from 65536 to 84736 are the screen memory map. Because 65536 is location of the first register mapped to the screen, we call it the base address of the screen memory map. Memory address 84737 is the last location of our RAM and refers to the keyboard memory map. Because 84737 is location of the first (in this case only) register mapped to the keyboard, we call it the base address of the keyboard memory map. Remember that each address points to one 32-bit register so our RAM occupies 2711616 bits or 2711616 / 8 / 1000 = 338.952 kilobytes.

For the ROM, we just designed it to be 2 ^ 16 = 65536 registers so in total 2097152 bits or 2097152 / 8 / 1000 = 262.144 kilobytes:

Key Code Mapping

We also include the full list of key code mappings for your reference. By no means you need to memorize any of them.

Last updated