always @(*) and the Default-at-Top Pattern
How always @(*) describes combinational logic, and why the default-assignment-at-top pattern is the single most important habit for avoiding an accidental latch.
Updated 2026-07-07
always @(*) describes pure combinational logic: the block re-evaluates its body whenever any signal it reads changes. Unlike a program, it does not run once top-to-bottom — it describes a piece of hardware that reacts continuously.
Every output the block can produce must be assigned on every possible path through the block. If a path exists where an output is never assigned, the synthesizer has no choice but to hold the last known value on that output — which means adding storage (a latch) you never asked for.
The reliable fix is the default-assignment-at-top pattern: assign every output a known default value as the very first statement inside the block, before any if or case. Later branches can override that default, but every path is now guaranteed to leave the output with a value. This one habit, applied consistently, prevents almost every accidental latch in combinational Verilog.