The IEEE Std. 1364.1(E):2002 (IEC 624142(E):2005), the Verilog register transfer level synthesis standard, states in Sec. 5.1 that an always block without any posedge
/negedge
events in the sensitivity list is combinational logic. I.e. the signals in the event list are ignored and the block is synthesized as if an implicit expression list (@(*)
, @*
) was used. The following example is given in the standard ("Example 4" on page 14):
always @ (in)
if (ena)
out = in;
else
out = 1’b1;
// Supported, but simulation mismatch might occur.
// To assure the simulation will match the synthesized logic, add ena
// to the event list so the event list reads: always @ (in or ena)
(the comment is also copied from the standard document)
I.e. for a synthesis tool your second block is effectively:
always @*
begin
case(CLK)
1'b1:
state <= next_state;
1'b0:
state <= state;
end
which is just a multiplexer with CLK
as select input, next_state
as active-1 input and the output (state
) fed back as active-0 input. A smart synthesis tool might detect that this is identical to a d-type latch with CLK
as enable-input and create a d-type latch instead of a combinational loop. Note that the synthesis tool is not required to detect this latch because the code explicitly assigns state
in all branches (compare Sec. 5.3. of the standard).
Either way this is different from the d-type flip-flop your first code example would synthesize to. This is one of many cases where Verilog-code has different meaning in simulation and synthesis. Therefore it is important to (1) write synthesizeable Verilog code in a way that avoids this cases and (2) always run post-synthesis simulations of your design (even if you are also using formal verification!) to make sure you have successfully avoided this pitfalls.