Skip to content

Latches and Flip-Flops

“State” is the internal information a circuit holds at a particular time. In sequential logic, outputs depend on both inputs and stored state. The fundamental storage structure is a bistable circuit with two stable states.

In practice, bistable storage is abstracted into two basic memory elements:

  • Latch: level-sensitive
  • Flip-flop: edge-triggered

They form the basis of registers, counters, and state machines.

D latch symbol

Figure 3.1: D latch symbol.

D flip-flop symbol

Figure 3.2: D flip-flop symbol.

A latch is level-sensitive. Its typical behavior is:

  • When enable is active (EN=1EN = 1), output follows input: Q=DQ = D.
  • When enable is inactive (EN=0EN = 0), output is latched and holds its previous value.

Some references use CLKCLK to mean enable. This manual uses ENEN to emphasize level sensitivity.

Latches are simple and have small delay, but if enable remains active too long, input glitches may propagate to output and cause hazards.

To avoid the uncertainty of level sensitivity, synchronous digital systems commonly use edge-triggered flip-flops. A flip-flop samples input only at a clock edge (rising or falling), and holds output stable between edges.

For a D flip-flop:

  • At the clock edge, QQ updates to the current DD.
  • Between edges, QQ is unaffected by changes on DD.

This discrete, synchronized state update makes flip-flops the preferred elements for program counters, general-purpose registers, and pipeline registers.

Experiment: Level-triggered vs edge-triggered behavior

Section titled “Experiment: Level-triggered vs edge-triggered behavior”
  • Understand the essential difference between level-triggering and edge-triggering.
  • Observe how a latch and a flip-flop respond to changing inputs.
  • Build intuition for clock–state–synchronization.

A latch is sensitive to the enable level; a flip-flop samples only at clock edges.

Logisim Evolution does not directly provide a D latch, so in this experiment you will build a D latch using basic gates. See Figure 3.3.

D latch gate-level circuit

Figure 3.3: Gate-level D latch circuit.

  • Simulator: Logisim Evolution

Task 1: Build a D latch and observe behavior

Section titled “Task 1: Build a D latch and observe behavior”
  1. Inputs/outputs
    • Place two input pins: DD and ENEN.
    • Place two output pins: QQ and Q\overline{Q} (label it nQ), set them as outputs.
  2. Generate D\overline{D}
    • Place a NOT gate and connect DD to get D\overline{D}.
  3. Build the gated signals and cross-coupled NAND latch
    • Place four NAND gates and wire them according to Figure 3.3.
  4. Verify and observe
    • Set EN=1EN=1, toggle DD (0→1→0) and check whether QQ follows immediately.
    • Set EN=0EN=0, toggle DD again and check whether QQ holds the value latched when ENEN switched 1→0.
    • Tip: if the state becomes abnormal due to wiring order, use Simulate → Reset Simulation.
  1. Inputs/outputs and clock
    • Place input pin DD and output pin QQ.
    • Place a Clock component as the clock source.
  2. Place a D flip-flop and connect clock
    • In Memory, place a D flip-flop.
    • Connect the clock output to the flip-flop’s CLK pin (triangle-marked).
  3. Connect data path
    • Wire DD to the flip-flop’s D pin.
    • Wire flip-flop Q to output pin QQ.
  4. Verify and observe
    • Toggle DD multiple times between two clock edges and check whether QQ stays unchanged.
    • Trigger one clock edge and check whether QQ updates to the value of DD at that edge.
    • Tip: use a low clock frequency to make edge sampling easier to observe.
  • Circuit screenshots.
  • A table/notes comparing:
    • how QQ responds to DD for a D latch with EN=1EN=1 vs EN=0EN=0;
    • how QQ updates for a D flip-flop before/after clock edges.
  • Write the truth tables for the D latch and D flip-flop and summarize (in your own words) the key difference between level-triggering and edge-triggering. Explain which is more suitable for synchronous register design.
  • Why do CPUs almost never use level-triggered latches directly as general-purpose register storage elements?

Read the Logisim Evolution documentation and draw timing diagrams for the D latch and D flip-flop.

Experiment: 4-bit synchronous parallel register

Section titled “Experiment: 4-bit synchronous parallel register”
  • Understand the structure of a parallel register.
  • Understand the role of a synchronous clock.
  • Build a multi-bit register using D flip-flops.
  • Implement a load-enable (write-enable) control.
  • Understand the purpose of asynchronous reset for initialization.
  1. Parallel register structure

An nn-bit register is built from nn D flip-flops in parallel. All bits share the same clock so the state updates synchronously.

  1. Load enable

To hold the current value when desired, place a 2-to-1 MUX in front of each flip-flop to select between “keep old value” (feedback) and “load new value”.

  1. Asynchronous reset

Asynchronous reset clears the register to zero without relying on the clock.

  • Simulator: Logisim Evolution
  1. Place four D flip-flops (name them bit0…bit3).
  2. Add one clock and connect it to all four flip-flops.
  3. Place four input pins: D0,D1,D2,D3D_0, D_1, D_2, D_3 and connect them to the corresponding D inputs.
  4. Place four output pins: Q0,Q1,Q2,Q3Q_0, Q_1, Q_2, Q_3 and connect them to the corresponding Q outputs.

Basic parallel register circuit

Figure 3.4: Basic 4-bit parallel register circuit.

  1. Verify by setting inputs (e.g. 1010), triggering clock edges, and observing outputs update.

Add a global control signal LoadLoad and place a 2-to-1 MUX before each flip-flop:

  • MUX input 0: feedback from current QiQ_i (hold)
  • MUX input 1: external DiD_i (load)
  • MUX select: LoadLoad

Register with load enable

Figure 3.5: 4-bit register with load-enable using MUX feedback.

Verify:

  • Load=1Load=1: outputs update on clock edge.
  • Load=0Load=0: outputs hold their values across clock edges.

Add a global reset signal ResetReset and connect it to the clear/reset pins of all flip-flops.

Register with async reset

Figure 3.6: 4-bit register with asynchronous reset.

Verify that toggling ResetReset clears outputs to 0000 immediately, even without a clock edge.

  • Circuit screenshots.
  • Verification screenshots + brief analysis for:
    1. Write: Load=1Load=1 writes on clock edge.
    2. Hold: Load=0Load=0 holds across edges.
    3. Reset: ResetReset clears immediately.
  1. To extend this to an 8-bit register, what changes are required (flip-flop count, MUX count, I/O widths, etc.)?
  2. When Load=0Load=0, why is the value “locked” in the register? Explain using the MUX feedback path.
  3. Where does the “asynchronous” nature of async reset show up? How would you implement a synchronous reset?