Search code examples
verilogsystem-veriloghdl

Using '<=' operator in verilog


Can any one explain me the reason why this particular module doesn'twork when we use '<=' instead of '='

module TestCell(x0, x1, y0, y1, z);
input x0, x1, y0, y1;
output z;
reg z;
reg a1, a2, a3, a4;
always @(x0 or x1 or y0 or y1) begin
a1 <= ~(x0 & y1);
a2 <= ~(y0 & x1);
a3 <= ~(a2 | a1);
a4 <= a2 & a1;
z <= ~(a4 | a3);
end
endmodule

And what we should ensure in order to use '<=' in verilog.


Solution

  • As Cthulhu has said = is blocking, That implies the statement will be evaluated before moving on to the next line of code.

    always @* begin 
      a = b & c;
      d = e & f;
      g = a & d ;
    end
    

    The above example is the same as :

    always @* begin
      g = b & c & e & f;
    end
    

    However if we switch to using <= Then they are no longer the same in simulation, the g will be the OLD a AND OLD b. Since this is a combinatorial block, ie not regularly triggered or evaluated like a flip-flop, you will get odd results from simulation.

    Correct use of the <= non-blocking assignment is in implying flip-flop.

    always @(posedge clk or negedge rst_n) begin
      if (!rst_n) begin
        a <= 1'b0;
        d <= 1'b0;
        g <= 1'b0;
      end
      else begin
          a <= b & c;
          d <= e & f;
          g <= a & d ;
      end
    end
    

    In the Flip-Flop example above g takes the value of a and d from last clk cycle not the current evaluation.

    In your example you have used always @(sensitivity list), that is a combinatorial circuit and = would be the correct usage. I would also recommend switching to always @* if your simulator allows it. The * is a wildcard and removes the need for manually entering the sensitivity list.

    I think that is is worth remembering that synthesis tools will base their results on the statement following the always @ If it is edge based they will use a type of flip-flop if it is combinatorial they will place combinatorial logic. The use of = or <= only has an effect in simulation. Using the wrong type means your simulation will not match the synthesised hardware.