7.4 Flip-Flop: Edge-Triggered Storage, State, Set, and Reset

Explain how edge-triggered storage differs from level-sensitive storage, and describe the roles of state, active clock edge, set, and reset in a general flip-flop.

A flip-flop is the workhorse storage element of synchronous digital design — the component every register, counter, and finite-state machine in the rest of this course is ultimately built from. Where a latch is level-sensitive and transparent for the whole duration an enable is asserted, a flip-flop is edge-triggered: it samples its input at one single, instantaneous clock transition and is otherwise completely unresponsive to input changes for the rest of the cycle. This topic introduces the general vocabulary — state, clock edge, set, reset — that applies to every specific flip-flop type covered in Module 8 (SR, JK, D, T).

Core Concept: Sample-Once-Per-Edge Behavior

A flip-flop holds a single bit of state, conventionally labeled Q (with its complement Q'). At every active clock edge — a rising edge for a positive-edge-triggered flip-flop, a falling edge for a negative-edge-triggered one — the flip-flop looks at its data input(s) exactly once, decides what the new state should be according to its specific type's rule (D, T, JK, or SR — covered device-by-device in Module 8), and updates Q to that new value. Between active edges, no matter how the data inputs wiggle, Q does not move at all; it is deaf to everything except the instant of the active edge.

This is the crucial contrast with the latch from Topic 7.3: a D flip-flop captures D at the active clock edge and holds that captured value rock-steady until the next active edge, whereas a D latch would have tracked D continuously for the entire time its enable was high. Edge-triggered behavior is what makes flip-flop-based synchronous design predictable and analyzable — a signal's value only matters at one precise instant per clock cycle, not throughout an entire window.

• Q = the flip-flop's stored state (one bit); Q' is its complement. • Active edge = the single instant (posedge or negedge) at which the flip-flop samples its input(s). • Between active edges, Q is completely unaffected by data input changes.

Step-by-Step: Set, Reset, and the Two Flavors of Each

Beyond its normal data input, most practical flip-flops also expose set and reset controls that force Q to a known value (1 for set, 0 for reset) independent of the regular data path — essential for initializing state at power-up or recovering from an error condition. These controls come in two flavors that behave very differently and must never be confused: a synchronous set/reset only takes effect at the next active clock edge, exactly like the normal data input, so it participates in the same edge-triggered sampling discipline as everything else. An asynchronous set/reset, by contrast, takes effect immediately the instant it is asserted, completely independent of the clock — it can force Q to 0 or 1 in the middle of a clock cycle, ignoring the clock entirely.

Asynchronous reset is typically used for power-on initialization (getting every flip-flop in a chip into a known state as soon as power stabilizes, before the clock is even guaranteed to be running cleanly), while synchronous reset is generally preferred inside the steady-state operating logic because it behaves as just another synchronous input, which keeps static timing analysis clean and avoids reset-related glitches on the reset release edge.

Practical Application: Flip-Flops as the Basis of Registers, Counters, and FSMs

Every register you will meet in Module 9 is simply a bank of flip-flops sharing a common clock, each holding one bit of a multi-bit value. Every counter in Module 10 is a set of flip-flops whose next-state logic increments (or decrements) the stored value on each active edge. Every finite-state machine — including the traffic-light controller and digital-lock design challenges referenced later in this course — stores its current state in flip-flops and computes next-state and output logic combinationally from that stored state plus the current inputs. In other words: flip-flops are the atomic memory unit, and essentially the entire remainder of sequential digital design is composition of flip-flops with combinational logic around them.

General edge-triggered flip-flop behavior

At active clock edge (posedge clk, or negedge clk):
    Q <= new_state   // determined by the specific flip-flop type's rule

Between active edges:
    Q unchanged, regardless of data input activity

Asynchronous reset:  rst asserted -> Q = 0 immediately, independent of clk
Synchronous reset:   rst sampled only at the next active clk edge

Code Examples

D wiggles freely between clock edges, but Q only updates at each posedge, capturing whatever D happens to equal at that exact instant. Notice that D briefly goes to 1 and back to 0 between the second and third edges — that transient value is never captured, because the flip-flop was not sampling at that moment. Only the value present exactly at each rising edge propagates to Q.

Q changes only at posedge clk, and only to whatever D equals at that precise instant — nothing that happens between edges affects Q.

clk:   __|‾|__|‾|__|‾|__|‾|__
D:     __0__1____0__1_1__1__
Q:     __0__0____1__1_0__1__
               ^edges sample D here only

Edge-triggered sampling vs. continuous latch tracking

The flip-flop only reacts at the instantaneous edge; the latch reacts continuously across the whole enabled window — the same D waveform produces very different Q behavior in each device.

Flip-flop (edge-triggered):
  clk  __|‾|________|‾|________
  D    __1____0_____1____0_____
  Q    __1______________0______
         ^only samples exactly here

Latch (level-sensitive, for contrast):
  EN   __|‾‾‾‾‾‾‾‾‾‾|__________
  D    __1____0_____1__________
  Q    __1____0_____[frozen]___

Important Rules

A flip-flop samples its input(s) only at the active clock edge (posedge or negedge), never continuously.

Between active edges, Q is completely unaffected by data input changes, no matter how they wiggle.

Synchronous set/reset takes effect only at the next active clock edge, like any other synchronous input.

Asynchronous set/reset takes effect immediately, independent of the clock — typically reserved for power-on initialization.

Pipeline registers in CPU design

In a pipelined CPU, flip-flops sit at every stage boundary (fetch/decode, decode/execute, execute/memory, and so on), each capturing the combinational result computed in one stage so it is available, frozen, as the input to the next stage exactly one clock cycle later. This is precisely the edge-triggered discipline described in this topic, applied at CPU-architecture scale: the entire notion of a pipeline stage boundary is a bank of flip-flops sampling on a shared active edge.

Treating synchronous and asynchronous reset as interchangeable, e.g. assuming an asynchronous reset waits for the next clock edge to take effect.

Asynchronous reset forces Q to its reset value the instant it is asserted, with no dependency on the clock at all; only synchronous reset waits for and is sampled at the next active edge.

Confusing the two leads to real design bugs: if a designer assumes an asynchronous reset behaves synchronously, they may build logic that briefly runs from an unreset (garbage) state after power-up, before the reset has a chance to align with a clock edge that isn't guaranteed to exist yet.

What happens to a positive-edge-triggered flip-flop's output Q if its D input changes value in the middle of a clock cycle, well away from any clock edge? A. Q immediately tracks the new D value, just like a transparent latch B. Q is unaffected until the next active (rising) clock edge, at which point it captures whatever D equals at that instant C. Q toggles to the opposite of its current value D. The flip-flop enters an undefined state

B. Q is unaffected until the next active (rising) clock edge, at which point it captures whatever D equals at that instant — This is the defining behavior of edge-triggered storage: Q only updates at the active clock edge. A mid-cycle change on D has zero effect on Q until the next posedge arrives, at which point Q captures D's value at that precise instant.

Why is asynchronous reset typically reserved for power-on initialization rather than steady-state operating logic? A. Because asynchronous reset is slower than synchronous reset B. Because it takes effect immediately regardless of the clock, which is exactly what's needed before a clean clock is guaranteed to be running, but can otherwise complicate static timing analysis and introduce reset-related glitches inside steady-state logic C. Because asynchronous reset only works on JK flip-flops D. Because asynchronous reset cannot force Q to a known value

B. Because it takes effect immediately regardless of the clock, which is exactly what's needed before a clean clock is guaranteed to be running, but can otherwise complicate static timing analysis and introduce reset-related glitches inside steady-state logic — Asynchronous reset's whole value is that it does not depend on the clock — ideal for getting a chip into a known state as soon as power stabilizes. But because it can assert independent of the clock at any point in a cycle, it complicates timing closure and can create glitches on release, so synchronous reset (sampled cleanly at an active edge, like any other input) is generally preferred inside normal operating logic.

A flip-flop is positive-edge-triggered (posedge). Given D = 0,1,1,0,1 sampled exactly at five successive rising clock edges, and D also glitches to the opposite value briefly between each pair of edges, what is Q after each edge?

Q after each successive posedge simply equals D's value at that edge: Q = 0, 1, 1, 0, 1 — the mid-cycle glitches between edges have no effect whatsoever on Q.

Only the value of D exactly at each posedge matters — ignore anything that happens between edges.