The sensitivity list in an always block tells the simulator when to start evaluation of the block. The always block itself evaluates expressions which it contains. Expressions essentially have operands and results. Excluding intermediate results, the always block has inputs, constituted with the non-intermediate operands.
So, the sensitivity lists describe events relevant to the block inputs. But there is always a possibility that it does not list all of the inputs. In such a case the block might not behave as expected. For example
always @(a)
c = a & b;
in the above example the always block will evaluated only if the a
value changes. But what if b
changes? In such a case c
will still contain the value of the previous evaluation and the block behaves as a latch. Synthesis will be not generate a latch though and you have a problem.
v2k introduced always @*
(same as always @(*)
). It requires a simulator to figure out all inputs of the always block and build an internal sensitivity list out of all the inputs. So, in the following example value of c
will be evaluated if any of a
or b
changes:
always @*
c = a & b;
in system verilog always_comb
and always_latch
work the same way but do not require use of @*
. The following is equivalent to the previous example.
always_comb
c = a & b;