Loading header...

Sequential Logic in Verilog

Sequential logic remembers state. In an FPGA, that usually means flip-flops updated by a clock edge. This is where FPGA design begins to feel very different from ordinary programming: many registers update at the same instant.

Learning Objectives

You will learn to:

  • write clocked logic in Verilog;
  • distinguish combinational and sequential assignments;
  • use enables and resets deliberately;
  • understand why synchronous design is the default FPGA style.

Clocked Registers

always @(posedge clk) begin
    q <= d;
end

This describes a flip-flop. On each active clock edge, q captures d.

Nonblocking Assignment

Inside clocked Verilog blocks, use nonblocking assignment:

q <= d;

Think of all registers in the block sampling first, then updating together. This matches flip-flop behavior.

Counter Example

module counter8 (
    input  wire       clk,
    input  wire       rst,
    input  wire       en,
    output reg  [7:0] count
);
    always @(posedge clk) begin
        if (rst) begin
            count <= 8'd0;
        end else if (en) begin
            count <= count + 8'd1;
        end
    end
endmodule

Reset Choices

Reset type Description Beginner guidance
Synchronous reset reset checked on clock edge easiest for timing and most FPGA flows
Asynchronous reset reset can affect register without clock useful but must be released carefully
No reset register powers up by configuration/init or is flushed by protocol common in datapaths after you know why

Do not reset every register by reflex. Control registers usually need known startup states. Large datapaths often do not.

Worked Example: Edge Detector

To detect a rising edge, store the previous input and compare it with the current synchronized input.

reg signal_d;
wire rising_edge_seen;

always @(posedge clk) begin
    signal_d <= signal;
end

assign rising_edge_seen = signal & ~signal_d;

This creates a one-clock pulse when signal changes from 0 to 1, assuming signal is already in the same clock domain.

title "Illustrative one-clock edge detector"
time start=0 end=10 unit=cycles divisions=10

CLK: square label="clk" low=0 high=1 duty=50 cycles=5 unit=logic color=#2563eb
SIG: step label="signal" low=0 high=1 at=3 unit=logic color=#dc2626
PULSE: pulse label="rising_edge_seen" low=0 high=1 at=4 width=1 unit=logic color=#16a34a

marker EDGE at=4 label="one clock pulse"

The waveform is illustrative; real timing depends on the clock and implementation.

Exercise

Write a 4-bit counter with:

  • synchronous reset;
  • enable input;
  • output terminal_count, high when the count equals 15.

Then decide whether terminal_count should be combinational or registered and explain the tradeoff.

Common Mistakes

  • Mixing blocking and nonblocking assignments without a reason.
  • Using a signal from another clock domain directly.
  • Creating derived clocks with ordinary logic.
  • Resetting huge datapaths unnecessarily.
  • Forgetting that registers update together, not line by line.

Summary

Sequential logic is built from clocked registers. Use clean clocked blocks, nonblocking assignments, deliberate reset strategy, and synchronization discipline. This is the foundation for counters, state machines, FIFOs, and real FPGA systems.

Next: Finite-State Machines in Verilog.

Further Reading

  • Vendor HDL coding guidelines for synchronous design
  • Clifford Cummings papers on nonblocking assignments and resets
  • Project F FPGA tutorials on counters and clocks

Mind Map

mindmap root((Sequential Verilog)) Core concept Registers update on clock Nonblocking assignments Reset behavior Applications Applications Counters State storage Pipelines Design checks Checks One clock edge Reset test Common mistakes Common mistakes Mixing clocks Blocking in flops