EXAMPLES

Real, working Verilog & SystemVerilog code

No teaching prose, no Q&A — just correct, idiomatic code you can read, copy, and adapt for your own designs or simulations.

Looking for something else? Tutorials explain concepts with prose and code together. Guides cover a topic in reference depth with no code. RTL Design Questions test your understanding of these patterns.

D Flip-Flop with Synchronous Reset

The most basic sequential element in RTL design.

module dff_sync_reset (
    input  wire clk,
    input  wire rst_n,
    input  wire d,
    output reg  q
);
    always @(posedge clk) begin
        if (!rst_n)
            q <= 1'b0;
        else
            q <= d;
    end
endmodule

4-bit Synchronous Counter

A counter with synchronous reset and an enable signal.

module counter_4bit (
    input  wire clk, rst_n, en,
    output reg [3:0] count
);
    always @(posedge clk) begin
        if (!rst_n)
            count <= 4'b0000;
        else if (en)
            count <= count + 1'b1;
    end
endmodule

Simple Synchronous FIFO

A basic single-clock FIFO with full/empty flags — the design most often asked about in RTL interviews.

module sync_fifo #(
    parameter DEPTH = 8,
    parameter WIDTH = 8
)(
    input  wire clk, rst_n,
    input  wire wr_en, rd_en,
    input  wire [WIDTH-1:0] din,
    output reg  [WIDTH-1:0] dout,
    output wire full, empty
);
    reg [WIDTH-1:0] mem [0:DEPTH-1];
    reg [$clog2(DEPTH):0] wr_ptr, rd_ptr;

    assign full  = (wr_ptr - rd_ptr) == DEPTH;
    assign empty = (wr_ptr == rd_ptr);

    always @(posedge clk) begin
        if (!rst_n) begin
            wr_ptr <= 0; rd_ptr <= 0;
        end else begin
            if (wr_en && !full) begin
                mem[wr_ptr[$clog2(DEPTH)-1:0]] <= din;
                wr_ptr <= wr_ptr + 1;
            end
            if (rd_en && !empty) begin
                dout <= mem[rd_ptr[$clog2(DEPTH)-1:0]];
                rd_ptr <= rd_ptr + 1;
            end
        end
    end
endmodule

Two-Flop CDC Synchronizer

The standard pattern for safely bringing a single-bit asynchronous signal into a new clock domain.

module sync_2ff (
    input  wire clk_dst, rst_n,
    input  wire async_in,
    output reg  sync_out
);
    reg meta;
    always @(posedge clk_dst) begin
        if (!rst_n) begin
            meta <= 1'b0; sync_out <= 1'b0;
        end else begin
            meta     <= async_in;
            sync_out <= meta;
        end
    end
endmodule
// Never synchronize a multi-bit bus this way —
// use a handshake or a FIFO instead.

Moore FSM: Traffic Light Controller

A classic Moore machine, where output depends only on the current state.

module traffic_light (
    input  wire clk, rst_n,
    output reg [1:0] light // 00=Red 01=Green 10=Yellow
);
    localparam RED=2'b00, GREEN=2'b01, YELLOW=2'b10;
    reg [1:0] state;
    reg [3:0] timer;

    always @(posedge clk) begin
        if (!rst_n) begin state <= RED; timer <= 0; end
        else begin
            timer <= timer + 1;
            case (state)
                RED:    if (timer==9) begin state<=GREEN;  timer<=0; end
                GREEN:  if (timer==7) begin state<=YELLOW; timer<=0; end
                YELLOW: if (timer==2) begin state<=RED;    timer<=0; end
            endcase
        end
    end
    always @(*) light = state;
endmodule

UVM Sequence Item

A minimal randomizable transaction class — the basic unit of stimulus in a UVM testbench.

class my_seq_item extends uvm_sequence_item;
    rand bit [7:0] addr;
    rand bit [7:0] data;
    rand bit       write;

    `uvm_object_utils_begin(my_seq_item)
        `uvm_field_int(addr,  UVM_ALL_ON)
        `uvm_field_int(data,  UVM_ALL_ON)
        `uvm_field_int(write, UVM_ALL_ON)
    `uvm_object_utils_end

    function new(string name = "my_seq_item");
        super.new(name);
    endfunction
endclass

Want the concepts behind this code?

Our tutorials explain the reasoning, not just the syntax.

See tutorials