0
0
VerilogHow-ToBeginner · 4 min read

How to Use Always Block in Verilog: Syntax and Examples

In Verilog, the always block is used to describe behavior that should run repeatedly whenever specified signals change. It contains procedural code that executes on events like clock edges or signal changes, making it essential for modeling sequential and combinational logic.
📐

Syntax

The always block starts with the keyword always followed by an event control in parentheses, then a block of code enclosed in begin and end. The event control defines when the block runs, such as on a clock edge or any change in signals.

  • always @(posedge clk): Runs on the rising edge of the clock signal.
  • always @(negedge reset): Runs on the falling edge of the reset signal.
  • always @(*): Runs whenever any signal in the block changes (used for combinational logic).
verilog
always @(posedge clk) begin
    // code to run on clock rising edge
end
💻

Example

This example shows a simple flip-flop that stores a bit on the rising edge of a clock and resets asynchronously.

verilog
module d_flip_flop(
    input wire clk,
    input wire reset,
    input wire d,
    output reg q
);

always @(posedge clk or posedge reset) begin
    if (reset) begin
        q <= 0;
    end else begin
        q <= d;
    end
end

endmodule
⚠️

Common Pitfalls

Common mistakes when using always blocks include:

  • Forgetting to include all signals in the sensitivity list for combinational logic, causing simulation mismatches.
  • Using blocking assignments (=) instead of non-blocking (<=) in sequential logic, which can cause timing errors.
  • Mixing combinational and sequential logic in the same always block, leading to unintended latches or glitches.
verilog
/* Wrong: Missing signals in sensitivity list */
always @(a) begin
    y = a & b; // 'b' missing in sensitivity list
end

/* Right: Use @(*) for combinational logic */
always @(*) begin
    y = a & b;
end
📊

Quick Reference

UsageDescriptionExample
Sequential LogicRuns on clock edges for flip-flopsalways @(posedge clk) begin ... end
Asynchronous ResetRuns on reset signal edgesalways @(posedge clk or posedge reset) begin ... end
Combinational LogicRuns whenever inputs changealways @(*) begin ... end
Blocking AssignmentUse for combinational logica = b + c;
Non-blocking AssignmentUse for sequential logicq <= d;

Key Takeaways

Use always blocks to describe behavior triggered by signal changes or clock edges.
Use @(posedge clk) for sequential logic and @(*) for combinational logic.
Always include all relevant signals in the sensitivity list or use @(*) to avoid simulation mismatches.
Use non-blocking assignments (<=) inside sequential always blocks to model flip-flops correctly.
Avoid mixing combinational and sequential logic in the same always block to prevent unintended behavior.