Tutorials

Learn More

Procedural Assignments

In the dataflow modeling, a continuous assignment statement is discussed where LHS expression is always updated for changes in RHS expression. Refer to continuous assignment for more details. In the case of procedural assignment, the LHS variable remains unchanged until the same value is updated by the next procedural statement.

Syntax:

<variable> = <expression or value>

  1. RHS expression can be a value or an expression that evaluates to a value.
  2. LHS expression can be reg, integer, real, time-variable, or memory element.
  3. The procedural assignments can be placed inside procedural blocks like initial and always blocks. They can also be placed inside tasks and functions. 
  4. The procedural assignments can also be placed directly inside a module while declaring a variable. (Ex. reg [3:0] i_data = 4’h7)

There are two types of procedural assignments and both of them are widely used in the designs written in the Verilog language.

  1. Blocking assignments
  2. Non-blocking assignments

Blocking Assignments

The blocking assignment statements are executed sequentially by evaluating the RHS operand and finishes the assignment to LHS operand without any interruption from another Verilog statement. Hence, it blocks other assignments until the current assignment completes and is named as “blocking assignment”. 

An equal ‘=’ is used as a symbol for the blocking assignment operator.

Syntax:

<variable> = <expression or value>

Example:

module blocking;
  reg [3:0] data = 4'h4;
  real r_value;
  integer i_value;
  time T;
  
  initial begin
    $monitor("At time T = %0t: data = %0d, r_value = %0f, i_value = %0h", T, data, r_value, i_value);
    r_value = 3.14;
    i_value = 4;
    #2 data = 4'h5;
    #3 data = 'd7;
    i_value = 10;
    i_value = 6;
    $finish;
  end
  
  always #1 T = $time;
endmodule

Output:

At time T = 0: data = 4, r_value = 3.140000, i_value = 4
At time T = 1: data = 4, r_value = 3.140000, i_value = 4
At time T = 2: data = 5, r_value = 3.140000, i_value = 4
At time T = 3: data = 5, r_value = 3.140000, i_value = 4
At time T = 4: data = 5, r_value = 3.140000, i_value = 4
$finish called from file "design.sv", line 16.
$finish at simulation time 5

A blocking assignment does not block the execution of a statement in another procedural block. For example, two initial blocks start execution at the same simulation time. A blocking assignment in the first initial block does not block execution in another initial block.

Race around condition: A problem with blocking assignment

If a variable is used in LHS of blocking assignment in one procedural block and the same variable is used in RHS of another blocking assignment in another procedural block. The race-around condition can occur as an order of execution is unknown if both statements are scheduled at the same simulation time.

module blocking;
  reg [3:0] data = 4'h5;
  reg [3:0] y = 4'h3;
    
  initial begin // first initial block
    y = data;
    $display("1st block: data = %0h and y = %0h", data, y);
  end
  
  initial begin // second initial block
    data = y;
    $display("2nd block: data = %0h and y = %0h", data, y);
  end  
endmodule

Output:

1st block: data = 5 and y = 5
2nd block: data = 5 and y = 5

In this example, 

Since procedural blocks (both initial and always) can be executed in any order.

A. If the first initial block executed before the second initial block then 

  1. The value of y will be updated as 4‘h5 in the first initial block
  2. The value of data will be updated as 4‘h5 in the second initial block

B. If the second initial block executed before the first initial block then 

  1. The value of data will be updated as 4‘h3 in the second initial block
  2. The value of y will be updated as 4‘h3 in the first initial block