From: Giorgos Tzampanakis on
I was under the impression that in Verilog nonblocking
assignments are evaluated in an arbitrary order. However, in
Quartus, I have noticed that if you use something like this:

always @(posedge clock) begin
a <= 1;
if (condition) a <= 0;
end

Then, if "condition" is true "a" will always be assigned the
value 0. Is this the way Verilog is described in the standard
or is it just an Altera convention?

Which bring us to my next question: Can I block multiple non-
blocking assignments together like so:

always @(posedge clock) begin
begin
a <= 1;
b <= 2;
end

begin
c <= a;
d <= b;
end
end

So that "c" will end up with value 1 and "d" will end up with
value 2? I know that if I had only "a" and "c" I could use
blocking assignments, but with two groups of variables it
wouldn't be possible. So does the above snippet work reliably?

From: Jonathan Bromley on
On Jul 15, 2:20 am, Giorgos Tzampanakis <g...(a)hw.ac.uk> wrote:

> So does the above snippet work reliably?

Yes, but not in the way you described :-)

> I was under the impression that in Verilog nonblocking
> assignments are evaluated in an arbitrary order.

You're not alone, but it's a delusion.

> However, in
> Quartus, I have noticed that if you use something like this:
>
> always @(posedge clock) begin
>         a <= 1;
>         if (condition) a <= 0;
> end
>
> Then, if "condition" is true "a" will always be assigned the
> value 0. Is this the way Verilog is described in the standard

Yes. The standard says that if you have multiple nonblocking
assignments (NBAs) to a variable, all maturing at the same
time, then they will take effect in the same order in which
they were executed procedurally. Given that your begin...end
is a procedural block, it's clear that the second a<=0 will
be executed later than the a<=1 assignment, and so it will
also take effect (update its target variable) later. This
is a fine, reasonable and useful coding style: make a
default assignment, and then possibly change your mind
about it later in the same procedural block.

> Which bring us to my next question: Can I block multiple non-
> blocking assignments together like so:
>
> always @(posedge clock) begin
>         begin
>                 a <= 1;
>                 b <= 2;
>         end
>
>         begin
>                 c <= a;
>                 d <= b;
>         end
> end
>
> So that "c" will end up with value 1 and "d" will end up with
> value 2?

No. There will be a one-clock delay between the update on a
and the update on c, and similarly for d and b. The
inner begin...ends are completely irrelevant and superfluous;
begin...end is simply bracketing to make a string of procedural
statements act syntactically like a single procedural statement.
Within the begin...end the statements are executed sequentially,
and each begin...end block is executed in sequence as if it were
a single more complex procedural statement.

Here's what happens:
1.On the first clock edge, all four assignments are executed
sequentially as you would expect. However, at the point when
c<=a is executed, the earlier NBA a<=1 has not yet taken
effect, so the assignment is effectively c<=1'bx (assuming
a was initially 1'bx).
2.At the time of that same clock edge, various other code in
your design will also execute as the result of @(posedge clock)
controls. All these code blocks will execute as far as their
next @() or other delay control.
3.When all code that was triggered by the clock has done executing
and has stalled at some delay control, Verilog moves on to the
NBA region of its scheduling model. The NBAs that were executed
in steps 1 and 2 now mature, and drop their assigned values
on to their target variables.
4.As a result of those variables being updated, it's quite likely
that other always or continuous-assign code may be triggered
for execution. But you can be sure that the clocked always
blocks are not among them, because (I hope!) none of the NBAs
updated the clock.
5.Then everything goes quiet until the next active clock edge,
and we're back to step 1 again.

The net result of all of this is that when you write a
conventional synthesisable clocked always block, you have
some guarantees about the behaviour of variables that were
written by NBA...
- when you READ the value of such a variable, either in a test
condition or in an expression on the RHS of some assignment,
you are reliably getting the variable's value as it was
immediately BEFORE the clock edge;
- when you ASSIGN to a variable using NBA, you are not yet
updating the variable; rather, you are specifying the
value that variable will take immediately AFTER the clock
edge. And you can rewrite that specification as often
as you please, by making successive NBAs to the same
variable.

> I know that if I had only "a" and "c" I could use
> blocking assignments, but with two groups of variables it
> wouldn't be possible

I really don't know what you mean by that.
Standard advice: take a look at Cliff Cummings's well-known
paper on blocking and nonblocking assignments (Google for
"Cummings coding styles that kill nonblocking"), which is
a thorough and generally reliable overview of the
situation. But please keep your critical faculties
engaged; there are some unjustified "rules" in his
paper that simply don't make sense. I and others
have ranted at length about that here, many times.
--
Jonathan Bromley
From: Giorgos Tzampanakis on
Jonathan Bromley <spam(a)oxfordbromley.plus.com> wrote in
news:9250a4ef-19e7-41af-9e91-4970608bc6bb(a)j13g2000yqj.googlegro
ups.com:

> Yes. The standard says that if you have multiple
> nonblocking assignments (NBAs) to a variable, all maturing
> at the same time, then they will take effect in the same
> order in which they were executed procedurally.
>
> (snip)
>
> No. There will be a one-clock delay between the update on a
> and the update on c, and similarly for d and b. The
>

So, if we have assignments to the same variable we are
guaranteed that the assignments will take place in the order
they are written in the code. But with assignments to different
variables the situtation is still unclear. Compare the
following two snippets:

//Snippet 1
always @(posedge clock) begin
a <= 1;
if (condition) b <= a;
end

//Snippet 2
always @(posedge clock) begin
a <= 1;
b <= a;
end

if "condition" is true, do they behave exactly the same?
From: Jonathan Bromley on
On Thu, 15 Jul 2010 13:59:48 +0000 (UTC), Giorgos Tzampanakis wrote:

>So, if we have assignments to the same variable we are
>guaranteed that the assignments will take place in the order
>they are written in the code. But with assignments to different
>variables the situtation is still unclear.

No, it isn't.

> Compare the following two snippets:
>
>//Snippet 1
>always @(posedge clock) begin
> a <= 1;
> if (condition) b <= a;
>end
>
>//Snippet 2
>always @(posedge clock) begin
> a <= 1;
> b <= a;
>end
>
>if "condition" is true, do they behave exactly the same?

Yes. And in both cases, b<=a will read the OLD value
of a (not the new value '1' whose assignment is
scheduled for the upcoming NBA region of the
scheduler). I can't really understand what would
make you think they would be different.
--
Jonathan Bromley
From: Jonathan Bromley on
On Thu, 15 Jul 2010 13:59:48 +0000 (UTC), Giorgos Tzampanakis wrote:

Sorry about the second response, but I just noticed....

>So, if we have assignments to the same variable we are
>guaranteed that the assignments will take place in the order
>they are written in the code.

No, that's not the point at all. They will take place
** in the order they were executed **. In other words,
scheduled updates go on to a particular timeslot's
NBA queue in FIFO order.

In a single sequential block, then of course that has
the same effect as "the order they are written" (except
in loops, which can divert the flow of execution backwards
in the code). But in the presence of concurrent
assignment to the same variable from multiple blocks,
or of intra-assignment delays, the difference is critical.

Fortunately for the present discussion, neither of
those two situations is suitable for synthesisable
design code.
--
Jonathan Bromley