Verilog had no non-blocking assignments (NBAs) until some years after the language was first used (even the second edition of Thomas and Moorby's The Verilog Hardware Description Language, for example, doesn't mention them). This has, over time, lead to a great deal of confusion, and a great deal of code that suffers from race conditions. To avoid race conditions, you'll need to use a methodology that correctly uses non-blocking assignments. A simple rule-of-thumb is:
-
In an always block that generates sequential (clocked) logic, use
non-blocking assignments (
<=
). However, this isn't the full story: see 'Sanity testing' for an example of a clocked process that misbehaves when an NBA is used instead of a blocking assignment -
In an always block that generates combinatorial logic, use blocking
assignments (plain
=
)
If you want (a lot) more detail, see the paper by Cliff Cummings. Note that VHDL doesn't have this problem, as variable assignments are blocking, while signal assignments are non-blocking.