# Simulation of blocking assignments in always @ blocks

Tracking down some weird simulation results, I found that the use of blocking assignments at clock edges was the culprit. More specifically, different simulators seem to treat them differently.

Take the following example:

module test;

reg clk, foo, bar;

initial
begin
clk = 0;
foo = 0;
bar = 0;
#10 \$finish;
end

always
#1 clk = ~clk;

always @(posedge clk)
foo = ~foo;

always @(posedge clk)
bar <= foo;

endmodule


Running this in Xilinx' ISim gives the following waveform:

This seems reasonable although I do find it a bit strange that a change in foo at a clock edge gets picked up by bar at the same clock edge.

The following waveform is produced by running the same example using Icarus Verilog:

This seems completely wrong to me. A change in foo from 0 to 1 is not picked up by bar at the same clock edge. However, a change in foo from 1 to 0 does get picked up by bar at the same clock edge (otherwise bar would change to 1 at the second positive clock edge I suppose).

So, I have two questions:

1. Which, if any, of these simulators is correct? In other words, how should the above code behave?
2. Are differences between simulators something we should always be aware of? If so, are there any guidelines on writing code that is deterministic across different simulators?

Note: I'm aware of the fact that using blocking assignments in always @ blocks is not a good idea and that using a non-blocking assignment in my example gives logical and consistent results. I'm asking this question because I'm currently debugging some third-party simulation code.