Blocking Vs Non Blocking in Combinational Circuit


We will continue to learn about Difference in Blocking and Non blocking - this time around combinational Circuit. Consider the following circuit that has three inputs a, b and c and one output y. We are trying to infer the following circuit y = (a & b) | c; Although, we coul implement it using a single assign statement, we are making it complicated for the purpose of understanding the difference between blocking and non blocking.
The following is one implemmentation of this circuit

// referencedesigner.com 
// A combinational Circuit with blocking assignment
module combinationalblocking (
      input wire a,b,c,
  output  reg y
    );
 
  always @(a,b,c)
      begin
        y = a & b;
        y = y | c ;
      end	
  endmodule


A simple testbench shows that the code behaves as expected



`timescale 1ns / 1ps
// Testbench
module test;
  reg a, b, c;
  wire y;
 
  // Instantiate design under test
  combinationalblocking cb1 (.a(a), .b(b),
                                .c(c), .y(y) );
 
  initial begin
    $monitor ("a =%1b , b=%1b , c=%1b , y = %1b ",  a,b,c,y);
    a =0; b =0; c = 0;
    #5 a = 1;
    #5 b =1;
    #5 a = 0;
    #5 b = 0;
    #5 c = 1;
  end
 
endmodule


It will give the following output


a =0 , b=0 , c=0 , y = 0 
a =1 , b=0 , c=0 , y = 0 
a =1 , b=1 , c=0 , y = 1 
a =0 , b=1 , c=0 , y = 0 
a =0 , b=0 , c=0 , y = 0 
a =0 , b=0 , c=1 , y = 1
 


The most important line to see is


        y = a & b;
        y = y | c ;
 
These two lines are executed sequentially in that order. So first, y is assigned a & b. The next statement is executed only after this one finishes. So when y = y | c is to be executer, the y on RHS has already has the value a & b from previous assignement.

The question we are trying to answer is - what happens if we use the non blocking assignment as in

        y <= a & b;
        y <= y | c ;
 
Well, here is the result of the simulation

a =0 , b=0 , c=0 , y = x 
a =1 , b=0 , c=0 , y = x 
a =1 , b=1 , c=0 , y = x 
a =0 , b=1 , c=0 , y = x 
a =0 , b=0 , c=0 , y = x 
a =0 , b=0 , c=1 , y = 1
 
Initially y is undecided or x. Right at the begining a & b evaluates to 0 from y <= a & b. Simultaneously, the RHS of y <= y | c is executed. Since an or or 1'b0 with undecided results in undecided, we have value of y as undecided or 1'bx.

We can similarly explain other outputs. For example see the last line of the output from simulation


a =0 , b=0 , c=1 , y = 1
 
When a and b are both 0, y <= a&b makes y 0. The assignment y = y |c with c= 1'b1 makses y as 1.

The problem with this kind of assignment is that we are tying togather, the output of a&b and the y |c. This is not the intended operation.

This bring us to one important rule of thumb for combinatorial circuits

Do not use non blocking assignments for combinational circuits.