Blocking and Non-Blocking Assignment

keysymbols: =, <=.

Blocking (the = operator)

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 (the <= operator)


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.

Application of Non-Blocking Assignments:

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};

No comments:

Post a Comment

Please provide valuable comments and suggestions for our motivation...

Popular Posts