keysymbols: =, <=.
With blocking assignments each statement in the same time frame is executed in sequential order within their blocks. If there is a time delay in one line then the next statement will not be executed until this delay is over.
integer a,b,c,d; initial begin a = 4; b = 3; example 1 #10 c = 18; #5 d = 7; end
Above, at time=0 both a and b will have 4 and 3 assigned to them respectively and at time=10, c will equal 18 and at time=15, d will equal 7.
Non-Blocking assignments tackle the procedure of assigning values to variables in a totally different way. Instead of executing each statement as they are found, the right-hand side variables of all non-blocking statements are read and stored in temporary memory locations. When they have all been read, the left-hand side variables will be determined. They are non-blocking because they allow the execution of other events to occur in the block even if there are time delays set.
integer a,b,c; initial begin a = 67; #10; a <= 4; example 2 c <= #15 a; d <= #10 9; b <= 3; end
This example sets a=67 then waits for a count of 10. Then the right-hand variables are read and stored in tempory memory locations. Here this is a=67. Then the left-hand variables are set. At time=10 a and b will be set to 4 and 3. Then at time=20 d=9. Finally at time=25, c=a which was 67, therefore c=67.
Note that d is set before c. This is because the four statements for setting a-d are performed at the same time. Variable d is not waiting for variable c to complete its task. This is similar to a Parallel Block.
This example has used both blocking and non-blocking statements. The blocking statement could be non-blocking, but this method saves on simulator memory and will not have as large a performance drain.
We have already seen that non-blocking assignments can be used to enable variables to be set anywhere in time without worrying what the previous statements are going to do.
Another important use of the non-blocking assignment is to prevent race conditions. If the programmer wishes two variables to swap their values and blocking operators are used, the output is not what is expected:
initial begin x = 5; y = 3; end example 3 always @(negedge clock) begin x = y; y = x; end
This will give both x and y the same value. If the circuit was to be built a race condition has been entered which is unstable. The compliler will give a stable output, however this is not the output expected. The simulator assigns x the value of 3 and then y is then assigned x. As x is now 3, y will not change its value. If the non-blocking operator is used instead:
always @(negedge) begin x <= y; example 4 y <= x; end
both the values of x and y are stored first. Then x is assigned the old value of y (3) and y is then assigned the old value of x (5).
Another example when the non-blocking operator has to be used is when a variable is being set to a new value which involves its old value.
i <= i+1; or examples 5,6 register[5:0] <= {register[4:0] , new_bit};