Multiple non-blocking assigns in always block

R

romi

Guest
In the code below when 'set' is 1, is the next value of 'ff'
deterministic? My initial thought was that the LHS of non-blocking
assignments can be computed in any order and since there are 2 non-
blocking assignments, one assigning 0 and one assigning 1, either
value could potentially propagate to 'ff'. However, I also realize
that the always block itself is procedural so perhaps there is some
ordering of the LHS updates of non-blocking assignments within the
same always block. Thanks.


always @(posedge clk) begin
if(~reset_l) begin
ff<=0;
end else begin
ff<=0;
if(set) begin
ff<=1;
end
end
end
 
On Sat, 14 Jun 2008 21:25:00 -0700 (PDT), romi <weberrm@gmail.com>
wrote:

In the code below when 'set' is 1, is the next value of 'ff'
deterministic? My initial thought was that the LHS of non-blocking
assignments can be computed in any order and since there are 2 non-
blocking assignments, one assigning 0 and one assigning 1, either
value could potentially propagate to 'ff'. However, I also realize
that the always block itself is procedural so perhaps there is some
ordering of the LHS updates of non-blocking assignments within the
same always block. Thanks.
Indeed there is. The standard guarantees that "nonblocking assignments
shall be performed in the order the statements were executed". There
is no reordering of statements within a single begin-end block.
 
On Jun 14, 11:25 pm, romi <webe...@gmail.com> wrote:
In the code below when 'set' is 1, is the next value of 'ff'
deterministic?  My initial thought was that the LHS of non-blocking
assignments can be computed in any order and since there are 2 non-
blocking assignments, one assigning 0 and one assigning 1, either
value could potentially propagate to 'ff'.  However, I also realize
that the always block itself is procedural so perhaps there is some
ordering of the LHS updates of non-blocking assignments within the
same always block.  Thanks.

always @(posedge clk) begin
  if(~reset_l) begin
    ff<=0;
  end else begin
    ff<=0;
    if(set) begin
      ff<=1;
    end
  end
end
Within the same block, non-blocking assignments happen in the same
order in which they are in the RTL. So the next value of 'ff' is
deterministic - if 'set' is 1, then 'ff' is 1, otherwise it is 0. But
this is probably not a good coding style as it can cause glitches in
RTL simulation.
 
On Sat, 14 Jun 2008 22:44:07 -0700 (PDT), googler wrote:

Within the same block, non-blocking assignments happen in the same
order in which they are in the RTL. So the next value of 'ff' is
deterministic - if 'set' is 1, then 'ff' is 1, otherwise it is 0.
Indeed so. Important, powerful and useful.

this is probably not a good coding style as it can cause glitches in
RTL simulation.
Hmmm. Personally I think it *is* a "good coding style", because
it allows me to express intent clearly. But you are right, it
can cause zero-width glitches. Unfortunately Verilog does not
define whether such glitches will be seen as an event on the
signal. So it is something you would wish to avoid if the
output is then used as a clock for some other logic. In any
other situation, it's completely harmless.

Another example of VHDL out-smarting Verilog for RTL design :)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
romi wrote:
In the code below when 'set' is 1, is the next value of 'ff'
deterministic? My initial thought was that the LHS of non-blocking
assignments can be computed in any order and since there are 2 non-
blocking assignments, one assigning 0 and one assigning 1, either
value could potentially propagate to 'ff'. However, I also realize
that the always block itself is procedural so perhaps there is some
ordering of the LHS updates of non-blocking assignments within the
same always block. Thanks.


always @(posedge clk) begin
if(~reset_l) begin
ff<=0;
end else begin
ff<=0;
if(set) begin
ff<=1;
end
end
end
The last assignment supercedes, so this will synthesize the same as

if (set) ff<=1; else ff<=0;

As for style, it's generally to be avoided, because it can be hard to
maintain code that has assignments in multiple 'if' clauses. However, I
use this a lot for state machines for signals in which I only want
asserted in one or two states. I first set the default (deassertion)
and then assert the signal only in the states I desire. Then I don't
have to explicitly assign the signal in every single state, which
clutters up the code and leads to problems if I forget to deassert it in
certain states. -Kevin
 

Welcome to EDABoard.com

Sponsor

Back
Top