Google+ VLSI QnA: nonblocking assignments
Showing posts with label nonblocking assignments. Show all posts
Showing posts with label nonblocking assignments. Show all posts

Friday, 23 May 2014

Interview Questions on Blocking and Nonblocking Assignments

This post is continuation to our previous post on blocking and non-blocking assignments. For better understanding of how the blocking and nonblocking assignments are scheduled in Verilog, please go through this post.

Q.1) What will be the output of following code?

         module seq;
         reg clk, rst, d;
         initial
         begin
               $monitor("%g clk = %b rst = %b d = %b", $time, clk, rst, d);
               #1   clk = 0;
               #10 rst = 0;
               #5   d = 0;
               #10 $finish;
          end
          endmodule

Answer) 0     clk = x   rst = x   d = x
              1     clk = 0   rst = x   d = x
              11   clk = 0   rst = 0   d = x
              16   clk = 0   rst = 0   d = 0

Q.2) What will be the output of following code?

         module parallel;
         reg clk, rst, d;
         initial
         begin
             $monitor("%g clk = %b rst = %b d = %b", $time, clk, rst, d);
             fork
                   #1   clk = 0;
                   #10  rst = 0;
                   #5   d = 0;
             join
             #1 display("%t Terminating simulation", $time);
         end
         endmodule
(Note : fork-join block causes the statements to be evaluated in parallel, i.e. all at the same time.)

Answer) 0     clk = x    rst = x   d = x
              1     clk = 0    rst = x   d = x
              5     clk = 0    rst = x   d = 0
             10    clk = 0    rst = 0   d = 0
             11    Terminating simulation

Q.3) What will be the output of the following code ?

         blocking                                                                          nonblocking
         always @(i1 or i2)                                                          always @(i1 or i2)
         begin                                                                               begin
                i1 = 1;                                                                              i1 = 1;
                i2 = 2;                                                                              i2 = 2;
                #10;                                                                                 #10;
                i1 = i2;                                                                             i1  <= i2;
                i2 = i1;                                                                             i2  <= i1;
         end                                                                                  end
                      (a)                                                                                   (b)

Answer) In the case of (a), i.e. blocking the values of i1 and i2 will be both '2', whereas in the case of (b) (nonblocking) the values of i1 and i2 will be '2' and '1' respectively.
    

Q.4) What will be the output of the following code ?

         module tp;
                reg i1;
                initial 
                      $monitor("\$monitor: i1 = %b", i1);
                initial 
                begin
                       $strobe ("\$strobe : i1 = %b", i1);
                       i1 = 0;
                       i1 <= 1;
                       $display ("\$display: i1 = %b", i1);
                      #1 $finish;
                end
         endmodule

Answer) $display: i1 = 0
              $monitor: i1 = 1
              $strobe : i1 = 1

Q.5) What will be the output of the following code?

         module tp;
                  reg i1, i2;
                  initial 
                  begin
                           i1 = 0;
                           i2 = 1;
                           i1 <= i2;
                           i2 <= i1;
                           $monitor ("%0dns: \$monitor: i1=%b i2=%b", $stime, i1, i2);
                           $display ("%0dns: \$display: i1=%b i2=%b", $stime, i1, i2);
                           $strobe ("%0dns: \$strobe : i1=%b i2=%b\n", $stime, i1, i2);
                    #0   $display ("%0dns: #0 : i1=%b i2=%b", $stime, i1, i2);
                    #1   $monitor ("%0dns: \$monitor: i1=%b i2=%b", $stime, i1, i2);
                           $display ("%0dns: \$display: i1=%b i2=%b", $stime, i1, i2);
                           $strobe ("%0dns: \$strobe : i1=%b i2=%b\n", $stime, i1, i2);
                           $display ("%0dns: #0 : i1=%b i2=%b", $stime, i1, i2);
                     #1  $finish;
                  end
         endmodule

Answer) 0ns: $display: i1=0 i2=1
              0ns: #0 : i1=0 i2=1
              0ns: $monitor: i1=1 i2=0
              0ns: $strobe : i1=1 i2=0
              1ns: $display: i1=1 i2=0
              1ns: #0 : i1=1 i2=0
              1ns: $monitor: i1=1 i2=0
              1ns: $strobe : i1=1 i2=0

In case of any doubt regarding the above solutions, feel free to leave a comment.

Thursday, 22 May 2014

Verilog "Stratified Event Queue"

Verilog "Stratified Event Queue"


The Verilog event queue is a conceptual model, which helps us understand how various events like blocking assignments, nonblocking assignments function.

According to the Verilog IEEE standard, the Verilog event queue is logically segmented into five different regions.

1) Active Events :
     Events which occur at the current simulation time and can be executed in any order. These include blocking assignments, continuous assignments, $display commands, evaluation of instance and primitive inputs followed by updates of primitive and instance outputs, and the evaluation of nonblocking RHS expressions.

2) Inactive Events.
     Events which are processed after the processing of active events. In this queue, #0 delay assignments are scheduled.

3) Nonblocking assign update events
     Events that were evaluated during previous simulation time, but are assigned at this simulation time after the processing of active and inactive events. It is these queue where the LHS of nonblocking assignment is updated.

4) Monitor Events
    Events that are processed after all the active, inactive and nonblocking assign update events have been processed. This queue contains $monitor and $strobe assignments.

5) Future Events
     Events to occur at future simulation time.

Verilog Event Queue model
Verilog Event Queue model

Example :
What will be the output of following piece of code?
initial
begin
     a = 1'b0;
     a <= 1'b1;
     $display("\nValue of a is :%b", a);
end
     
Many of us think that the the value of a displayed will be '1', but it is not correct. Using the Verilog event queue,
I) a = 1'b0;
   This will be placed in the active events, so the assignment will take place immediately. Hence, at this time , the value of a is '0'.

II) a <= 1'b1;
     As you remember from our previous post on nonblocking assignments, the nonblocking assignment is a two step process, so only RHS evaluation will be scheduled in active event. At this point the LHS will not be updated, so the value of a still remains '0'.

III) $display("\nValue of a is :%b",a);
      Since, it is a display statement the statement will be placed in active events and processed immediately, so we get the value of a printed as '0'.

IV) In this step, the LHS of nonblocking statement in II will be updated, at this time the value of a will change from '0' to '1'.

Tuesday, 20 May 2014

Blocking, Nonblocking Assignments and Verilog Race Condition

Blocking Assignment

The blocking assignment operator is denoted by an equal sign ("="). The blocking assignment evaluates the RHS arguments and complete its assignment without interrupt from any other Verilog statement.

Execution of blocking assignments can be seen as a one-step process:
  1. Evaluate the RHS and update the LHS of the blocking assignment without interruption from any other Verilog statement.

The problem occurs, when the RHS side of one assignment in one procedural block is same as the LHS side of another assignment in another procedural block and both the assignments are scheduled to be executed in the same simulation time step, then in this case there is no sure way to predict which assignment will occur first. This condition is known as Verilog race condition.  The race condition is shown using the below example

module tp ( output reg o1,
                  output reg o2,
                  input         clk,
                  input         rst
                );

    always @(posedge clk or posedge rst)
        if (rst) 
              o1 = 1; 
        else 
              o1 = o2; //------> I

    always @(posedge clk or posedge rst)
        if (rst) 
              o2 = 0; 
        else
              o2 = o1;  //-------> II
endmodule

In this case, when the design gets out of reset, we cannot predict whether statement I will be executed first or statement II. If statement I is executed first, then values of o1 = 0, o2 = 0 ; if statement II is executed first, then o1 = 1; o2 = 1, hence this is a Verilog race condition.

Nonblocking Assignment

The nonblocking assignment operator is denoted by "<=".  A nonblocking assignment evaluates the RHS side of a nonblocking statement at the beginning of a time step and schedules the LHS update to take place at the end of the time step. Between evaluation of the RHS expression and update of the LHS expression, other Verilog statements can be evaluated and updated and the RHS expression of other Verilog nonblocking assignments can also be evaluated and LHS updates scheduled.

Execution of nonblocking assignments can be seen as a two-step process:

  1. Evaluate the RHS of nonblocking statements at the beginning of the time step.
  2. Update the LHS of nonblocking statements at the end of the time step.

module tp ( output reg o1,
                  output reg o2,
                  input         clk,
                  input         rst
                );

    always @(posedge clk or posedge rst)
        if (rst) 
              o1 <= 1; 
        else 
              o1 <= o2; //------> I

    always @(posedge clk or posedge rst)
        if (rst) 
              o2 <= 0; 
        else
              o2 <= o1;  //-------> II
endmodule

In this case, when reset is applied, o1 = '1' and o2 = '0', when the reset is de-asserted, the RHS side of both the statements are updated at the start of time step, but the assignment takes place only at the end of the time step, hence there is no race condition. At the end of time step , o1 = '0' and o2 = '1'.