Always @(*) vs always @(posedge clk) in Verilog: Key Differences
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.
| Aspect | always @(*) | always @(posedge clk) |
|---|---|---|
| Type of logic | Combinational logic | Sequential (clocked) logic |
| Trigger condition | Any change in inputs (sensitivity list auto) | Rising edge of clock signal |
| Timing | Immediate update when inputs change | Updates only on clock edge |
| Use case | Logic without memory (e.g., gates, muxes) | Flip-flops, registers, counters |
| Sensitivity list | Automatically includes all inputs | Only clock signal specified |
| Risk of latches | Possible if not all outputs assigned | No 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
module combinational_example(
input wire a,
input wire b,
output reg y
);
always @(*) begin
y = a & b; // AND gate behavior
end
endmodulealways @(posedge clk) Equivalent
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
endmoduleWhen 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.always @(*) to model immediate logic without memory.always @(posedge clk) to model clocked storage elements.