Wednesday, January 7, 2009


Address Decoding
As an assembly language programmer, you know that the CPU registers have no address. Instead, you specify them by name eg: A, B, C, etc.. As a result, it may seem confusing to you that to access an I/O port, you use an address, even though they may be thought of as similar to registers. CPU registers use the fastest (and most expensive) memory technology, then cache memory uses a slightly slower technology and then system RAM uses a slower and cheaper technology. Nevertheless, all are forms of memory. In fact, you could think of standard RAM as a large collection of slow registers. The difference is simply in the way that we name them.
You should also realize (especially if you have installed additional memory in your own computer) that RAM consists of multiple chips, each of which contains a number of memory locations. Each chip is physically just like every other chip. There is nothing about the chip itself that makes it hold a particular range of addresses. The locations on a single chips are linearly ordered, but there is no inherent ordering among the separate chips. The ordering comes from the way the chips are connected to the address bus. When you specify a particular address, the corresponding location exists only in one of those chips. In a very real sense, part of the address selects the correct chip (the upper part of the address), while the rest of the address selects the correct location on that chip. You can look at the low order bits as forming an offset from the first location on the chip to the correct location on the chip for the address you are specifying. The method that we use to select the correct location on the correct chip is called address decoding and we use the voltages carried on the wires of the address bus to accomplish the selection. Notice that it is critical that each address selects a unique location.
In additon to talking about memory addresses in memory space (or area), we also have an area the microprocessor treats slightly different called the port (I/O) space or area. On the 8085 CPU, we know the memory space is 64K bytes as there are 16 address lines. The port (I/O) space on the 8085 is 256 bytes as there are only 8 address lines used to select a port address. More on this later.
Each chip (whether it is a memory chip or a peripheral device chip) has an input called chip select ( ) or similar. To activate the chip, we must send a logic "0" (0 volts) to this input because it uses negative logic. If there is a logic "1" (+5 volts) on the wire connected to this input, the chip is inactive. Some chips also have an enable (EN) input. Chips of this type must receive a logic "1" on this input and a logic "0" on the input to be active. The fact that we can "turn on" (activate) or "turn off" (deactivate) a chip using signals like these allows us to select the correct chip for a particular address.
In order to see how this works in practice, we can design an address decoder for a very tiny memory, made up in part of "conventional RAM" and in part of I/O ports. You will recall from the beginning of the semester that the number of wires on the address bus determines the number of memory locations to which we have access. Conversely, the number of locations to which we need access determines the number of address lines we need. For this example, there will be sixteen 8-bit memory locations to which we want access. This means that we will need four address lines (24 = 16). Assume that we have eight memory locations in conventional memory and eight I/O ports. If we assume that each conventional memory chip contains four memory locations, we will need two chips or banks of memory. Assume the I/O ports are on eight separate chips, each with one register (in reality, peripheral devices typically have several registers each, but the concept is the same). Arbitrarily, we will say that the eight lowest addresses will be on the conventional memory chips and the eight highest addresses will correspond to the I/O ports on peripheral devices. First, we will specify all sixteen addresses in binary, so that we can see easily which address lines will have high voltage and which will have low voltage for any particular address.

The first thing we need to do is figure out how we can use the first eight patterns to activate the conventional memory chips and the second eight patterns to activate the I/O ports. We will use the EN input to enable the appropriate chips. Later, we will need to worry about the input, because both the EN and must receive appropriate inputs in order to activate a chip, but for now, we will just consider how to "enable" some of the chips. We need something that is common to all eight of the first set of patterns and that distinguishes them from the second set of eight patterns. If you look at the values of the A3 line, you can see that this line is always 0 for the first eight addresses and always 1 for the second set of eight addresses. We can use this line to provide the EN signal for both conventional memory and I/O ports (provided that the input also receives an appropriate input). Since A3 = 0 for the conventional memory addresses, we must invert it to obtain a 1 for the corresponding EN inputs. Since A3 = 1 for the I/O port addresses, we simply feed A3 directly to the EN inputs of the I/O ports.

1 comment: