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
endmodulet=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.
Share your question in comments or talk to our mentor team for batch guidance.
Open this design in the free in-browser simulator — edit, compile and see the waveform/log instantly.
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