Reputation: 15
I know that an always block will be trigger on a change in any of the elements in its sensitivity list however, my question is what happens if a change in sensitivity list happens while the statements inside the always blocks are still being executed (due to a previous trigger). Does the always block begin execution again in a parallel thread or is triggering blocked until execution finishes first?
Upvotes: 1
Views: 3133
Reputation: 42698
Many people do not realize that @ is a statement modifier, not construct by itself. It says to delay the statement that follows until there is an event. @(A or B)
means wait until there is a change in the value of A or B (not to be confused with a change in the result of A|B). @*
means look at the statement that follows, and build an implicit sensitivity list of signals to wait for a change.
always @(A or B) C = A + B;
always begin
@(A or B) C = A + B;
end
always begin
@* C = A + B;
end
always_comb
begin
C = A + B;
end
These 4 always
blocks have identical behavior with the exception of the last always_comb
also triggers at time 0 regardless of any change on A or B.
If you look at the code that follows the always
as a procedural sequence of executing statements, it might be easier to see the @
construct as part of that procedural sequence, and the change has to occur while you are executing the construct. Just adding another delay will show this concept (not synthesizable)
always @(A or B) begin
#10 C = A + B;
end
This says "wait for a change on A or B, then wait 10 more time units, then make an assignment to C with the current values of A + B". If A or B changes during the 10 time unit wait, that change is missed. You have to wait for another change on A or B after those 10 time units.
Upvotes: 4
Reputation: 12354
As soon as an always block is triggered, it will be executed from the beginning to the end. Verilog is a single-thread simulation engine, therefore only one block can be executed at a time. Nothing else could happen while an always block is executed, unless it contains delay statements or waits on events. In the latter case it will just yield to allow other blocks to being executed, then it continues.
If an always block changes its inputs by the end of the execution, then next simulation behavior depends on the type of the block:
With v2k/v95 always blocks you can end up with a zero-delay loop if you are not careful. In other words simulation can hang.
With SystemVerilog blocks you can get an interesting read-before-write condition (when a variable is read before it is written in the same block). This can potentially create simulation/synthesis mismatch.
Upvotes: 1
Reputation: 13967
Each always block is a single thread (unless it contains a fork
-join
). So, if it's executing, it won't retrigger if something in the sensitivity list changes. (If it does contain a fork
-join
then it splits into multiple threads once triggered, but again won't retrigger).
Upvotes: 1