diff between these two implementation of clock

Thanks everone for clearing few things for me. Really great info.
Thanks again
 
"Alex" <agnusin@gmail.com> writes:

However, if you swap these two lines:

c <= a;
a = 1;

then races appear.

Since it is easy to make the "ordering mistake", one of verilog coding
guidelines is:

"Do not mix blocking and nonblocking assignments in the same always
block".

Regards,
-Alex
There are strong arguments the rule you cite. One it is simple.

However, we use an alternate rule, all blocking assignments must
appear before all non-blocking assignments in any given always block.
Or in other words, after a non-blocking assignment, one cannot use a
blocking assignment. We have a tool that enforces this restriction.
It's a slightly more terse coding style than forcing blocking and
non-blocking assignments being in separate blocks and still avoids
races.

If one visualizes blocking assignments as representing combinatorial
code, and non-blocking assignments as state elements (flip-flops,
register files, etc.). Then putting all the blocking assignment
statements at the front of the block and the blocking assignments at
the back, effectively says there are some combinatorial elements whose
outputs are saved in state devices. The clock edge on the always
block tells you what the state devices synchronize on. It's a pretty
straight forward model of either a Mealey or a Moore machine, which
ever one has no gates on the output side of the flops. If you want
gated outputs from the flops, you put them in continuous assignments
or an always block with no clock.

From the original code, it looks like that was the style the first
poster was following.

Note, we also disallow variables assigned in a blocking assignment of
a clocked always block being used outside that block and disallow
cyclical references that don't go through a non-blocking assignment.
We also require all non-blocking assignments to be in a clocked always
block. Again, the tool enforces these restrictions. If you follow
these conventions, one can easily identify the state elements (and
their clocks) in the Verilog--they're assigned to in the non-blocking
assignments. Everything else is combinatorial.

-Chris
 
Chris F Clark wrote:
"Alex" <agnusin@gmail.com> writes:

There are strong arguments the rule you cite. One it is simple.
For me, it is very serious argument. The idea is to simplify the rules
to express the nature of design. The design is already complex enough.


However, we use an alternate rule, all blocking assignments must
appear before all non-blocking assignments in any given always block.
Or in other words, after a non-blocking assignment, one cannot use a
blocking assignment. We have a tool that enforces this restriction.
It's a slightly more terse coding style than forcing blocking and
non-blocking assignments being in separate blocks and still avoids
races.
If one visualizes blocking assignments as representing combinatorial
code, and non-blocking assignments as state elements (flip-flops,
register files, etc.). Then putting all the blocking assignment
statements at the front of the block and the blocking assignments at
the back, effectively says there are some combinatorial elements whose
outputs are saved in state devices. The clock edge on the always
block tells you what the state devices synchronize on. It's a pretty
straight forward model of either a Mealey or a Moore machine, which
ever one has no gates on the output side of the flops. If you want
gated outputs from the flops, you put them in continuous assignments
or an always block with no clock.

From the original code, it looks like that was the style the first
poster was following.

Note, we also disallow variables assigned in a blocking assignment of
a clocked always block being used outside that block and disallow
cyclical references that don't go through a non-blocking assignment.
We also require all non-blocking assignments to be in a clocked always
block. Again, the tool enforces these restrictions. If you follow
these conventions, one can easily identify the state elements (and
their clocks) in the Verilog--they're assigned to in the non-blocking
assignments. Everything else is combinatorial.

-Chris
If I understand it correctly, you combine combinatorial and sequential
blocks into single sequential block, for example:

always @* begin // Combinatorial process (1)
b = a;
c = b;
end

always @(posedge clk) //Sequential process (2)
d <= c;

into :

always @(posedge clk) begin //Combined process (3)
b = a;
c = b;
d <= c;
end

Then, There is also a tool which checks that "combinatorial" part of
the process always appears before the "sequential" part of it.

"Combined" coding style has it's own problems too. Consider, for
example, passing the signal from one synchronous clock domain to
another while using "combined" coding style:

always @(posedge clk1) begin
b = a;
c = b;
d <= c;
end

always @(posedge clk2)
e <= b;

Because new value of b will be re-evaluated only at posedge clk1, it
will propagate with unwanted delay into clk2 clock domain.

In general, it looks like event-based vs cycle-based simulation ;)

Regards,
-Alex
 
However, if you swap these two lines:

c <= a;
a = 1;

then races appear.
I don't see the race condition here. This first statement will schedule
a non-blocking update for "c" to whatever "a" was set to previously,
and then "a" will be set to 1 by the blocking assignment. Perhaps I'm
missing something.

David Walker

Alex wrote:
Alex overstated the case.

I agree. The code

a = 1;
c <= a;

is race-free, since the first assignment blocks the execution of the
rest of statements (including nonblocking ones) within the same block.
However, if you swap these two lines:

c <= a;
a = 1;

then races appear.

Since it is easy to make the "ordering mistake", one of verilog coding
guidelines is:

"Do not mix blocking and nonblocking assignments in the same always
block".

Regards,
-Alex

In a single always block, blocking assignments are executed in order.
That's why they are called "blocking". They block the execution of
other statements within the same always block until the assignment
completes. The semantics of blocking assignments are designed to
mimic the semantics of other familiar languages like C.




-Alex


Chris F Clark wrote:
Alex writes:

so if we have something like this:
a = 1;
c <= a;


is that means we have race conditions. since now a is set and a is
evaluated for non-blocking in random order. sometimes c will set to 1
and sometimes it will not.

Yes, that's correct. As you pointed out, it results from the
non-specified ordering in Q1:

ankitks@yahoo.com writes:

if this leads to race condition, than why this FSM is not!
state <= next;
and next = CENT5 or..

Alex overstated the case.

In a single always block, blocking assignments are executed in order.
That's why they are called "blocking". They block the execution of
other statements within the same always block until the assignment
completes. The semantics of blocking assignments are designed to
mimic the semantics of other familiar languages like C.

Note, this does not hold between different always blocks or between
always blocks and continuous assignments. There are also other rules
about synchronization that are more subtle, but if you assume
non-determinism you will always be safe, because the deterministic
choice is always one of the non-deterministic choices.

Hope this helps,
-Chris

*****************************************************************************
Chris Clark Internet : compres@world.std.com
Compiler Resources, Inc. Web Site : http://world.std.com/~compres
23 Bailey Rd voice : (508) 435-5016
Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)
------------------------------------------------------------------------------
 
dbwalker0min@gmail.com wrote:
However, if you swap these two lines:

c <= a;
a = 1;

then races appear.

I don't see the race condition here. This first statement will schedule
a non-blocking update for "c" to whatever "a" was set to previously,
and then "a" will be set to 1 by the blocking assignment. Perhaps I'm
missing something.

From my previous post:
Q1 - (in any order) :
(A) - Evaluate RHS of all non-blocking assignments
(B) - Evaluate RHS and change LHS of all blocking assignments

c <= a; // (1)
a = 1; // (2)

Since (1) is non-blocking, (1) and (2) are in fact processed
simultaneously. In a case of (A -> B) ordering, during Q1, RHS of (1)
evaluates to "a" , and then in (2) "a" evaluates to 1. However, it will
not affect the value of RHS in (1) which is already evaluated. Then, in
Q2 "c" is assigned to RHS, which in not "1" but the previous value of
"a".

In a case of (B -> A) ordering, "a" changes value to "1" first. Then,
RHS in (1) takes new value of a, which is now "1". Then, in Q2 "c" is
assigned to "1" too.

Since ordering is not defined by standatd, "c" can be
non-deterministically assigned to either "1" of to the previous value
of "a".

-Alex


David Walker

Alex wrote:
Alex overstated the case.

I agree. The code

a = 1;
c <= a;

is race-free, since the first assignment blocks the execution of the
rest of statements (including nonblocking ones) within the same block.
However, if you swap these two lines:

c <= a;
a = 1;

then races appear.

Since it is easy to make the "ordering mistake", one of verilog coding
guidelines is:

"Do not mix blocking and nonblocking assignments in the same always
block".

Regards,
-Alex

In a single always block, blocking assignments are executed in order.
That's why they are called "blocking". They block the execution of
other statements within the same always block until the assignment
completes. The semantics of blocking assignments are designed to
mimic the semantics of other familiar languages like C.




-Alex


Chris F Clark wrote:
Alex writes:

so if we have something like this:
a = 1;
c <= a;


is that means we have race conditions. since now a is set and a is
evaluated for non-blocking in random order. sometimes c will set to 1
and sometimes it will not.

Yes, that's correct. As you pointed out, it results from the
non-specified ordering in Q1:

ankitks@yahoo.com writes:

if this leads to race condition, than why this FSM is not!
state <= next;
and next = CENT5 or..

Alex overstated the case.

In a single always block, blocking assignments are executed in order.
That's why they are called "blocking". They block the execution of
other statements within the same always block until the assignment
completes. The semantics of blocking assignments are designed to
mimic the semantics of other familiar languages like C.

Note, this does not hold between different always blocks or between
always blocks and continuous assignments. There are also other rules
about synchronization that are more subtle, but if you assume
non-determinism you will always be safe, because the deterministic
choice is always one of the non-deterministic choices.

Hope this helps,
-Chris

*****************************************************************************
Chris Clark Internet : compres@world.std.com
Compiler Resources, Inc. Web Site : http://world.std.com/~compres
23 Bailey Rd voice : (508) 435-5016
Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)
------------------------------------------------------------------------------
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Alex wrote:
dbwalker0min@gmail.com wrote:
However, if you swap these two lines:

c <= a;
a = 1;

then races appear.
I don't see the race condition here. This first statement will schedule
a non-blocking update for "c" to whatever "a" was set to previously,
and then "a" will be set to 1 by the blocking assignment. Perhaps I'm
missing something.

From my previous post:
Q1 - (in any order) :
(A) - Evaluate RHS of all non-blocking assignments
(B) - Evaluate RHS and change LHS of all blocking assignments

c <= a; // (1)
a = 1; // (2)

Since (1) is non-blocking, (1) and (2) are in fact processed
simultaneously.
No. Mr. Walker is exactly right, there is no race here so long
as these statements are in the same process. The ordering is well
defined. The process will complete up to its next blocking statement
before any non-blocking assignments take effect. Period.

If these statements are in different processes (i.e. different
"always" statements) then it is indeed a race, but then this thread
wouldn't be talking about switching the order of statements in a block.
- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFFdf3DrPt1Sc2b3ikRAgt5AJ9Ogax7YTLiZ9ZFDbOMNRs0o8IrywCg2d+E
PJPHoSU9WXTxJIInlT0ACno=
=GH1z
-----END PGP SIGNATURE-----
 
dbwalker0min@gmail.com wrote:
However, if you swap these two lines:

c <= a;
a = 1;

then races appear.

I don't see the race condition here. This first statement will schedule
a non-blocking update for "c" to whatever "a" was set to previously,
and then "a" will be set to 1 by the blocking assignment.
Agreed.

A nonblocking assignment is guaranteed to evaluate its RHS before
execution continues. And two statements in a sequential block (i.e.
begin-end) are guaranteed to execute in the order they appear.
So there is no race condition for either order of statements, unless
they are inside a fork-join instead of a begin-end.

Verilog execution order is nondeterministic in some cases, but some
people seem to be greatly exaggerating this.
 
sharp@cadence.com wrote:
Verilog execution order is nondeterministic in some cases, but some
people seem to be greatly exaggerating this.
I am trying to educate myself not from implementation (existing verilog
simulators) but from specification (Verilog standard). As a
verification engineer, it is my professional habit ;)


Here is exempt from 1364-2001 Verilog standard which most likely refers
to this question:

---------------------------------------------------------
5.4.1 Determinism
This standard guarantees a certain scheduling order.
1) Statements within a begin-end block shall be executed in the order
in which they appear in that begin-end block. Execution of statements
in a particular begin-end block can be suspended in favor of other
processes in the model; however, in no case shall the statements in a
begin-end block be executed in any order other than that in which they
appear in the source.
2) Non blocking assignments shall be performed in the order the
statements were executed. Consider the following example:
When this block is executed, there will be two events added to the non
blocking 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.
---------------------------------------------------------


(1) is indeed speaking about in-order execution of all statements in
the block - either blocking or non-blocking. However, it is not
speaking about the ordering of ASSIGNMENTS.

Then, (2) is asserting, that "non-blocking ASSIGNMENTS shall be
performed in the order the statements were executed".

Also, it is clear that blocking assignments execute in-order.

Is there any statement in the standard which clearly defines ordering
rules for intermixed blocking/nonblocking asignments within the same
block?

Regards,
-Alex
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Alex wrote:

(1) is indeed speaking about in-order execution of all statements in
the block - either blocking or non-blocking. However, it is not
speaking about the ordering of ASSIGNMENTS.

Then, (2) is asserting, that "non-blocking ASSIGNMENTS shall be
performed in the order the statements were executed".

Also, it is clear that blocking assignments execute in-order.

Is there any statement in the standard which clearly defines ordering
rules for intermixed blocking/nonblocking asignments within the same
block?
The stratified event queue implies it. The non-blocking assignment
values are placed into the nb-assign event queue. That queue is
not processed until all statements have advanced as far as they
can. Only after all the statements are blocked waiting on events
will the nb-assign queue start its work.


- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFFdi2XrPt1Sc2b3ikRAvQ9AJ9+bUOASNjmqEshE/ZsqrIApjozhgCbBcME
7zxWNojfuoxnShauc1x1+3A=
=MUk/
-----END PGP SIGNATURE-----
 
Stephen Williams wrote:
The stratified event queue implies it. The non-blocking assignment
values are placed into the nb-assign event queue. That queue is
not processed until all statements have advanced as far as they
can. Only after all the statements are blocked waiting on events
will the nb-assign queue start its work.
Here is the definition of stratified queue from Verilog standard:

------------------------------------------------------------------------
5.3 The stratified event queue
The Verilog event queue is logically segmented into five different
regions. Events are added to any of the five regions but are only
removed from the active region.
1) Events that occur at the current simulation time and can be
processed in any order. These are the active events.
2) Events that occur at the current simulation time, but that shall be
processed after all the active events are processed. These are the
inactive events.
3) Events that have been evaluated during some previous simulation
time, but that shall be assigned at this simulation time after all the
active and inactive events are processed. These are the non blocking
assign update events.
4) Events that shall be processed after all the active, inactive, and
non blocking assign update events are processed. These are the monitor
events.
5) Events that occur at some future simulation time. These are the
future events. Future events are divided into future inactive events,
and future non blocking assignment update events.
The processing of all the active events is called a simulation cycle.
The freedom to choose any active event for immediate processing is an
essential source of nondeterminism in the Verilog HDL.
------------------------------------------------------------------------

Sorry, but I cannot extract the features you've mentioned from the
implementation details of stratified event queue. In fact, I don't see
nothing related to execution of start ... end blocks.

Probably, I will be able to do this after writing my own Verilog
simulator.But do I need to write simulator to understand important
properties of verilog scheduling process?


Regards,
-Alex
 

Welcome to EDABoard.com

Sponsor

Back
Top