In SystemVerilog, assignment statements are essential for defining the behavior of variables in a procedural block. There are two main types of assignments: blocking assignments and non-blocking assignments. These two types control the execution of statements differently, which can lead to varying results in simulation. Let’s take a closer look at both.

What is Blocking Assignment?

In SystemVerilog, blocking assignments are made using the = operator. When using blocking assignments, the next statement in a procedural block cannot execute until the current statement finishes. This means that each statement runs sequentially, one after another, in the order it is written.

Blocking Assignment Example:

module tb;
  reg [7:0] a, b, c, d, e;

  initial begin
    a = 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b = 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c = 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end

  initial begin
    d = 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e = 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Simulation Log for Blocking Assignment:

ncsim> run
[0] a=0xda b=0xx c=0xx
[0] a=0xda b=0xf1 c=0xx
[0] a=0xda b=0xf1 c=0x30
[0] d=0xaa e=0xx
[0] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

How Blocking Assignments Work

In this example, two initial blocks run in parallel when the simulation starts. Within each block, statements execute sequentially, meaning each statement waits for the previous one to finish.

For example:

  • First, variable a is assigned 8'hDA.
  • Then, the display statement prints the current values of a, b, and c.
  • Next, the b variable is assigned 8'hF1, followed by another display statement.

Notice that in the first display output, b and c are still unassigned (0x), because the assignment statements for b and c have not been executed yet.

What is Non-Blocking Assignment?

In contrast, non-blocking assignments use the <= operator. This type of assignment allows multiple statements to be executed without waiting for the current one to finish. The right-hand side (RHS) value of the assignment is captured at the current time step and assigned to the left-hand side (LHS) variable only at the end of the time step.

Non-Blocking Assignment Example:

module tb;
  reg [7:0] a, b, c, d, e;

  initial begin
    a <= 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b <= 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c <= 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end

  initial begin
    d <= 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e <= 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Simulation Log for Non-Blocking Assignment:

ncsim> run
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] d=0xx e=0xx
[0] d=0xx e=0xx
ncsim: *W,RNQUIE: Simulation is complete.

How Non-Blocking Assignments Work

In this case:

  • When a <= 8'hDA is executed, the RHS value (8'hDA) is noted but not immediately assigned.
  • The display statement prints a=0x because the assignment to a has not yet taken place.
  • Similarly, for b and c, their RHS values are noted, but the assignments only happen at the end of the time step.

Blocking vs Non-Blocking: Key Differences

FeatureBlocking Assignment (=)Non-Blocking Assignment (<=)
Execution OrderSequential execution (one after another)Parallel execution (does not block)
RHS Assignment TimingAssigned immediatelyAssigned at the end of the time step
Use in Sequential LogicSuitable for simple sequential operationsSuitable for clocked processes and pipelines
Simulation Output TimingVariables are updated instantly in the order they are writtenVariables are updated only at the end of the time step
Impact on Parallel ExecutionBlocks parallel executionAllows parallel execution without blocking

Example with Delays in Blocking Assignment

In the next example, we add some delays in the blocking assignment to see how it behaves in simulation.

module tb;
  reg [7:0] a, b, c, d, e;

  initial begin
    a = 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    #10 b = 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c = 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end

  initial begin
    #5 d = 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    #5 e = 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Simulation Log with Delays:

ncsim> run
[0] a=0xda b=0xx c=0xx
[5] d=0xaa e=0xx
[10] a=0xda b=0xf1 c=0xx
[10] a=0xda b=0xf1 c=0x30
[10] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

Conclusion: When to Use Blocking or Non-Blocking Assignments?

  • Blocking assignments are useful when you need operations to execute sequentially.
  • Non-blocking assignments are ideal when you want to allow parallel execution or when you’re working with clocked processes.

By understanding the differences between these two types of assignments, you can control how your simulation behaves, ensuring that your designs operate as intended.

Scroll to Top