I have not clear at all this part of Verilog when using <= or when =

I have some always blocks that make some adds, subtracts and multiplies an example is like this:

    module Calcs 
        parameter RC = 24'h0186DA,
                  RV = 24'h018666
        input clk,    // Clock

        output reg go  

    reg [63:0] val1; 
    reg [63:0] val2; 

    reg [63:0] val3; 
    reg [63:0] val4; 

    reg [63:0] ValSelected;

    reg [127:0] Mult1; 
    reg [127:0] Mult2; 

    reg [128:0] Subs; 

    reg [128:0] Mult3; 

    reg isNeg;

    reg go1;

    reg [63:0] LastVal1;
    reg [63:0] LastVal2;
    reg [63:0] LastValSelected;

    always @ (posedge clk) begin

         Is_Valid  = (val1 != 0) && (val2 !=0); 

        if (val4 >=  val3) ValSelected = val3; 
        else if (val4 < val3) ValSelected = val4; 

        if (Is_Valid) begin
            Mult1      = val2 * RV;
            Mult2      = val1 * RC;
            Subs       = Mult2 - Mult1;
            isNeg      = Subs < 0;
            if (!isNeg) Mult3 = ValSelected * Subs;
            else Mult3 = 0;
            if (Mult3 > 1) begin
                if (((val1 != LastVal1) || (val2 != LastVal2))  || (ValSelected != LastValSelected)) go1 <= 1'b1;
                else if(((val1 == LastVal1) || (val2 == LastVal2))  || (ValSelected == LastValSelected)) go1 <= 1'b0;           

    always @ (posedge clk) begin
        if (go1) begin
            LastVal1 = val1;
            LastVal2 = val2;
            LastValSelected = ValSelected;
            go <= 1'b1;
        else go <= 1'b0;

There is some strange behavior when I use <= to set the value to go1 this is never executed and if I change this for = this execute always and if the if is fulfilled go1 it never comes back to 0

can someone help me to understand this?

sorry if the code has some issues there is just an example

Many Thanks!

  • \$\begingroup\$ Welcome to Stack Exchange. You might try to get a minimal working example that shows your problem. That makes it easier to see your problem or others help you. \$\endgroup\$ Sep 23, 2018 at 23:16

2 Answers 2


The rule is simply:

If one process writes to a variable synchronized to an event, and another process reads the same variable synchronized to the same event, you must write using an NBA ensuring that the reading process uses the old value of the variable.

If you don't use an NBA writing process, there is a race condition in the reading process in that you don't know if it reads the old or new value.

Note that each always block in your example is both a reading and writing process depending on which variable we are considering synchronized to the posedge clk event. Also consider the processes that write to the module inputs and read the module outputs.

If you have a variable that is local to a process, it is your choice to use either assignment depending on the functionality you desire. But for combinational, blocking assignments are recommended.

  • \$\begingroup\$ So thinking of this in my logic I need to use NBA anyway this is something that i was testing few minutes ago but the reg go it never comes back to 0, really I don't know why \$\endgroup\$ Sep 22, 2018 at 4:12
  • \$\begingroup\$ First fix your issues with using non-blocking assignments inappropriately on all variables (not just "go"), then if you still have problems post a question with a complete (i.e. including the testbench) minimal example describing your problem. \$\endgroup\$ Sep 25, 2018 at 15:58

Verilog - Blocking Assignment (=) Two Register outputs are assigned the same input, after a shared clk edge.

Verilog – Non-blocking Assignment (<=) Two Register outputs are cascaded, one after the other, after a shared clk edge, I.e. a clock delayed register

As promised, proof that the above is true Ref

enter image description here

Anyone who disagrees must justify.

  • \$\begingroup\$ Are you talking about combinatorial and sequential logic? \$\endgroup\$ Sep 22, 2018 at 3:37
  • \$\begingroup\$ No I’m talking only about synchronous race-free events using a FF register assignments , synthesized by 2 D FF’s This is correct. Why -1? \$\endgroup\$ Sep 22, 2018 at 4:18
  • \$\begingroup\$ I.e. <= is a 2 stage shift register \$\endgroup\$ Sep 22, 2018 at 4:39
  • 1
    \$\begingroup\$ @TonyEErocketscientist Because it's wrong. The <= operator does not always even imply synchronous logic, and I cannot think of any situation where it would ever synthesize to multiple chained registers. \$\endgroup\$
    – user39382
    Sep 22, 2018 at 5:34
  • 2
    \$\begingroup\$ You have overlooked the fact that there are three nonblocking assignments in the corresponding source. The Powerpoint slide you've included in your answer (without attribution, by the way) is trying to show that, in a clocked always block, each <= assignment is effectively synthesized to one register. \$\endgroup\$
    – user39382
    Sep 24, 2018 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.