CS 201: Gates and Circuits

Gates and circuits I.

Summary:

However, each of the following sets is also a complete basis for the Boolean functions: {AND, NOT}, {OR, NOT}, {NAND}, {NOR}. We left open the question of whether {AND, OR} or {XOR, NOT} is a complete Boolean basis.

Please also see the notes: Gates and circuits and Boolean bases.

We looked at a circuit for the key/door/seatbelt alarm signal, derived from the Boolean expression a ≡ $k * (d' + b')$. Recall that this computes an alarm signal ($a$) as a function of sensor values for the key in the ignition ($k$), the door closed ($d$), and the seatbelt fastened ($b$). Drawings of the symbols for six types of gates and for the alarm circuit are in: Gates and circuits

In the alarm circuit, there are 4 gates (two NOT gates, one AND gate, and one OR gate.) We model the time for this circuit to compute its output as follows. Each gate takes some small but non-zero time to get the correct answer on its output wire after its inputs are changed, its delay. In reality, different gates will have different delays, but for our purposes we assume that each gate takes the same time, a unit we call 1 gate delay. If at a given time $t$ the inputs $k, d, b$ are correct and stable, then after 1 gate delay, the outputs of the two NOT gates will be correct and stable, (namely, $d'$ and $b'$.) Note that the two NOT gates operate in parallel -- neither has to wait for the other's output. After another 1 gate delay, the output of the OR gate is correct and stable (namely, $(d' + b')$). Note that we cannot assume that the inputs to the OR gate are correct and stable until the NOT gates have produced correct outputs. Finally, after 1 more gate delay, the output of the AND gate is correct and stable (namely, $k*(d' + b')$.) Thus, the delay for the whole circuit is $1+1+1 = 3$ gate delays. This is also the number of gates in the longest path of wires and gates from an input wire to an output wire, the depth of the circuit.

Because any Boolean function can be expressed using AND, OR and NOT, we know we can build a circuit to compute any Boolean function using just AND, OR and NOT gates. However, we note that

$$(x + y) \equiv (x' * y')'$$

that is, OR can be expressed using just AND and NOT. (This equivalence can be checked using a truth table, or by applying one of DeMorgan's laws and the law of double negation:

$$(x' * y')' \equiv (x')' + (y')' \equiv x + y$$

Thus, everywhere we have an OR gate, we can substitute a small circuit of 3 NOT gates and an AND gate. That is, we can build a circuit for any Boolean function using just AND and NOT gates; the set of gate types {AND, NOT} is a complete Boolean basis. By duality, we could replace every AND gate using 3 NOT gates and an OR gate using the dual equivalence:

$$(x * y) \equiv (x' + y')'$$

Thus, the set of gate types {OR, NOT} is a complete Boolean basis. In fact, if we consider the NAND gate, which computes the NOT-AND function

$$(x \rm{NAND} y) \equiv (x * y)'$$

then we can build a circuit for any Boolean function just using NAND gates. The truth table for NAND is as follows.

    x  y  |  (x NAND y)
   --------------------
    0  0  |      1
    0  1  |      1
    1  0  |      1
    1  1  |      0

Because (x NAND x) ≡ x', we can use a single NAND gate both of whose inputs are x as a replacement for a NOT gate. And because $(x NAND y)' \equiv ((x * y)')' \equiv (x * y)$, we can use a pair of NAND gates to replace each AND gate in a circuit. Because we previously showed that {AND, NOT} is a complete Boolean basis, we conclude that {NAND} is a complete Boolean basis. Dually, we consider the NOR function: (x NOR y) ≡ (x + y)' and can similarly show that {NOR} is a complete Boolean basis. (As a footnote: The Wikipedia article on logical NOR claims that "The computer used in the spacecraft that first carried humans to the moon, the Apollo Guidance Computer, was constructed entirely using NOR gates with three inputs.")

We left open the questions of whether {AND, OR} or {XOR, NOT} might be a complete Boolean basis.

Gates and circuits II.

Summary: - A combinational circuit to compare two 4-bit numbers -- output 1 if they are equal and 0 if they are unequal. - Comparing the time taken by different organizations of the tree of AND gates combining the results for individual bits. - A combinational circuit to add two 4-bit binary numbers, getting a 5-bit result: a half-adder, a full-adder, and combining them into a ripple-carry adder. - The time taken by the ripple-carry adder, and the distinction between linear time (BAD) and logarithmic time (GOOD) time for circuits.

Please see the notes: Equality circuit and Addition circuit.

In this lecture we consider two combinational circuits, one to compare two 4-bit numbers for equality, and one to add two 4-bit numbers to get a 5-bit sum. In a computer, combinational circuits perform basic operations like adding, subtracting, multiplying or dividing numbers, comparing numbers and other quantities, performing shifts and logical operations, and the like. The other important type of circuit, sequential circuits, are used to implement memory, storing values before and after they are operated on. The next lecture will consider sequential circuits.

To construct a circuit to compare two 4-bit quantities, $x1, x2, x3, x4$ and $y1, y2, y3, y4 $for equality, we first consider a circuit to compare two single bits for equality. The input is two bits, $x$ and $y$, and the output is one bit $z$, where $z = 1$ if and only if $x = y$. A truth table for this Boolean function is as follows.

    x  y  |  z
   ------------
    0  0  |  1
    0  1  |  0
    1  0  |  0
    1  1  |  1

We could use the sum-of-products algorithm to write an expression for $z$, namely, $z = x'*y' + x*y$. We could also observe that the function in this table is just the negation of the XOR of $x$ and $y$, because

    x  y  |  (x XOR y)  (x XOR y)'
   -------------------------------
    0  0  |      0          1
    0  1  |      1          0
    1  0  |      1          0
    1  1  |      0          1

Thus, we can also write $z = (x XOR y)'$. These two expressions lead to two different circuits for the given Boolean function. Using the expression $z = x'*y' + x*y$, we get a circuit with two NOT gates, two AND gates and an OR gate, with a gate delay of 3 in the longest path. Using the expression $z = (x XOR y)'$, we get a circuit with one XOR gate and one NOT gate, and a gate delay of 2 in the longest path. Of course, the second circuit assumes that gates computing the XOR operation are available.

Once we have a circuit available for computing whether two bits are equal, we draw a rectangle around it, and give it a label, say $EQ$, and use it as a subcircuit in our further circuit design. This kind of abstraction, like writing auxiliary procedures in Racket, helps to keep us from being overwhelmed in details as our designs get more complex.

Given the design of $EQ$, we use four copies of it and three AND gates to compare two 4-bit numbers, a number $x$ represented by inputs $x1, x2, x3$, and $x4$, and a number $y$ represented by inputs $y1, y2, y3, y4$, and produces an output $z$, where $z = 1$ if and only if $x1 = y1$ and $x2 = y2$ and $x3 = y3$ and $x4 = y4$, that is, the two 4-bit numbers $x$ and $y$ are equal. Please see the notes: Equality circuit

A circuit for 4-bit binary addition. Please see the notes: Addition circuit.

Gates and circuits III. How to build a computer memory

Summary:

  • Using a selector to choose one of two inputs to be an output. (Read one bit of Memory)
  • Sequential circuits:
    • a NOT gate whose input is its output wire can function as a clock
    • an OR gate one of whose inputs is its output wire and its analysis
    • the NAND latch and the analysis of its stable states. (Store one bit of memory)

    Please also see the diagrams: NAND latch and D flipflop.

  • Previously we saw the design of a circuit to add two 4-bit numbers to produce a 5-bit sum. We could also design a circuit to subtract two 4-bit numbers to produce a 5-bit difference. (Exactly what that means will become clearer when we talk about number systems for computers.) Suppose we want to choose between the sum and difference of two 4-bit numbers based on a Boolean value $s$. That is, we want a circuit with inputs $x3, x2, x1, x0$ (representing a binary number) and $y3, y2, y1, y0$ (representing a binary number) and $s$ (to choose between sum and difference), and outputs $z4, z3, z2, z1, z0$ where if $s = 1$, then $z4, z3, z2, z1, z0$ is the sum of the two input numbers, and if $s = 0$, then $z4, z3, z2, z1, z0$ is the difference of the two input numbers. In a programming language this is just an if statement, for example, in Racket we would have something like (if (= s 1) (add x y) (subtract x y)). In hardware, we have a different solution: compute both the sum and difference, in separate circuits, in parallel, and then use s to select which values will appear on the output wires $z4, z3, z2, z1, z0$.

    We can think about this one bit at a time. A 1-bit selector circuit has inputs $s$, $x$, and $y$, and one output $z$, where $z$ is equal to $x$ if $s = 0$ and $z$ is equal to $y$ if $s = 1$. If we construct a truth table for this Boolean function, we get the following.

       s  x  y  |  sel(s,x,y)
       ----------------------
       0  0  0  |    0
       0  0  1  |    0
       0  1  0  |    1
       0  1  1  |    1
       1  0  0  |    0
       1  0  1  |    1
       1  1  0  |    0
       1  1  1  |    1
    

    Note that in the top half of the table (where $s = 0$), the output just copies $x$, and in the bottom half of the table (where $s = 1$), the output just copies $y$. We could write out an expression with four terms using the sum of products algorithm, but there is a simpler equivalent expression, namely

    $$z = (s' * x) + (s * y)$$

    This can be verified by constructing the truth table for this expression, or by noting that when $s = 0, s' = 1$, so we have $z = (1 * x) + (0 * y)$, which simplifies to $z = x$, and when $s = 1$, $s' = 0,$ so we have $z = (0 * x) + (1 * y)$, which simplifies to $z = y$. A circuit based on this expression takes time 3 gate delays.

    This one-bit selector can be generalized to any number of bits. That is, if we have a selector input s and two n-bit inputs $a1, a2, ..., an$, and $b1, b2, ..., bn$, and an n-bit output $c1, c2, ..., cn$, we can arrange that if $s = 0$ then $c1 = a1, c2 = a2, ..., cn = an$ and if $s = 1$ then $c1 = b1, c2 = b2, ..., cn = bn$, by using n one-bit selectors with the same s input. The first one-bit selector has $a1$ and $b1$ as its other inputs, and $c1$ as its output. The second one-bit selector has $a2$ and $b2$ as its other inputs, and $c2$ as its output, and so on. Each of these one-bit selectors operates in parallel with the others, so after just 3 gate delays the n-bit output $c1, c2, ..., cn$ is available. Thus, with a 5-bit selector we can solve our original problem of selecting the sum or difference of two 4-bit inputs.

    Sequential circuits.

    Up to now we have considered only combinational circuits, which have no loops of wires and gates. In a combinational circuit, the eventual final outputs of the circuit are completely determined by the values of the circuit inputs. However, the outputs of a sequential circuit may depend on both the inputs and the past values of the wires of the circuit. We'll consider several examples of sequential circuits. The first is a single NOT gate whose input is its own output, indicated in the following diagram.

    
    
        ---|NOT>---*----- z
        |          |
        ------------
    
    

    Here the wire $z$ is both the output of the NOT gate and its input. We examine the behavior of this circuit assuming that $z$ is initially $0$. This is the input to the NOT gate, which one gate delay later outputs $z = 1$. After one further gate delay later, the output of the NOT gate is $z = 0$. Thus, the value of $z$ alternates between $0$ and $1$ at intervals of one gate delay, indefinitely. Graphing the value of $z$ as a function of time (measured in gate delays):

    
      1      ====    ====    ====    ====   
    
      0  ====    ====    ====    ====
         0   1   2   3   4   5   6   7
    
    

    The output value of this circuit never stabilizes, but nonetheless, it could be useful as a clock marking off time in units of one gate delay.

    Another sequential circuit ("Garden of Eden").

    We now consider a sequential circuit consisting of an OR gate whose output is fed back as one of the inputs to the OR gate. A picture of this situation follows.

    
       x ----|
             |OR>----+---- z
          ---|       |
          |          |
          ------------           
    
    
    This is an OR gate with inputs $x$ and $z$ and output $z$. Some assignments of values to the wires $x$ and $z$ are stable in the sense that they are not different after one gate delay. To find these values, we consider the equation:
        z = x OR z
    

    This has three solutions:

        x = 0 and z = 0
        x = 1 and z = 1
        x = 0 and z = 1
    
    The combination $x = 1$ and $z = 0$ is not stable, because after one gate delay we have $x = 1$ and $z = 1$. If we consider the three solutions as states of the circuit, and see how changes in the input $x$ can transition from one state to another, we have the following diagram.
    (x = 0, z = 0) ------->  (x = 1, z = 1) -------> (x = 0, z = 1)
                    x = 1          ^         x = 0         |
                                   |                       |
                                   -------------------------
                                             x = 1
    

    We see that the state $x = 0$ and $z = 0$ is a so-called "Garden of Eden" state, because once we leave it (by setting the input $x$ to $1$), we cannot re-enter it. From the state $x = 1$ and $z = 1$ we can reach the state $x = 0$ and $z = 1$ by setting the input $x$ to $0$, and from the state $x = 0$ and $z = 1$ we can reach the state $x = 1$ and $z = 1$ by setting $x$ to $1$, but the fact that $z = 1$ in both states means that $z$ will continue to be $1$. This circuit exhibits a kind of memory, recording whether the input $x$ has ever been set to $1$.

    The NAND latch.

    Please also see the diagrams: NAND latch and D flipflop. The third kind of sequential circuit that we consider provides a more useful kind of memory. It consists of two NAND gates with the output of each one fed back to be an input of the other. A diagram follows.

    
        x  ----|
               |NAND>----*----- q
            ---|        /
            |          / 
            ----------/---
                     /   |
            --------/    |
            |            |
            ---|         |
               |NAND>----*----- u
        y  ----|
    
    

    The inputs to the circuit are $x$ and $y$, and the outputs are $q$ and $u$. The output $q$ is an input with $y$ to a NAND gate whose output is $u$, and the output $u$ is an input with $x$ to a NAND gate whose output is $q$. The stable states of this circuit are those assignments of $0$ and $1$ to the wires $x$, $y$, $q$, and $u$ that satisfy the following equations.

       q  =  x NAND u
       u  =  y NAND q
    
    This set of equations has 5 solutions, as follows.
    (1)   x = 0, y = 0, q = 1, u = 1
    (2)   x = 1, y = 0, q = 0, u = 1
    (3)   x = 0, y = 1, q = 1, u = 0
    (4)   x = 1, y = 1, q = 1, u = 0
    (5)   x = 1, y = 1, q = 0, u = 1
    

    Note that the values of the output wires $q$ and $u$ are not determined by the values of the input wires (see (4) and (5)). If we avoid state (1), we can use the other four states to remember one bit of information. Consider how we can move from one of these four states to another by changing the value on one input wire, either $x$ or $y$.

                            (y=0)
                          <--------   
        (x=1,y=0,q=0,u=1) ---------> (x=1,y=1,q=0,u=1)
                         ^  (y=1)    /
                          \         /
                           \       /
                            \     /
                             \   /
                              \ /
                               X
                              / \
                      (x=0)  /   \  (y=0)
                            /     \
                           /       \
                          /         \
                         /           \
                        V   (x=0)     \
                          <--------
        (x=0,y=1,q=1,u=0) ---------> (x=1,y=1,q=1,u=0)
                            (x=1)
    
    In the states on the left, the inputs $(x=1,y=0)$ or $(x=0,y=1)$ determine the outputs. Then when $y$ (or $x$) is set to $1$, there is a transition to the corresponding state on the top, where the inputs are $x=1$ and $y=1$, but the state on top indicates that the preceding left state was $(x=1,y=0)$ while the state on the bottom indicates that the preceding left state was $(x=0,y=1)$.

    The NAND latch is the heart of a D-flip flop, which we'll see next lecture.

    Gates and circuits IV.

    Summary:

    Please see the notes: NAND latch and D flipflop. and Memory.

    The NAND latch (previous lecture) is the heart of a D flipflop, which we now describe. (There are numerous other types of flipflops for various purposes, but the D flip flop will illustrate the basic ideas.) Consider the diagram of a D flipflop at the bottom of the page: NAND latch and D flipflop. The inputs of the circuit are $d$ (for data) and $s$ (for set), and the output is $q$. The subcircuit in the box is just the NAND latch, with the second output, $u$, used only internally. (We could just as well have made it an output of the circuit, but we chose not to.) To understand the behavior of this circuit, first consider the case when $s = 0$. Because $s$ is an input to the two NAND gates on the left, we know that the (internal) wires $x$ and $y$ will both be $1$ (regardless of the value of $d$.) By our previous analysis of the NAND latch, we know that the wire q will retain its previous value, regardless of the value of d. In effect, when $s = 0$, the D-flip flop just remembers the previous value of $q$. When $s = 1$, then what happens depends on the value of $d$. We know that if one of the inputs to a NAND gate is $1$, then the output is the complement of the input (because NAND(1,0) = 1 and NAND(1,1) = 0). Looking at the values of the internal wires $x$ and $y$, we see that when $s = 1, x = d'$ and $y = d'' = d$. Thus, when $d = 1$, we have $x = 0$ and $y = 1$, so $q = 1$ by our previous analysis of the NAND latch. And when $d = 0$, we have $x = 1$ and $y = 0$, so $q = 0$ by our previous analysis of the NAND latch. In effect, when $s = 1$, $q$ is set to the value of $d$.

    This behavior is used to store one bit of information. Normally we keep $s = 0$, and the circuit stores the previous value of $q$ (either $0$ or $1$), which is continuously available on the output wire $q$. At the time in the computation when the wire $d$ has the value that we want to store, we set $s = 1$ for a short time. This causes the NAND latch to set $q$ to the value on the wire $d$, and then $s$ is set back to $0$, which causes this value to be the new stored value.

    We can arrange several one-bit memories in parallel to form a register -- a circuit that can store several bits of data, with a common set line. For example, see the 4-bit register constructed out of 4 D-flip flops in the notes: Memory. The idea of the register is that when its set line = 1, each one-bit memory copies the value on its individual input line to be its new stored value, and when its set line = 0, the values on each output line stably remain what they were, regardless of the values on the input lines in the meantime.

    We consider a set of four 4-bit registers and a single 2-bit register, organized into a tiny "random access memory" (or RAM). We consider each of the four registers to have an address consisting of two bits, so that the addresses are 00, 01, 10, 11. The 2-bit register (which is the "memory address register" (or MAR)), can hold one of these addresses; we denote its two output wires as a1 (for the high-order bit) and a0 (for the low-order bit). "Reading" from the RAM consists of arranging for the contents of the memory register whose address is in the MAR to appear on a selected set of output wires. We can use three 4-bit selectors to accomplish this, as follows. One selector has the 4 outputs of register 00 as its left inputs and the 4 outputs of register 01 as its right inputs, and a0 (the low-order bit of the address) as its selector input. Thus, its output wires have the contents of register 00 if a0 = 0 and the contents of register 01 if a0 = 1. The second selector has the 4 outputs of register 10 as its left inputs and the 4 outputs of register 11 as its right inputs, and a0 (again, the low-order bit of the address) as its selector input. Thus, its output wires have the contents of register 10 if a0 = 0 and the contents of register 11 if a0 =1. The third selector has the outputs of the first selector as its left inputs, and the outputs of the second selector as its right inputs, and a1 (the high-order bit of the address) as its selector input. The output wires of the third selector will have the desired values, namely, the contents of the memory register addressed by the two bits of the MAR.

    A diagram: Memory read with selectors.

    Consider now what happens if the MAR contains the address 10. Because a0 = 0, the output wires of the first selector will have the value of register 00, and the output wires of the second selector will have the value of register 10. Because a1 = 1, the output wires of the third selector will have the value of register 10, as desired. If we generalize this construction to a RAM with 2^a memory registers and an a-bit MAR, the selectors using each bit of the address operate in parallel, so the time for the contents of the addressed register to appear on the output wires of the final selector is linearly proportional to the quantity a (the number of address bits).

    An alternative view of the memory read circuit, without the abstraction of the 4-bit selectors: Memory read. While we didn't discuss how to implement writing to memory, a picture of the Fall 2012 class design for a write circuit may be found in Memory write.

    Gates and circuits - one more thing.

    A diagram: Memory read with selectors.

    Consider now what happens if the MAR contains the address 10. Because a0 = 0, the output wires of the first selector will have the value of register 00, and the output wires of the second selector will have the value of register 10. Because a1 = 1, the output wires of the third selector will have the value of register 10, as desired. If we generalize this construction to a RAM with 2a memory registers and an a-bit MAR, the selectors using each bit of the address operate in parallel, so the time for the contents of the addressed register to appear on the output wires of the final selector is linearly proportional to the quantity a (the number of address bits).