Debugging the Digital Circuit


By Dave Lame
Minor modifications by Vamshidhar Kommineni

"My Circuit Doesn't Work"


    So often is this cry heard in the ECE 249, and for many students it is the beginning of the ordeal of debugging the circuit.

    Many students are baffled by the process of making faulty circuits work. They have studied the theory of circuit design, and having applied the proper technique, expect the thing to work as soon as power is applied. When it doesn't, the students stare blankly at the mass of wires and integrated circuits that now face them.

    These students would do well to remember their days of learning to program computers. They probably entered the first program, pushed the keys to make it run, and were surprised to find that the computer didn't know what they wanted. In the process of learning to program, they learned some techniques to help them debug their code. Fortunately, many of these techniques are applicable to debugging digital circuits.

    The first way to making debugging simpler in the case of programs or circuits is: Do it right in the first place. A circuit thrown together quickly without a lot of thought will work about as well as the program that is typed in without being examined in detail. Remember to look for the special cases or unusual circumstances that might bother you in the future. This can save you a lot of time in the lab, where time is severely limited.

    But no program worth mentioning works the first time it is run. Likewise, few circuits work correctly the first time. So, you must figure out where the problem lies.

    The most important thing to remember is that inputs and outputs won't tell you much. Often a student will observe various combinations of inputs and (incorrect) outputs for quite some time, hoping to discover the problem. This is like running the program over and over again with different input data. It takes lots of time and it doesn't tell you much.

    In order to discover something useful, you must look at the intermediate states. In programming, this is generally accomplished by the addition of temporary print statements. Intermediate results are printed so that the programmer can see where something goes wrong.

    So too must the designer display intermediate states. He must observe voltage levels at the inputs, the outputs, and various points in between, looking for the source of an incorrect value.

    This brings up an interesting point. How do you observe intermediate states? The answer is to place some probe that will indicate voltage at the point in the circuit that you wish to observe.

    A simple probe for this purpose is an LED. Connect some point to an LED and it will tell you whether that point registers a "1" or "0". While this may be useful information, it is inadequate.

    Despite what you may be told, all electrical circuits are continuous and may take on a continuous range of voltages. Therefore, an LED, which can indicate only two discrete states, is not sufficient to tell you exactly what is happening in your circuit. Instead you must use the oscilloscope in the lab station.

    Of course, few of you have an oscilloscope outside the lab. There, LEDs will have to do. The point is that the scope is a far superior instrument, and should be used when possible.

    Now that you know how to look, you may wonder what to look for. Simply put, you look for something wrong. Begin at the input and look until you find something that isn't right. (Note that this implies that you should know exactly what the circuit should be doing.) Something could be wrong in two ways; it could be that a logic 1 is a logic 0, or the level could be a "suspect".

    In TTL, an ideal logic 1 is +5V with respect to ground and logic 0 is 0V. In reality, anything less than about 1.5V will act as a 0, and anything greater than 3V will act as a 1. If the voltage is in between these two levels, it usually indicates a problem. I call these values "suspect". A suspect value can be caused by many things.

    One thing that causes them is an improper ground or power connections. Much time is wasted looking for problems that would disappear if all circuit ground and power connections were properly made. All chips must have Vcc and ground connections. Also, the ground of the I/O must be connected to the ground of the protoboard.

    The other most common cause of suspect values is a connection of two outputs. The following configuration is unacceptable. If the following occurs with any non-open collector TTL gates, improper results may occur. In many cases the result will be a suspect logic level.

    Note that suspect logic levels cannot be found with LEDs.

    If you observe a suspect level, first check that the chip involved is powered and grounded. Then check to see that no outputs associated with the chip may have been accidentally connected together.

    Now that we know what to look for(wrong or suspect values), what kind of errors cause them?

    The frst kind of improper error is an error in the logic, ie. a mistake in the Boolean algebra or an improper analysis of the states in a sequential circuit. The best way to detect and fix these errors is on paper before the circuit is built. In other words, don't make them.

    The circuits of this lab should be fairly easy to analyze for basic operations assuming ideal gates. If you do make this mistake, it will be readily apparent, but time consuming to fix if you build your circuit with it.

    The second type of error is a wiring error. This is analogous to a typographical error in inputting a program. Only here, there is no compiler to detect it. When an error is localized, examine all the wires attached to that point. Remember, all points connected with wires (not through gates) are electrically common, so check them all.

    One sign that a wiring error has occurred is a suspect logic value. Often, the cause is an improper connection that leaves two outputs connected together, or an output connected to ground or power.

    The third kind of error, not found in computer programming is the timing error. The most common of these is the Glitch.

    A Glitch is a temporary improper output. They may be caused by many things, the most common being different path lengths in a circuit. Experiments 1 and 4 show examples of circuits with glitches.

    To prevent glitches, remember a few basic rules. In synchronous circuits, make all transitions on correct clock edges, usually the same edge for all transitions.

    In asynchronous circuits, make sure that only one input changes at a time.

    Glitches are often difficult to detect, since they only last a few seconds. Due to their nature they will only cause problems, in sequential circuits (ie. circuits with memory). If the static situation is correct before and after a state transition, but the state transition is incorrect, or a counter or shift register advances more than once, a glitch is a likely cause.

    Use a timing diagram to discover a glitch if you think they are present.

    The final cause of problems you may encounter in debugging is also not often encountered by programmers: equipment failure.

    Occasionally, but not often, equipment in the 249 lab will fail. Usually this is in the form of a defective IC. Don't be too eager to blame the equipment though. Most cases where students blame the equipment are caused by other things. (For example, the 249 lab has a circuit to test the lab I/O boards. Its primary purpose is to demonstrate to students that situations in which equipment appears to be faulty may be caused by improper electrical connections.)

    Equipment failure can be detected when outputs at a chip do not correspond to inputs. For example, the inputs of a NAND gate are each +4V, a logic 1, and the output is 2.1V, a suspect logic value. It is not necessarily the equipment that is to blame. More often, the chip is not properly grounded, or a wiring error has occurred. If you suspect equipment failure, test the suspect IC when disconnected from the rest of the circuit. Remove all connections from this IC to your circuit. If it still misbehaves, it is probably faulty; replace it. If it works correctly in isolation, a connection is probably faulty. Under any circumstances if the second chip behaves the same way, there is almost certainly something wrong with your circuit.

    Finally, there are a couple of things you can do to help find these errors. If a computer program is complex, programmers break them into subroutines to aid debugging. Likewise a complex circuit can be broken into functional blocks. Then each functional block can be debugged individually. Start by identifying which blocks work, and which blocks don't.

    This means that the first signals to check are the connections between the blocks. These form the inputs and outputs of the block. If these signals are incorrect, examine the insides of the block.

    One last thing to do corresponds to single-stepping an assembly language program. In many cases the circuits you design specify the use of a high speed clock from a function generator. However few require such a clock to work correctly. In these cases, obtain the clock from a debounced switch while debugging. This will allow you to observe signals for a long period in between clock transitions.


In Summary