Sequential Logic and the D Flip-Flop

Sequential logic has memory: its output depends on the present inputs and on past inputs, held as state. The element that stores that state, synchronised to a clock, is the flip-flop. Where combinational logic computes, sequential logic remembers — and almost every real design is layers of combinational logic clocked between flip-flops.

The D flip-flop

A D flip-flop captures the value on its D input at the active clock edge and holds it until the next edge. In Verilog it is an always @(posedge clk) block with a non-blocking assignment. Add an asynchronous reset and you have the workhorse storage element of synchronous design:

module dff(input clk, rst_n, d, output reg q);
  always @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 1'b0;   // async active-low reset
    else        q <= d;      // capture D on rising edge
endmodule

module tb;
  reg clk=0, rst_n=0, d=0;
  wire q;
  dff u(clk, rst_n, d, q);
  always #5 clk = ~clk;      // 100 MHz
  initial begin
    #3 rst_n = 1;            // release reset
    d = 1; @(posedge clk); #1 $display("t=%0t after edge: d=%b q=%b", $time, d, q);
    d = 0; @(posedge clk); #1 $display("t=%0t after edge: d=%b q=%b", $time, d, q);
    d = 1; @(posedge clk); #1 $display("t=%0t after edge: d=%b q=%b", $time, d, q);
    $display("q follows d, delayed by one clock");
    $finish;
  end
endmodule
t=6 after edge: d=1 q=1
t=16 after edge: d=0 q=0
t=26 after edge: d=1 q=1
q follows d, delayed by one clock

The output q takes the value d had just before each rising edge — it is “d delayed by one clock”. Chaining flip-flops this way builds shift registers, counters and the pipeline stages inside every processor.

Check yourself

What is the difference between a latch and a flip-flop?

A level-sensitive latch is transparent whenever its enable is active — the output tracks the input the whole time. An edge-triggered flip-flop samples its input only at the clock edge and holds it otherwise. Synchronous design uses flip-flops; unintended latches are a common bug.

Why use a non-blocking assignment (<=) inside a clocked always block?

Non-blocking assignments all sample their right-hand sides at the edge and update together, which models real flip-flops updating simultaneously and avoids race conditions between registers in simulation. Blocking (=) would create order-dependent, hardware-mismatched behaviour.

Have questions about this topic?
Share your question in comments or talk to our mentor team for batch guidance.
▶ Try it in the ChipXpert Lab

Open this design in the free in-browser simulator — edit, compile and see the waveform/log instantly.

Run it in the Lab

Learn Verilog with mentors, labs and placement support

This free series is maintained by the ChipXpert training team in Hyderabad & Bengaluru. Go deeper with instructor-led courses on real EDA tools.

Explore VLSI Courses
Next batch starts 18th November 2026
Start your VLSI career with ChipXpert

Live online and classroom batches in Hyderabad & Bengaluru. Fill in your details and a counsellor will call you back.

  • Real EDA tools in your browser: industry-standard EDAReal EDA tools in your browser
  • Recorded sessions on the elearn portalRecorded sessions
  • Placement assistance: resume, mock interviewsPlacement assistance
  • Merit scholarship up to 60% · EMI optionsScholarship up to 60%
Hi! Ask me about courses, fees, batches or discounts. ×
BENGALURU
HYDERABAD