Lecture 20: Sequential logic (by Trek Palmer) ================================================ Sequential Circuits -------------------- So far what we've been working with is known as combinational logic, meaning you just lump the circuits together to process some input. If we want a system that uses flip-flop based memory, then we're going to have to worry about the amount of time it takes to stabilize the outputs and inputs to the memory device. There are two approaches, you can deeply analyze the circuitry and determine that the signals are all valid when they're processed. This is hard (and is known as asynchronous circuitry). An easier solution is to extend the clock signal necessary for real flip flops to the entire logic of the chip. If everybody's operating on the same clock, they can't get out of sync with the memory! This solution is easier and is known as synchronous circuitry. The only down side is that as clock speeds increase, the amount of area that can be covered by a clock within a single tick shrinks. Any circuitry that relies on memory, that is, any circuit whose succeeding state depends upon inputs as well as the current state is known as a sequential circuit (because it progresses through a sequence of states, presumably). Simple Counter --------------- As a first sequential circuit, lets examine a two-bit counter that can count up or down. So, since it has two bits, it can assume the values 0,1,2,3, encoded as 00,01,10,11. Let's call the input to control the direction of the counter x. If x is 0 the counter counts up, if x is 1 the counter counts down. Let's further assume that the counter has an output, z, and that z is 1 if the counter's value is 3, 0 otherwise. With sequential circuits, a truth table is insufficient. At the very least, the truth table must be extended to include the current state of the system. In this case, that's not too bad, but in real circuits the number of states can be quite massive, and the resulting truth table would be really really MASSIVE. Fortunately, there's a better way. Using our diagramming skillz we can construct what's known as a state machine. In a state machine, circles represent states, and arrows between them indicate transitions between states keyed by input. It is also usual to specify the output along a given transition. So, for this circuit the following state machine would be: +-----+ x = 0 / z = 0 +------+ | S0 |--------------------------------->| S1 | | |<---------------------------------| | +-----+ x = 1/ z = 0 +------+ | ^ | ^ | | | | x=1/| | x=0/ x=0/ | | x=1/ z=0 | | z=1 z=0 | | z=0 | | | | | | | | | | | | | | | | | | | | | | | | | | | | v | v | +-----+ x = 1 / z = 1 +------+ | S3 |--------------------------------->| S2 | | |<---------------------------------| | +-----+ x = 0 / z = 0 +------+ We can also describe this in a state table thus: Current | Next state | Output (z)| State | x=0 | x=1 | x=0 | x=1 | --------+-----+------+-----+-----+ S0 | S1 | S3 | 0 | 0 | --------+-----+------+-----+-----+ S1 | S2 | S0 | 0 | 0 | --------+-----+------+-----+-----+ S2 | S3 | S1 | 0 | 0 | --------+-----+------+-----+-----+ S3 | S0 | S2 | 1 | 1 | --------+-----+------+-----+-----+ So, to actually build a circuit out of this we need two flip flops. Let's be creative and dub them '1' and '2'. In addition to the clock, we have two inputs, Y1 and Y2 which are the inputs to the 'D' line of flipflop 1 and 2 respectively. Both 1 and 2 have two outputs each. We'll dub them y1, ~y1, y2, ~y2. Now, given the state table and these values, we can actually construct a truth table of sorts and run some kind of analysis over it (such as karnaugh mapping) to derive a boolean formula for this system in terms of Y*, y*, x and z. Now, this is a lot of stuff that is strictly beyond the scope of this class (unfortunately), so you'll just have to take my word for it that: Y2 = y2 XOR y1 XOR x Y1 = ~y1 z = y1 ^ y2 So we now have the following circuit: X----------+ +------+-----\ | | | AND |---------------------------------Z | | +---+-----/ ~y1 | | | +---------|------|--|-------------------------------------------+Y1 | | | | ______ | | y1 +------|--|--\\ \ | | +------------|--+---\\ XOR \----------------------+Y2 | | | +--------+------// / | | | | |y2 //______/ | | | | | | | | | | flip-flop2 | | | | | +----------+ | | | | +----------+ Q D+------------------------+ | | | | | | | | | ~Q CLK|o---------+ | | | +----------+ | | | | | | | | flip-flop1 | | | | +----------+ | | | +--------------+ Q D+----------|----------------------+ | | | | +------------------+ ~Q CLK|o---------+-------Clock +----------+ Note that even though it's a 3-input XOR, the function is (y2 XOR y1) XOR x State machine for a 2-bit saturating counter -------------------------------------------- A variant of the previous counter is what's known as a saturating counter. Whereas the previous counter was performing mod-4 arithmetic, a 2-bit saturating counter won't loop from 3 to 0 or from 0 to three. So, in saturating arithmetic 3 + 1 = 3 and 0 - 1 = 0. We can modify the state diagram to describe a saturating counter thus: +-----+ x = 0 / z = 0 +------+ | S0 |--------------------------------->| S1 | +>| |<---------------------------------| | | +-----+ x = 1/ z = 0 +------+ | | | ^ +---+ | | x=1/ x=0/ | | x=1/ z=0 z=0 | | z=0 | | | | | | | | x=0/z=1 | | +--+ | | | | | | v | v | +-----+ x = 1 / z = 1 +------+ | S3 |--------------------------------->| S2 | | |<---------------------------------| | +-----+ x = 0 / z = 0 +------+ We can also describe this in a state table thus: Current | Next state | Output (z)| State | x=0 | x=1 | x=0 | x=1 | --------+-----+------+-----+-----+ S0 | S1 | S0 | 0 | 0 | --------+-----+------+-----+-----+ S1 | S2 | S0 | 0 | 0 | --------+-----+------+-----+-----+ S2 | S3 | S1 | 0 | 0 | --------+-----+------+-----+-----+ S3 | S3 | S2 | 1 | 1 | --------+-----+------+-----+-----+ This is where the power of a state diagram comes in. All the state diagram required was a change to two arcs. The circuit necessary to implement this logic is not so obvious however. So, in most cases it is much more expressive to describe a sequential circuit with a state diagram or a state table. Timing diagrams ---------------- Because sequential circuits are dependent upon state, they can be said to have a notion of time. Therefore diagrams that explicitly chart the behavior of sequential circuits as time unfolds are useful. These are called, unsurprisingly, timing diagrams. Because we're dealing with synchronous logic, there is a global clock that all the circuitry is driven off of, so most timing diagrams are done in terms of clock ticks rather than nanoseconds. So, if we look at the simple 2-bit non-saturating counter, we can construct the following timing diagram: >| |<-one clock pulse CLK: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |__ X: _____________________________________ ____________________________| y1: ____ _____ _____ _____ _____ _____ _____ _____ ___| |___| |___| |___| |___| |___| |___| |___| |___ y2: _________ _____________ _________ ________ ______| |_______| |_______| |_______| z _____ _____ _____ _____ __________| |___________| |___________| |___________| |___ You can see from this diagram, that in addition to being a two-bit counter, the circuit also acts as a clock divider. Note that for a constant value of X, y1 pulses at half the frequency of CLK, and y2 at a quarter. Timing diagrams are often used to illustrate periodic causal relationships separated in time. For a simple circuit like this, it might seem a touch overkill, but for busses timing diagrams are one of the better ways of expressing data transfer protocols. Now let's look at the timing diagram for the saturating counter: >| |<-one clock pulse CLK: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |__ X: _____________________________________ ____________________________| y1: ____ _____________________ _____ ___| |___| |___| |__________________________ y2: _____________________________ ______| |______________________________ z _____________________ __________| |_________________________________ Not so clear now, eh. This is where timing diagrams start to show their usefulness. Here you can see more clearly the direct relationship between z and y1 and y2.