diff between these two implementation of clock

Guest
Hello guys,
I am confuse on how events will be sceduled in this two implemention of
clock

1.

module DUT (input clk);

initial begin
clk = 0;
#10 clk = ~clk;
end


2.
module DUT (input clk)
inital begin
clk <=0;
#10 clk <= ~clk;
end
 
Each Verilog simulation time step is divided into 4 queues:

Q1 - (in any order) :
- Evaluate RHS of all non-blocking assignments
- Evaluate RHS and change LHS of all blocking assignments
- Evaluate RHS and change LHS of all continuous assignments
- Evaluate inputs and change outputs of all primitives
- Evaluate and print output from $display and $write

Q2- (in any order) :
- Change LHS of all non-blocking assignments

Q3 - (in any order) :
- Evaluate and print output from $monitor and $strobe
- Call PLI with reason_synchronize

- Q4 :
- Call PLI with reason_rosynchronize


So, #10 clk = ~clk re-assigns new clock value during Q1, while
#10 clk <= ~clk re-assigns new clock value after that, in Q2.

You can try the following example to explore clock sheduling:


module clock_test;

reg clk1, clk2;

initial clk1 = 1;
always #5 clk1 = ~clk1;

initial clk2 <= 1;
always #5 clk2 <= ~clk2;

initial begin
#10 $display ($time, " 1: clk1 = %b, clk2 = %b", clk1,
clk2);
@(posedge clk1) $display ($time, " 2: clk1 = %b, clk2 = %b", clk1,
clk2);
@(posedge clk2) $display ($time, " 3: clk1 = %b, clk2 = %b", clk1,
clk2);
#10 $finish;
end

endmodule


-Alex
 
thanks Alex. That definetly helped me clarifing few things.
one question:

in Q1 -> we evaluate blocking assignment and also calculate RHS for
non-blocking assignment.

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.

thanks.
 
anki...@yahoo.com wrote:
thanks Alex. That definetly helped me clarifing few things.
one question:

in Q1 -> we evaluate blocking assignment and also calculate RHS for
non-blocking assignment.

so if we have something like this:
a = 1;
c <= a;
also will value of c will change in current timeslot or will be in next
cycle?

thanks
 
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:

Q1 - (in any order) :
- Evaluate RHS of all non-blocking assignments
- Evaluate RHS and change LHS of all blocking assignments


also will value of c will change in current timeslot or will be in next
cycle?
All non-blocking assignment are done at Q2 phase of current time slot.
However, you cannot use $display to prove that, since it will be
executed before in Q1 (use instead $monitor or $strobe). Also, you
cannot use the result of non-blocking assignment for any other
calculations in the current timeslot - there are no assignments after
Q2.

-Alex
 
so if we have something like this:
a = 1;
c <= a;
if this leads to race condition, than why this FSM is not!
state <= next;
and next = CENT5 or..


module fsm_state (input clk, reset, cent5, cent10, output reg value);
parameter [2:0] IDLE, CENT5, CENT10, CENT15, CENT20;
reg [2:0] state, next;

always @(posedge clk or negedge rst) begin
if (!rst) state <= IDLE;
else state <= next;
end

always @(state or cent5, cent 10) begin
value = 0;
next = 3'bz;
case (state) begin
IDLE: if (cent5) next = CENT5;
elseif(cent10) next = CENT10;
else next = IDLE;
CENT5: if ...
.........
endcase
end
 
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)
------------------------------------------------------------------------------
 
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)
------------------------------------------------------------------------------
 
thanks guys for great comments! and sorry for my ignorance but I still
don't understand how this FSM is simulation and synthatis correct!

###################################
always @(posedge clk) begin
state <= next;
end

always @(state or cent5, cent 10) begin
value = 0;
next = 3'bz;
case (state) begin
IDLE: if (cent5) next = CENT5;
elseif(cent10) next = CENT10;
else next = IDLE;
CENT5: if ...
.........
endcase
end
#################################

for this given block, how are events and assignment are sceduled in
given timeslot. Can someone please please explain me.


here is my understanding.
clk changes -> so always@(posedge clk) is activated -> causes RHS of
the NBS to sampled (that is next is sampled) -> no more blocking -> LSH
of NBS is evaluated (state) is changed -> triggers always@(state) block
-> blocking statement for 'next' value is evaluated in-order. -> next
changes -> nothing else to do -> move to next clock.
this understanding works fine, but what will happen if sensitivity list
cent5 changes in this case at poseedge of clock also. now clk changes
-> so always@(posedge clk) is activated
parrell s0 changes -> so
always@(state or cent5...) is actiated


so now for sampaling of next, RHS
of the NBS (for state <= next) and
assigment of next = NEW_STATE is
happing in parrell

that is race! isn't it?

please correct me. What I am assuming wrong.


Thank you.
 
"Alex" <agnusin@gmail.com> writes:
[stuff including quotes of me omitted]...
"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;
Yes, we disallow that case. We don't allow one to export a value from
a blocking assign in a clocked always block. And, the tool checks
this restriction. We treat the first block, more like it had been
written:

always @(posedge clk1) begin xyz:
reg b; // b is local to xyz
reg c; // c is local to xyz
b = a;
c = b;
d <= c; // d can be used elsewhere
end // xyz

In general, it looks like event-based vs cycle-based simulation ;)
Yes, that's a side-effect. We use a very fast (10x faster) cycle
based simulator, which speeds up our (pre-silicon) validation effort,
which is one of our slow parts in the design process. The validation
engineers and their manager are very psyched about the speed up, as it
makes them look better.

However, the main reason we do it is that it matches what happens if
we draw the circuit graphically. In fact, we started with a graphical
tool that models gates and flop, and translated them into stylized
Verilog (like the code above). Then, we realized that we liked the
style of Verilog so much that we standardized on it.

It matches what I mean when I talk about vizualing hardware when
writing Verilog. The style keeps the designers from "programming" in
Verilog. Everything which is legal in our style has a clear mapping
to some kind of hardware. In particular, it is easy to tell which
lines represent state elements (flops, registers, memories, and
latches) and what clocks control the state changes and which lines are
simply labels of a combinatorial signal. And, that's our main goal.

My apologies for being delayed in this reply. I had written a better
version of the above previously, but the system I connect to for
reading/writing news crashed and I lost it. So, it took awhile before
I got back to this group--this isn't my main area of interest.

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)
------------------------------------------------------------------------------
 
ankitks@yahoo.com writes:

thanks guys for great comments! and sorry for my ignorance but I still
don't understand how this FSM is simulation and synthatis correct!

###################################
always @(posedge clk) begin
state <= next;
end

always @(state or cent5, cent 10) begin
value = 0;
next = 3'bz;
case (state) begin
IDLE: if (cent5) next = CENT5;
elseif(cent10) next = CENT10;
else next = IDLE;
CENT5: if ...
.........
endcase
end
#################################

for this given block, how are events and assignment are sceduled in
given timeslot. Can someone please please explain me.
Here is a simplified model of what Verilog does. If you need more
details then this, then you probably have a model that depends too
much on event ordering and it is unlikely to synthesize to the same
logic that it simulates.

Ok, first. Make a list of all your variables. For variables, that as
assigned by blocking assignments give them one box (the "current"
value). For variables assigned by non-blocking assignments given item
two boxes--the first box is the "current" value and the second box
will be the "next" value.

Note, the following rules should be true (with some exceptions).

1) Each variable should be assigned to in only 1 always block
or in 1 continuous assignment statement.

2) Each variable should only be assigned to by 1 kind of
assignments statement, a blocking assignment, a non-blocking
assignment, or a continuous assignment.

Now, for a given always block, step through it in order and execute
the statements. If you are executing a blocking assignment, simply
overwrite the context of the box. If you are executing a non-blocking
assignment, write the value in the second (next) box. When reading
the value always use the current box. For simplicity, I've ignored
code with #delays--you shouldn't generally have #delays in
synthesizable code, because the synthesizer won't respect them and as
a result they can cause your code to behave differently once
synethsized than what your simulation predicted.

Note, you can execute the always blocks in any order (and mix the
continuous assignments in any order also). Not only that, but you
don't have to complete an always block before starting on another.
That's the essense of the non-determinism in Verilog.

Now, once you've executed all the always blocks and continuous
assignments, copy the contents of the "next" boxes into the current
boxes for the variables assigned to by non-blocking assignments, and
run any blocks or continuous that need to be run. Again, you can mix
the copying with the running of the blocks (that are caused by said
copying), and the result is thus non-deterministic. Note, that for
variables assigned by non-blocking assignments within one always
blocks, those copies must occur in the same order as the original code
assigned them, but otherwise you can copy in any order.

Looking at your code, a posedge of the clock (for simplicity assume
the clock goes from 0->1), will cause the value of the variable "next"
to be written in the 2nd box of the variable "state".

Now, if cent5 or cent10 has changes, you should run the 2nd always
block. If you do, value and next may get changed, and the value of
"state" that will be used will be the current (some would say old)
value of state, not the value assigned in the 1st always block. That
assignment is still pending.

Once, you are done running blocks, you have a pending update to
"state". So, copy the value of the 2nd box of state to the first box.
This will update state to the correct value (and probably change its
value). Now, since you have touched state, you run the 2nd always
block (potentially again, if you ran it before).

Note, if the value of state didn't change, you may be able to skip
running the 2nd always block. This detail is fuzzy in my mind, and I
don't think the standard actually says anywhere. However, if you've
written your code, such that whether you run or don't run the 2nd
always block matters, you probably have broken code anyway. In fact,
in general, code in always blocks that aren't sensitive to an edge,
should be written so that you can run them as many times as you want
and nothing bad will happen. If you have code, that you only want run
a fixed (specific) number of times, you put that code in an edge
sensitive (clocked) always block and use the edge of the clock to
determine how often (and when) it is run.

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)
------------------------------------------------------------------------------
 
Chris,
Great help. Thanks. I think that fills lots of black questions for me.
Can you tell me this last request..and I think I have a complete
picture.

let say cent5 is also goes from 0->1, when clk goes from 0->1. In this
case why we executed this always block first.

always @(posedge clk)
state <= next

followed by


always @(state or cent5)
next = if (state).....
.......................


my question is both always can go in parralle (since their sensitivity
list are now change together). But it doesn't..right? why?
 
Alex wrote:
I am trying to educate myself not from implementation (existing verilog
simulators) but from specification (Verilog standard).
This is a bit dangerous. The section on scheduling semantics was
grafted onto the standard rather late in the process. It uses
terminology that is not used anywhere else in the standard. It tries
not to disallow any behavior of Verilog-XL or other simulators of the
time, and in the process allowed so much nondeterminism that it would
be hard to write working Verilog if it were taken too literally. At
the same time, it codified behavior that was originally intended to be
nondeterministic, but where users had started relying on the behavior
of the Verilog-XL implementation. It takes a lot of side knowledge to
interpret properly. This is unfortunate, but true in practice.

(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.
The behavior of nonblocking assignments causes this awkward wording.
Where it refers to ASSIGNMENT, it is talking about the actual updating
of the value of the variable. With a
blocking assignment statement, the statement cannot complete execution
and continue with the next statement until the value has been updated.
With a nonblocking assignment, the RHS (and any indexes in the LHS)
must be evaluated, and the update scheduled, before the statement
completes execution, but the actual update happens later.

Then, (2) is asserting, that "non-blocking ASSIGNMENTS shall be
performed in the order the statements were executed".
This is one of those things that was originally nondeterministic, but
was then specified to match Verilog-XL behavior that users were relying
on. The LRM is specifying that the updates for nonblocking assignments
must occur in the same order that the statements were executed. So if
you do two nonblocking assignments to the same variable in consecutive
statements in a begin-end block, the variable will end up with the
second value. (1) ensures that the second statement executes second,
and (2) ensures that the updates will occur in the same order that the
statements executed.

In the older LRMs, there was still text from the Verilog-XL manual that
said that the order of the updates was nondeterministic. This
contradicted item (2), and should have been eliminated when the
decision was made to have it be deterministic. There have been some
very tortured attempts to find interpretations that satisfied both
pieces of text, from people who didn't realize that they were
contradictory and that one was supposed to have superceded the other.

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?
Yes. You should look at the pseudocode in 5.4 of 1364-2001. This
shows that nonblocking assign update events are not activated until
there are no more active or inactive events. In other words, you don't
update nonblocking assigns until all normal zero-delay event
propagation has settled.

This is the basis for most usage of nonblocking assignments. This
delay to a special later queue, even though it is still a zero delay,
is sufficient to resolve many zero-delay race conditions. It provides
a special "larger zero" hold time that is sufficient to exceed any
number of levels of normal zero delays in the clock paths. The same
thing could have been accomplished by the use of small non-zero
clock-to-output delays in flop models instead.
 
Alex wrote:
I am trying to educate myself not from implementation (existing verilog
simulators) but from specification (Verilog standard).
This is a bit dangerous. The section on scheduling semantics was
grafted onto the standard rather late in the process. It uses
terminology that is not used anywhere else in the standard. It tries
not to disallow any behavior of Verilog-XL or other simulators of the
time, and in the process allowed so much nondeterminism that it would
be hard to write working Verilog if it were taken too literally. At
the same time, it codified behavior that was originally intended to be
nondeterministic, but where users had started relying on the behavior
of the Verilog-XL implementation. It takes a lot of side knowledge to
interpret properly. This is unfortunate, but true in practice.

(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.
The behavior of nonblocking assignments causes this awkward wording.
Where it refers to ASSIGNMENT, it is talking about the actual updating
of the value of the variable. With a
blocking assignment statement, the statement cannot complete execution
and continue with the next statement until the value has been updated.
With a nonblocking assignment, the RHS (and any indexes in the LHS)
must be evaluated, and the update scheduled, before the statement
completes execution, but the actual update happens later.

Then, (2) is asserting, that "non-blocking ASSIGNMENTS shall be
performed in the order the statements were executed".
This is one of those things that was originally nondeterministic, but
was then specified to match Verilog-XL behavior that users were relying
on. The LRM is specifying that the updates for nonblocking assignments
must occur in the same order that the statements were executed. So if
you do two nonblocking assignments to the same variable in consecutive
statements in a begin-end block, the variable will end up with the
second value. (1) ensures that the second statement executes second,
and (2) ensures that the updates will occur in the same order that the
statements executed.

In the older LRMs, there was still text from the Verilog-XL manual that
said that the order of the updates was nondeterministic. This
contradicted item (2), and should have been eliminated when the
decision was made to have it be deterministic. There have been some
very tortured attempts to find interpretations that satisfied both
pieces of text, from people who didn't realize that they were
contradictory and that one was supposed to have superceded the other.

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?
Yes. You should look at the pseudocode in 5.4 of 1364-2001. This
shows that nonblocking assign update events are not activated until
there are no more active or inactive events. In other words, you don't
update nonblocking assigns until all normal zero-delay event
propagation has settled.

This is the basis for most usage of nonblocking assignments. This
delay to a special later queue, even though it is still a zero delay,
is sufficient to resolve many zero-delay race conditions. It provides
a special "larger zero" hold time that is sufficient to exceed any
number of levels of normal zero delays in the clock paths. The same
thing could have been accomplished by the use of small non-zero
clock-to-output delays in flop models instead.
 
Alex wrote:
Here is the definition of stratified queue from Verilog standard:

------------------------------------------------------------------------
5.3 The stratified event queue
....

Sorry, but I cannot extract the features you've mentioned from the
implementation details of stratified event queue.
You have to combine the definition of the queues from 5.3 with the
algorithm for processing the queues from 5.4. That gives you the
behavior of nonblocking assignments happening only after all the other
events for that time have been processed.

In fact, I don't see
nothing related to execution of start ... end blocks.
That is because the discussion of events is primarily targeted at the
execution order of different processes with respect to each other. It
is largely assumed that you understand that order of execution within a
single process follows the normal conventions of programming languages.
But 5.4.1 does explicitly tell you that statements in begin-end blocks
execute in order.

There is the rigamarole about allowing a begin-end to suspend in favor
of executing another process, and then resume later. If taken to
extremes, this would make the language very hard to use, since many
common practices would become nondeterministic. This seems to have
been stated partly to allow for simulator optimizations involving
inlining of one process into another. For example, when an always
block updates a variable, a simulator might immediately update a net
that is assigned from that variable. This can be viewed as suspending
the always block, executing the continuous assignment, and then
resuming the always block. But no simulator is going to arbitrarily
suspend one process to execute another, unless there is at least some
kind of event-driven connection between them.

This statement may also have been intended to allow for some kind of
parallel simulation, with processes running in parallel on different
processors. But while such things have always sounded good in theory,
they have never turned out to be practical in reality.

The scheduling semantics aren't really that complicated. With few
exceptions, in real simulators, processes run until they deliberately
suspend at an event control or delay control. There may be some
apparent exceptions for optimizations like inlining of fanout. The
order of execution of different processes that are ready to run at the
same time is generally nondeterministic. There is a special rule for
nonblocking assignments that requires their update order to
deterministically match their execution order. And nonblocking
assignment updates don't occur until all the rest of the events for
that simulation time are finished (though of course the nonblocking
assignment updates may start a new series of zero-delay event
propagation and eventually another set of nonblocking assignment
updates, all for the same time). The $monitor and $strobe tasks run
after all that has settled. Since they are not supposed to be able to
change anything, they really run at the end of the slice.

There is that business about #0 and inactive events, but it is an ugly
kludge. It is also another example of people relying on what
Verilog-XL did, and getting it codified in the LRM (and specified
incorrectly there too). It is just bad practice, and best avoided.
 
ankitks@yahoo.com wrote:
my question is both always can go in parralle (since their sensitivity
list are now change together). But it doesn't..right? why?
1. Because we simulate them on a sequential processor, which requires
that we execute one of them first (though the standard would actually
allow us to interleave them or execute them in parallel).

2. Even if we executed them in parallel, we still either read 'next' in
the first always block or update 'next' in the second always block
before doing the other. It is nondeterministic. So you could either
get the old or new value. This is called a race condition. This is
not only an error in your Verilog code, it is a design error in
hardware also. Look up the terms "setup time" and "hold time" for real
flip-flops to help you understand this. Changing the data at the same
time as the clock is a design error. In real hardware, changing the
data at too close to the same time as the clock is a design error, with
the timing requirements set by the properties of the device being used.
 
Sorry, I asked wrong question. I mean to say -> why we executed always
@(posedge clk) first not always@(state or cent5) first. Since clk and
cent5, both are going from 0->1 at posedge of clk.

thanks.
 
ankitks@yahoo.com writes:

Sorry, I asked wrong question. I mean to say -> why we executed always
@(posedge clk) first not always@(state or cent5) first. Since clk and
cent5, both are going from 0->1 at posedge of clk.

thanks.
The simulator can choose to execute either first. It is
non-deterministic (meaning you cannot determine) which always block
executes first or whether they are executed in parallel or interleaved
or any other pattern.

Steve Sharp's comment on that case is right. If your signals change
too close to the clock edge, then you have a design problem. Such
problems are usually called "setup" or "hold" time problems, because
the model of how circuitry works, is that you need the signal to
arrive some amount of time before the clock edge (the setup time) and
be steady at that value for a certain length of time (the hold time).

If your signal doesn't do that, it violates the premises of digital
design. And, if that happens, your circuit may work and it may not.
Equally important, your simulation may work or may fail, but that
doesn't really prove that your circuit works or fails. When you
violate the premises, all bets are off.

Some of the money spent on validation is to detect exactly the cases
where the signals are too close to the clock edges, because in big
designs the delays of the gates and the wires can make signals arrive
slower than one expects, and if a signal arrives too late, the circuit
won't behave as designed.

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)
------------------------------------------------------------------------------
 
ankitks@yahoo.com wrote:
Sorry, I asked wrong question. I mean to say -> why we executed always
@(posedge clk) first not always@(state or cent5) first. Since clk and
cent5, both are going from 0->1 at posedge of clk.
If they both happen at the same time independently, then the always
blocks could execute in either order. There is nothing in the language
or the real world that will give priority to one over the other. This
would be a race between the clock and an asynchronous input to the
circuit. Asynchronous inputs to a circuit can create serious problems
and generally require special attention to synchronization. This goes
beyond timing races, into something called metastability.
 

Welcome to EDABoard.com

Sponsor

Back
Top