Hardware Building Blocks Multiplexors and decoders We have established that we can build ANY logic circuits entirely from NAND gates or NOR gates. This is fine in theory but a pretty idiotic thing to do in practice. Gates represent the lowest level of integration available to the designer, if we go any lower we begin to think of discrete transistors. At the opposite end of the scale we have VLSI and ULSI or whatever the acronym of the day is, in which devices can have millions of transistors. It is difficult to imagine that the designers of the latest PC processors (Athlons etc) would use NAND gates in their designs it would take ages to simply draw such a circuit let alone design it! However it would be wrong to dismiss this idea until very recently, Cray supercomputers were produced entirely from very simple devices. In reality the digital designer has a bewildering armoury of high level components at his/her disposal. Take a look in the PRIMLOGI and 7400DEVS libraries in LogicWorks. These are a small step up from basic gates and 7400DEVS actually represent real chips which you can go out and buy. It is important to realise that these devices exist. It s somewhat less important to know how they all work unless you actually need to use one in a design. One or two exceptions are worth a closer look, partly because they are such a small step up from primitive gates, and also because they can sometimes behave just like gates. Multiplexors and decoders A common problem which faces the digital designer is the routing or distribution of data. Multiplexers and decoders are frequently used to achieve this. We can think of the multiplexor (or mux) as a data selector, the diagram below illustrates a four input mux. A B C D T X Y In this example, one of the inputs (A,B,C, or D) is routed to the output (T). Which input is selected is determined by X and Y, so we can represent the behaviour of this device using a truth table:
X Y T 0 0 A 0 1 B 1 0 C 1 1 D It can help to think of the multiplexor as the hardware equivalent of a look-up table which you might have encountered in software, and an interesting application is to use the mux to look-up logic functions. Look carefully at the diagram above it is a mux but drawn as a rectangle instead of a triangle (both representations are quite common) and the inputs have been hard-wired as ones and zeroes. Consider the truth table for this device: S0 S1 Q 0 0 0 0 1 1 1 0 1 1 1 0 It looks remarkably like the EX-OR truth table which we ve seen before! In fact, by wiring the inputs appropriately we can make this behave like any gate we choose. Multiplexors are available off the shelf in various sizes; 2,4,8, and 16 input devices are commonly available. Decoders Unfortunately, the term decoder is rather over used, but in the present context we can think of it as being the opposite of a mux. A data distributor rather than a data selector. The terms demultiplexor and decoder are often used interchangeably. Which term to use is usually suggested by the context. We ll begin by considering a 4 output device (usually described as a 2 to 4 decoder). As usual we ll use a truth table to describe the operation of this device.
The device has active low outputs (0 means true ) and the E input can mean either of two things: if we are talking demultiplexors then it is the data input, whereas, for a decoder, it is an Enable signal. The important part of the table is contained in the grey (or yellow!) rectangle. E S0 S1 Q0 Q1 Q2 Q3 1 X X 1 1 1 1 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 1 0 Just as muxes come in various sizes decoders do too. There is no point in a 1 to 2 decoder (draw the truth table and you will see that we could build it with a single inverter!). 2 to 4, 3 to 8, and 4 to 16 are the common variants. The diagram below illustrates a 3 to 8 decoder with active high outputs. Internally the device is quite simple, although no-one in their right mind would actually attempt to build a decoder using discrete gates it is instructive to consider how such devices might be made:
The inputs to the decoder are a 3-bit binary pattern which can have eight possible forms (000 to 111). Each of these corresponds to a single output. Another way of looking at this is to think of the outputs as logic functions: This leads naturally to using the decoder to implement more complex logic functions. Consider the following truth table: A B C T 0 0 0 0 0 0 1 1 0 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0 1 1 0 0 1 1 1 1 We could derive a Boolean expression for T, simplify it and build a circuit with NAND gates (or whatever). We could use a Karnaugh map perhaps. Or we could implement the function directly by using a decoder: One of the most common applications of decoders is in memory addressing in microcomputer systems. Suppose we have a simple microprocessor system which has a RAM chip, an EPROM chip, a parallel I/O device and a serial I/O device. In this particular example we will consider the signals which are appropriate to the 680X microprocessor families, however the problem is very similar for almost any microprocessor.
When the microprocessor puts an address on the address bus it asserts a strobe (in this case E) to indicate that the address is valid. The purpose of the address decoding is to enable the appropriate chip; typically we would use a 2-4 decoder (with active low outputs) to perform this function: In this example O 0 is asserted when A15 and A14 are both zero, which means all addresses from 0000H to 3FFFH. Similarly, O 1 is asserted when A15 is zero and A14 is one, corresponding to addresses in the range 4000H to 7FFFH, and in the same way, O 2 is asserted for addresses in the range 8000H to BFFFH, and O 3 for addresses in the range C000H to FFFFH. As we have four devices in our memory map all that we need to do is to connect the outputs from the decoder to the /CS (Chip Select) inputs of our devices and hey presto! We almost have a complete microprocessor system! Remember though, that by using the 2-4 decoder we have divided the 64K memory map into four equally sized 16K chunks. As long as our devices occupy 16K or less then this is fine, as an added bonus in this case we can also connect /E to the enable input of the decoder (G) so that our chips will only be enabled when the address is guaranteed to be valid. Suppose now that our EPROM chip is 16K and our RAM chip is 32K. We can not use the simple strategy outlined above so let's look more closely at the memory map:
This time the best solution is probably to use a 3-8 decoder which divides the memory map into 8 chunks, each of which is 8K in size. We need to allocate four of these chunks to the RAM chip, two to the EPROM and one each to the I/O devices. This is quite easily achieved using AND gates (you may have thought OR gates but remember that the logic is active low again).