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?
I would like to ask three questions about blocking & non-blocking assignment.
The first question is that How the blocking and non-blocking statement works when they are combined.
following the book "FPGA_Prototyping_By_Verilog_Examples" it says that
When an always block is activated, the right-hand-side expressions of nonblocking assignments are evaluated at the beginning of the time step.
Based on the above statement about a non-blocking statement, I've expected that the below always block would require two clocks for assigning value of a&b to the q0, but the book says it can do it in one clock cycle.
At the first glance, I've thought that the value of ab0 (RHS of non-blocking assignment) will be stored in somewhere before the always block is executed and to be used in the q0 <= ab0;. Therefore, I assumed that the value of ab0 will be estimated at the first clock cycle and the estimated value of ab0 will be assigned to the q0 in the second rising edge of the clock.
So my question is, when the value of RHS of non-blocking statements are decided when they are used with the blocking statements. If it is determined regardless of the blocking statement please let me know.
The second questions is How the non-blocking and blocking statements affects the real hardware?
I've read many articles that say the nonblocking and blocking assignments do not have any effect on the synthesis, but only regards to the simulation. If it is just about the simulation, How the hardware really works to executed instructions inside always block? Does it sequentially execute the instructions one by one like the C code?
As far as I know the ground rule is
- use the non-blocking assignment in the sequential circuit.
- use the blocking assignment in the cobinational circuit.
However, it seems that using the non-blocking assignment in the combinational circuit and blocking assignment in the sequential circuit are all legitimate and allowed or even mixed!!!
So, my last question is What is the advantage of mixing two assignments or what kind of cases are there to use non-blocking assignment in the combinational circuit and blocking assignment in sequential circuit?