In our previous blog, we talked about the procedural assignment in Verilog. These are almost the same in System Verilog, so let’s discuss that in this blog.
Procedural assignments come in the form of procedural blocks like “always”, “initial,” “task,” and “function.”
To regulate when assignments are assessed and/or assigned, event controls, delay controls, if…else statements, case statements, looping statements, and so on can all be utilized.
Any expression that evaluates a value can be used as the RHS of the procedural assignment. However, keep in mind that the assignment’s LHS may limit what is a permitted expression on the RHS.
The LHS can be a solitary variable, an aggregate variable, a bit-select, a part-select, a packed array slice, or an unpacked array slice.
Procedural assignments are classified into the following categories:
- Blocking assignment
- Non-blocking assignment
The operator ” =” is the most basic form of assignment. But in this blog, we will introduce you to other operators such as +=, =, e.t.c.
Blocking assignment
Throughout this blog, we’ve seen blocking assignments. As a result, we shall desist from further debate. Non-blocking is a new concept, and we must distinguish between the two. So we will shortly discuss the blocking assignment.
Blocking assignment statements are executed in sequential order. The execution of the following statement is halted until the current assignment operation is completed.
So let’s understand blocking assignments with an example.
module blocking_assignment; //variables declaration int a,b; initial begin $display("-----------------------------------------------------------------"); //initializing a and b a = 10; b = 15; //displaying initial value of a and b $display("\tBefore Assignment :: Value of a is %0d",a); $display("\tBefore Assignment :: Value of b is %0d",b); a = b; b = 20; $display("\tAfter Assignment :: Value of a is %0d",a); $display("\tAfter Assignment :: Value of b is %0d",b); $display("-----------------------------------------------------------------"); end endmodule
Figure 1 shows the output of the above code of blocking assignment.
Fig 1 Blocking assignment output
Non-blocking assignment
The non-blocking assignment permits assignment schedule without interfering with the flow of the procedure.
The non-blocking procedural assignment statement can be used when many variable assignments can be made within the same time step without regard for order or dependency on each other.
Non-blocking syntax is:
variable_name <= [delay_or_event_control] expression.
The non-blocking assignment operator is <=. The non-blocking assignment operator is the same as the relational operator less-than-or-equal-to.
However, non-blocking is determined by the context in which it appears.
Non-blocking execution may be divided into two steps:
1. At the start of the time step, evaluate the RHS of the non-blocking statement.
2. After the time step, evaluate the LHS of the non-blocking statement.
Consider the following example. We’ll compare blocking to non-blocking:
module nblock; logic a, b, c, d, e, f, temp; initial begin a = 0; b = 1; //Blocking assignment a = b; c = a; $display($stime,,, "Blocking a=%b b=%b c=%b", a, b, c); end initial begin d = 0; e = 1; //Non-Blocking assignment d <= e; f <= d; $monitor($stime,,, "Non-blocking d=%b e=%b f=%b", d, e, f); end initial begin #10; d = 0; e = 1; //Following is the same as non-blocking. temp = e; f = d; d = temp; $display($stime,,, "Using temp d=%b e=%b f=%b", d, e, f); end endmodule
The above code will compare blocking and non-blocking assignments and their output is shown in figure 2.
Fig 2: Blocking and Non-blocking example output
Let me explain this code for more explanation.
There are three “initial” blocks. The first is a blocking assignment:
a = b;
c = a;
With this assignment, “b” is allocated to “a,” and the new value of “a” is assigned to “c.” As a result, the new value of “a” (from a = b) is given to “c” (c = a). Because a = 0 and b = 1, a = b results in a = 1, and c = a results in c = 1.
As a result, the following appears in the simulation log:
0 Blocking a=1 b=1 c=1
The non-blocking assignment, on the other hand, operates as follows: Consider two flops linked in series:
d <= e;
f <= d;
Because they are non-blocking, the two assignments run concurrently. The first assignment does not prevent the second task from being completed. The current value of “e” is assigned to “d,” and the current value (before the assignment d = e) of “d” is assigned to “f.”
With d = 0 and e = 1, the simulation log shows the following:
0 Non-blocking d=1 e=1 f=0
Consider the preceding non-blocking as the extended version:
e = temp;
f = d;
d = temp;
When d = 0 and e = 1, the current value of “e” (= 1) is stored in the temp variable (temp = 1). The current “d” (= 0) value is then allocated to “f” (f = d). As a result, f = 0, and the value of “e” saved in “temp” is assigned to “d.” So, d = 1.
As a result, the simulation log displays the following:
10 Using temp d=1 e=1 f=0
It should be noted that this is the same outcome as a non-blocking assignment:
So, using a simple and effective example, we can quickly grasp the concept of blocking and non-blocking assignments.
As a result, we summarise the entire blog with a few questions.
- What exactly do you mean when you say “procedural assignment”?
- How many different kinds of procedural assignments are there?
- What exactly is a blocking assignment?
- How does a non-blocking assignment differ from a blocking statement?