In reply to dave_59:
In reply to bdreku:
Program blocks do not elimnate all race conditions and I do not recommend using them.
In reply to hemaja:
A race condition in SystemVerilog is a simulation modeling artifact where the order of execution between two different constructs cannot be guaranteed. The most common race condition is when there are multiple processes reading and writing the same variable synchronized to the same event region (like the edge of a clock). SystemVerilog does not guarantee the order of execution between the reading and writing, so there is no way to know if the “read” captures the old or the new value of that variable. (bdreku, this can happen just as easily within a program block or module)
The solution to this problem is to move either the reading or writing of that variable to a different event region. The most common way to do this is to use a non-blocking assignment (q <= d)for the writing of that variable. That postpones actual update of that variable to a later region. Now all the other process that try to read that variable in the current event region are guaranteed to the “old” value of that variable regardless of the writing process executes before or after the reading process. This technique is the way Verilog RTL designers have been coding for years, and works equally as well for testbench verification.
Testbench writers have a few other options, including using a different event for writing and reading (like the inverse edge of the clock), and clocking blocks to offset the reading and writing from a synchronous clock edge.
Real hardware does not have the same kind of problem with race conditions. Propagation delays through registers usually prevent simultaneous reading and writing, but physical issues like clock skew and setup/hold requirements can produce timing problems where it is difficult to predict reading the old or new value of a signal.
Hi Dave,
Can you give more detail on the later region in which update is done when doing non-blocking write ?