Always block
An always block is a procedural block that runs whenever its sensitivity condition is triggered.
It is used to describe either combinational logic or sequential (clocked) logic.
General form
always @(sensitivity_list) begin
// procedural statements
endIn SystemVerilog, prefer:
always_combfor combinational logicalways_fffor flip-flop logic
Combinational always
Use always @(*) (or always_comb) so the block reevaluates when any input changes.
always @(*) begin
y = (a & b) | c;
endGuidelines:
- Include default assignments to avoid inferred latches.
- Use blocking assignment
=in combinational blocks.
Sequential (clocked) always
Use edge-triggered sensitivity for registers.
always @(posedge clk) begin
q <= d;
endWith asynchronous reset:
always @(posedge clk or posedge rst) begin
if (rst)
q <= 1'b0;
else
q <= d;
endGuidelines:
- Use non-blocking assignment
<=in clocked blocks. - Keep one clock domain per block.
Typical pitfalls
- Missing signals in a manual sensitivity list (
always @(a or b)) can cause simulation/synthesis mismatch. - Missing
else/default branches in combinational blocks can infer latches unintentionally. - Mixing blocking and non-blocking assignments in the same sequential block is error-prone.
Rule of thumb
- Combinational logic:
always @(*)+= - Sequential logic:
always @(posedge/negedge clk)+<=
See also Non-Blocking and Blocking Assignments.