Sequential Logic & the Clock
Latches, D flip-flops, registers, counters and shift registers; why synchronous design uses one clock edge; a first look at setup and hold.
1. Why circuits need memory
Every circuit in Chapters 1 and 2 was combinational: its outputs depend only on its present inputs. That is enough to add two numbers, but not to count button presses, to step through a sequence of LEDs, or to remember the result of the last addition. All of those need a circuit whose output depends on what happened before. Such a circuit holds a state and is called sequential.
Memory in hardware comes from feedback: an output wired back to an input. The simplest example is two inverters in a ring. If the first outputs 1, the second outputs 0, which keeps the first at 1. The opposite state (0, then 1) is equally self-consistent. The loop is bistable: it has two stable states and stays in whichever one it is put in, as long as the power is on. That is one bit of memory. What is missing is a way to write it.
This chapter builds the standard memory elements step by step: the SR latch, the D latch and the edge-triggered D flip-flop. Then it uses flip-flops to build registers, counters and shift registers, and introduces the single most important discipline in FPGA design: synchronous design with one clock.
2. The SR latch
Replace the two inverters with two NOR gates and you get two extra inputs, S (set) and R (reset). Recall that a NOR outputs 0 as soon as any input is 1, and that with its other input at 0 it behaves as an inverter.
Follow a set operation: with \(S = 1\) the lower NOR outputs \(\overline{Q} = 0\). The upper NOR now sees \(R = 0\) and \(\overline{Q} = 0\), so \(Q = 1\), which also holds the lower gate at 0. When \(S\) returns to 0, the loop keeps \(Q = 1\): the latch has remembered the pulse. The combination \(S = R = 1\) breaks the rule that the two outputs are complements, and releasing both inputs together leaves the latch in an unpredictable state (Problem 2). It is therefore forbidden.
3. The D latch
The SR latch has two problems: a forbidden input, and the fact that it reacts at any time. The D latch fixes both. It has a data input D and a control input, here called clk. Two AND gates in front of an SR latch form \(S = D \cdot \text{clk}\) and \(R = \overline{D}\cdot\text{clk}\), which can never both be 1.
- While \(\text{clk} = 1\) the latch is transparent: \(Q\) follows \(D\).
- While \(\text{clk} = 0\) it is opaque (closed): \(Q\) holds the last value \(D\) had when clk fell.
This equation is a 2:1 multiplexer (Chapter 2) whose output is fed back to its own input: select the new data or keep the old value. Transparency, however, is a serious problem when a latch sits in a feedback loop. Imagine a counter made of latches and an incrementer: while clk is high, the new value goes straight through the latch, back into the incrementer, and around again. The count races ahead by an amount that depends on gate delays (Problem 5). We need a memory element that takes its new value at a single instant.
4. The edge-triggered D flip-flop
Put two D latches in series and drive them with opposite clock phases. The first, the master, is transparent while clk is 0. The second, the slave, is transparent while clk is 1. At no moment are both open, so there is never a transparent path from D to Q.
The result is a D flip-flop (DFF): its output takes the value of D at the rising edge of the clock (the instant clk goes from 0 to 1) and holds it until the next rising edge. Everything D does between edges is ignored. Writing \(Q[k]\) for the value during clock cycle \(k\):
The flip-flop is a one-cycle delay. Thanks to that, a feedback loop through a flip-flop is perfectly safe: the logic computes the next value from the current one at leisure, and the flip-flop takes it at the next edge, exactly once. The program below compares a D latch and a D flip-flop driven by the same signals. Notice the short glitch on D around 41 ns: the latch, transparent at that moment, copies it to its output; the flip-flop never sees it.
Click Run to execute the Python code
Code will be executed with Python 3 on the server
5. Enable and reset
Two extra inputs make the flip-flop practical. A clock enable (en) decides whether the flip-flop takes a new value at this edge or keeps its current one. It is a 2:1 mux in front of D, selecting between the new data and the flip-flop's own output:
A synchronous reset (rst) forces the flip-flop to a known value, usually 0, at the next clock edge. It is another mux, placed before the enable mux so that it has priority. Some designs instead use an asynchronous reset, which acts immediately without waiting for an edge; this course uses synchronous resets, which are timed like any other data input.
Every flip-flop in a Xilinx 7-series FPGA, including the Zynq-7020 on the PYNQ-Z2, has a clock-enable input and a set/reset input built in, so these features cost no extra logic (Chapter 5). The FPGA also loads every flip-flop with a defined initial value when it is configured, which is why many FPGA designs need no reset at all.
6. Registers and counters
An \(N\)-bit register is simply \(N\) flip-flops sharing the same clock (and usually the same enable and reset), storing an \(N\)-bit word. Registers hold the state of every digital system: a processor's registers, the current count, the current state of a state machine.
A counter is a register whose input is its own output plus one. In other words, a register and an adder (Chapter 2) in a feedback loop:
Looking at individual bits, bit 0 toggles on every edge, and bit \(i\) toggles exactly when all bits below it are 1, since that is when a carry reaches it: \(q_i[k+1] = q_i[k] \oplus (q_0 q_1 \cdots q_{i-1})[k]\). Bit \(i\) therefore toggles every \(2^i\) cycles, a square wave of frequency \(f_\text{clk}/2^{i+1}\).
Counters are everywhere: dividing a fast clock down to a visible blink rate, timing a debounce interval, generating the bit rate of a serial port, addressing memory. Comparing the count with a constant (count == 15) gives a one-cycle pulse that can enable other registers, the "tick" pattern used throughout this course.
7. Shift registers
Chain flip-flops so that each one's D input is the previous one's Q, all on the same clock. On every edge, each bit moves one position along the chain. That is a shift register.
Shift registers convert between serial and parallel data: a UART receiver (Chapter 16) collects the bits of a byte one at a time into a shift register and then reads all eight at once. They also delay a signal by a fixed number of cycles, and they form the two-flip-flop synchroniser that brings button signals safely into the clock domain (Chapter 14). A shift register works only because each flip-flop takes its input at the edge and changes its output slightly after it, so a bit advances exactly one stage per edge (Problem 5).
8. Synchronous design and the clock
We can now state the design style that almost every FPGA design follows. A synchronous circuit is built from just two kinds of parts:
- registers (flip-flops), all driven by the same clock edge, which hold the state;
- combinational logic between them, which computes the next state from the current state and the inputs.
Every feedback loop passes through at least one register, and the clock is a dedicated, regular square wave that is not produced by the logic. On each rising edge all registers update simultaneously; during the rest of the cycle the logic settles. This reduces the analysis of a design with millions of gates to two questions: is the logic correct (a matter of truth tables, checked in simulation), and is it fast enough to settle within one clock period (a timing question, checked by tools)?
On the PYNQ-Z2 the programmable logic receives a 125 MHz clock, so one cycle lasts 8 ns. FPGAs distribute the clock through a dedicated low-skew network so that it reaches all flip-flops at nearly the same instant (Chapter 6).
9. A first look at setup, hold and maximum frequency
A flip-flop needs its D input to be stable for a short window around the clock edge. It must be stable for at least the setup time \(t_{su}\) before the edge, and remain stable for the hold time \(t_h\) after it. After the edge the new value appears at Q after the clock-to-Q delay \(t_{cq}\).
Follow one bit through the path in the figure. At edge \(k\) the launching flip-flop changes its output after \(t_{cq}\); the logic needs up to \(t_{pd}\) to settle; and the capturing flip-flop needs the result \(t_{su}\) before edge \(k+1\). Hence the setup condition, which sets the maximum clock frequency:
The margin \(T_\text{clk} - (t_{cq} + t_{pd} + t_{su})\) is called the slack; positive slack means the path meets timing. The setup condition must hold for the slowest path in the design, the critical path, which is why the ripple-carry delay of Chapter 2 matters. The program in Section 4 ends with two illustrative numbers: a short path that could run at about 600 MHz and a long ripple adder path limited to about 170 MHz.
The hold condition protects the other side of the edge: the new value launched at edge \(k\) must not reach the capturing flip-flop so quickly that it corrupts the value being captured at that same edge. Using the minimum delays (the contamination delay \(t_{cd}\) of Chapter 2):
Notice that the clock period does not appear: a hold violation cannot be fixed by slowing the clock. In FPGAs the tools guarantee hold automatically in almost every case, but setup is something you will work on yourself. What happens when an input violates the setup/hold window anyway (a button pressed at a random instant) is the subject of metastability. Chapter 15 treats all of this in depth: clock skew, slack reports, pipelining and the mean time between failures of a synchroniser.
| Quantity | Symbol | Meaning |
|---|---|---|
| clock period | T_clk | time between rising edges (8 ns on the PYNQ-Z2) |
| clock-to-Q | t_cq | delay from the edge until Q shows the new value |
| propagation delay | t_pd | longest settling time of the logic between registers |
| contamination delay | t_cd | shortest time before the logic output starts to change |
| setup time | t_su | D must be stable this long before the edge |
| hold time | t_h | D must stay stable this long after the edge |
10. Preview: the same thing in HDL
Here is a D flip-flop with enable and synchronous reset, and the 4-bit counter of Section 6, in Verilog and VHDL. Part III explains the syntax (clocked processes are the subject of Chapter 9). For now, find the key ideas of this chapter in the code: posedge clk and rising_edge(clk) mean "only at the rising edge"; the if (rst) branch comes first, so reset has priority; when en is 0 nothing is assigned, which means "keep the old value"; and the counter is a register fed back through + 1.
// D flip-flop with clock enable and synchronous reset.
// q changes only on a rising edge of clk.
module dff_en (
input wire clk,
input wire rst, // synchronous, active high
input wire en, // clock enable
input wire d,
output reg q = 1'b0
);
always @(posedge clk) begin
if (rst)
q <= 1'b0;
else if (en)
q <= d;
// otherwise q keeps its value
end
endmodule// 4-bit binary counter: a register plus an adder feeding it back.
module counter4 (
input wire clk,
input wire rst, // synchronous, active high
input wire en, // count only when en = 1
output wire [3:0] count,
output wire wrap // 1 while count = 15 and en = 1
);
reg [3:0] q = 4'd0;
always @(posedge clk) begin
if (rst)
q <= 4'd0;
else if (en)
q <= q + 4'd1; // 15 + 1 wraps to 0
end
assign count = q;
assign wrap = en & (q == 4'd15);
endmoduleA testbench (Chapter 10) clocked both modules at 125 MHz for 40 cycles with the enable switched off every third cycle, checking the outputs after every edge against a simple model. Both the Verilog and VHDL versions report count = 11 after 40 cycles (27 enabled), wraps = 1 and PASS: 27 enabled increments from 0 wrap once past 15 and stop at \(27 - 16 = 11\). In Chapter 14 a counter just like this one, made 27 bits wide, blinks an LED on the PYNQ-Z2.
Practice Problems
0000 0000 and shifts towards the MSB on each rising edge, with the serial input entering at bit 0. The serial input carries 1, 0, 1, 1 on four successive edges, then 0 forever. Write the contents after each of the first four edges, and say after how many edges the first 1 reaches bit 7.