0
0
VerilogComparisonBeginner · 3 min read

Always @(*) vs always @(posedge clk) in Verilog: Key Differences

In Verilog, always @(*) is used for combinational logic and triggers whenever any input changes, while always @(posedge clk) is used for sequential logic and triggers only on the rising edge of the clock signal. The first models logic that updates immediately with inputs, the second models logic that updates synchronized to a clock.
⚖️

Quick Comparison

This table summarizes the main differences between always @(*) and always @(posedge clk) in Verilog.

Aspectalways @(*)always @(posedge clk)
Type of logicCombinational logicSequential (clocked) logic
Trigger conditionAny change in inputs (sensitivity list auto)Rising edge of clock signal
TimingImmediate update when inputs changeUpdates only on clock edge
Use caseLogic without memory (e.g., gates, muxes)Flip-flops, registers, counters
Sensitivity listAutomatically includes all inputsOnly clock signal specified
Risk of latchesPossible if not all outputs assignedNo latches, state stored in registers
⚖️

Key Differences

always @(*) is designed for combinational logic blocks. It automatically includes all input signals in its sensitivity list, so the block runs whenever any input changes. This means outputs update immediately to reflect input changes, modeling logic like gates or multiplexers without memory.

In contrast, always @(posedge clk) models sequential logic that updates only on the rising edge of a clock signal. This means the block runs once per clock cycle, storing state in registers or flip-flops. It is used to build counters, state machines, and other memory elements.

Using always @(*) incorrectly can cause unintended latches if outputs are not assigned in all cases, while always @(posedge clk) inherently stores state and avoids latches. The choice depends on whether you want immediate combinational behavior or clocked sequential behavior.

⚖️

Code Comparison

verilog
module combinational_example(
    input wire a,
    input wire b,
    output reg y
);

    always @(*) begin
        y = a & b; // AND gate behavior
    end

endmodule
Output
Output y is the AND of inputs a and b, updated immediately when a or b changes.
↔️

always @(posedge clk) Equivalent

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

    always @(posedge clk) begin
        if (reset)
            q <= 0;
        else
            q <= d; // Store input d on clock rising edge
    end

endmodule
Output
Output q updates to input d only on the rising edge of clk, storing state.
🎯

When to Use Which

Choose always @(*) when you need combinational logic that reacts immediately to input changes without storing state, such as simple gates, multiplexers, or combinational functions.

Choose always @(posedge clk) when you need sequential logic that updates synchronously with a clock, such as registers, counters, or state machines that store and remember values across clock cycles.

Using the correct type ensures your design behaves as intended and avoids unintended latches or timing issues.

Key Takeaways

always @(*) is for combinational logic triggered by any input change.
always @(posedge clk) is for sequential logic triggered on clock rising edge.
Use always @(*) to model immediate logic without memory.
Use always @(posedge clk) to model clocked storage elements.
Choosing the right block prevents unintended latches and timing errors.