Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Synthesis of non-blocking statements

I'm wondering why the following two Verilog code snippets are synthesized in the same way.

Because of non-blocking statements, tools should give a warning in the first case.

# out is the default when a=0
always @(posedge clk) begin
   out <= 0
   if(a)
      out <= in
end


always @(posedge clk) begin
   if(a)
      out <= in
   else
      out <= 0
end

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The two blocks of code are functionally equivalent. Verilog simulation and synthesis tools allow multiple NBA assignments to the same variable in the same process - the last write cancels the previous writes.

    The writing style of the first block is convenient when a process contains many variable assignments and many branching statements. Each branch need only specify the NBA assignments that are different from the default.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Because of non-blocking statements, tools should give a warning in the first case.

    --- Quote End ---

    They don't however, and there's no reason why they should.

    Due to the sequential code elaboration, the last assignment to a variable wins, all previous are ignored.

    If you feel that explicite else statements improve code readability, you'll possibly use it in some cases though.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ok, I found this clause in the Verilog 2001 spec, section "5.4.1 Determinism":

    ...

    Nonblocking assignments shall be performed in the order the statements were executed inside begin-end block. Consider the following example:

    initial begin
      a <= 0;
      a <= 1;
    end

    When this block is executed, there will be two events added to the nonblocking assign update queue. The previous rule requires that they be entered on the queue in source order; this rule requires that they be taken from the queue and performed in source order as well. Hence, at the end of time step 1, the variable a will be assigned 0 and then 1.

    ...