The term Blocking assignment confuses people because the word blocking would seem to suggest time-sequential logic. But in synthesized logic it does not mean this, because everything operates in parallel.
Perhaps a less confusing term would be immediate assignment, which would still differentiate the intermediate results of combinational logic from the inputs to non-transparent memory elements (for example clocked registers), which can have delayed assignment.
From a legalistic standpoint, it all works out very nicely. You can, in fact, consider the to be a blocking (time-sequential) operation even within sequences. However, the distinction between time-sequential and parallel makes absolutely no difference in this case because the block is defined to repeat until the instruction sequence converges on a stable state -- which is exactly what the hardware circuitry will do (if it meets the timing requirements).
The synthesizable subset of Verilog (and especially SystemVerilog) is extremely simple and easy to use -- once you know the necessary idioms. You just have to get past the clever use of terminology associated with the so-called behavioral elements in the language.
answered Jan 10 '15 at 19:49
I'm implementing a simple serializer in Verilog, but I do not understand the nuances of when blocking assigns can cause problems. I'm specifically having trouble understanding part of this answer. "However, you should never use blocking assignments for synchronous communication, as this is nondeterministic."
I'm building a block that takes, as an input:
- A bit clock
- A 5-bit parallel data input (the value to be serialized)
- A "Data valid" signal that indicates valid 5-bit data is present
As an output, I have:
- Serial data out
- A "Complete" signal that indicates it's time for a new 5-bit value
- A "Transmitting" signal that's high whenever there's valid serial data going out on the bus
Whenever data valid goes high, the block starts outputting the 5-bit value, one bit a time, starting at the next rising edge of the bit clock. When the last bit is out on the wire, the block signals "complete" so a new 5-bit value can be made available.
Omitting some of the reset logic, the code to do this looks like this:
Now, I can write the block with all non-blocking assigns, but I feel that it hurts readability. That would look something like this:
Both appear to do what I want in simulation, and I favor the 1st one because it's easier for me to read but since I don't understand why using blocking assignments for synchronous communication is nondeterministic, I'm worried that I've coded up a ticking time bomb
The Question: Am I doing something wrong in the 1st code that's going to blow up when I try to synthesize this? Is the 2nd code preferable despite being a bit harder (for me anyway) to read? Is there some 3rd thing I should be doing?