question about the verilog standard.

  • Thread starter katelman@gmail.com
  • Start date
K

katelman@gmail.com

Guest
I was reading the following post on deepchip and it got me wondering
about something...

http://www.deepchip.com/items/0428-09.html

suppose I have the following:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

and that somehow a = b = 0 when simulation starts. By the reasoning of
the deepchip post, once the a = 1 update event happens, the always
block can execute its body and stop in the middle, so x = 1 + 0 = 1
and y is unassigned, then b = 1 can execute and since the always
block hasn't made it back to the @, it doesn't sense b to re-evaluate.
Therefore, when it resumes y = 1 + 1 = 2, but x does not get re-
evaluated and the end result is x = 1. Therefore, this
nondeterministically allows for x = 1 or x = 2 when simulation
finishes? correct? Thanks.

-Mike
 
On Fri, 3 Apr 2009 11:14:09 -0700 (PDT)
"katelman@gmail.com" <katelman@gmail.com> wrote:

I was reading the following post on deepchip and it got me wondering
about something...

http://www.deepchip.com/items/0428-09.html

suppose I have the following:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

and that somehow a = b = 0 when simulation starts. By the reasoning of
the deepchip post, once the a = 1 update event happens, the always
block can execute its body and stop in the middle, so x = 1 + 0 = 1
and y is unassigned, then b = 1 can execute and since the always
block hasn't made it back to the @, it doesn't sense b to re-evaluate.
Therefore, when it resumes y = 1 + 1 = 2, but x does not get re-
evaluated and the end result is x = 1. Therefore, this
nondeterministically allows for x = 1 or x = 2 when simulation
finishes? correct? Thanks.

-Mike
If you read the Verilog standard more carefully, you'll notice that
there is a guarantee that this won't happen. x and y will always be 2
in Verilog. Think of it this way: once a=1 starts, the always block
cannot be triggered until b=1 finishes.

--
And now for something completely different.
 
On Apr 3, 5:55 pm, Jason Zheng <Xin.Zh...@jpl.nasa.gov> wrote:
On Fri, 3 Apr 2009 11:14:09 -0700 (PDT)



"katel...@gmail.com" <katel...@gmail.com> wrote:
I was reading the following post on deepchip and it got me wondering
about something...

http://www.deepchip.com/items/0428-09.html

suppose I have the following:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
 x = a + b;
 y = a + b;
end

and that somehow a = b = 0 when simulation starts. By the reasoning of
the deepchip post, once the a = 1 update event happens, the always
block can execute its body and stop in the middle, so x = 1 + 0 = 1
and y is unassigned, then b = 1  can execute and since the always
block hasn't made it back to the @, it doesn't sense b to re-evaluate.
Therefore, when it resumes y = 1 + 1 = 2, but x does not get re-
evaluated and the end result is x = 1. Therefore, this
nondeterministically allows for x = 1 or x = 2 when simulation
finishes? correct? Thanks.

-Mike

If you read the Verilog standard more carefully, you'll notice that
there is a guarantee that this won't happen. x and y will always be 2
in Verilog. Think of it this way: once a=1 starts, the always block
cannot be triggered until b=1 finishes.

--
And now for something completely different.
Thank your for your demeaning response! However, both the post I
linked and the standard (section 9.9) disagree with your assertion
that the initial block must finish before the always block is
triggered. Who to believe? You have your considerable aplomb, but the
synopsys engineer and standard writers have some authority as well I
SHOULD THINK!

Contrary to your baseless assertion about my knowledge of the
standard, I have spent a considerable amount of time reading it. It's
not the clearest document. The purpose of my post wasn't to get
exasperated answers, but rather some thoughtful justification based on
the language of the standard why it should do what you say, or why it
should do something else. I'm not interested in building hardware
(otherwise I would just write predicatable Verilog) but I am
interested in understanding the semantics at a deeper level.

-Mike
 
katelman@gmail.com wrote:
I was reading the following post on deepchip and it got me wondering
about something...

http://www.deepchip.com/items/0428-09.html

suppose I have the following:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

and that somehow a = b = 0 when simulation starts. By the reasoning of
the deepchip post, once the a = 1 update event happens, the always
block can execute its body and stop in the middle, so x = 1 + 0 = 1
and y is unassigned, then b = 1 can execute and since the always
block hasn't made it back to the @, it doesn't sense b to re-evaluate.
Therefore, when it resumes y = 1 + 1 = 2, but x does not get re-
evaluated and the end result is x = 1. Therefore, this
nondeterministically allows for x = 1 or x = 2 when simulation
finishes? correct? Thanks.

-Mike
Hmmm,
I didn't read the entire deep chip post, but I never ever heard of this
kind of race condition and IMHO it wouldn't make sense.

If you have multiple always blocks with the same or similiar triggers
you might not know what happens first.

example:
initial a=3;
always @(a) $display("Will I be the first");
always (@a) $display("Or will I be the first");


but a verilog simulator should never 'task switch' / 'interrupt'
between two statements without delay.
This would needlessly slow down the simulation.


so back to your example:
initial begin // No other verilog code will be executed
a = 1;
b = 1;
end // until you arrive here
// (because no delays/forks/.joins or @

always @(a or b) begin // this will wait till a or b changes
x = a + b; // from here on code is non 'interruptible'
y = a + b;
end // till end is reached


bye

N
 
On Fri, 3 Apr 2009 11:14:09 -0700 (PDT), "katelman@gmail.com"
<katelman@gmail.com> wrote:

I was reading the following post on deepchip and it got me wondering
about something...

http://www.deepchip.com/items/0428-09.html

suppose I have the following:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

and that somehow a = b = 0 when simulation starts. By the reasoning of
the deepchip post, once the a = 1 update event happens, the always
block can execute its body and stop in the middle, so x = 1 + 0 = 1
and y is unassigned, then b = 1 can execute and since the always
block hasn't made it back to the @, it doesn't sense b to re-evaluate.
Therefore, when it resumes y = 1 + 1 = 2, but x does not get re-
evaluated and the end result is x = 1. Therefore, this
nondeterministically allows for x = 1 or x = 2 when simulation
finishes? correct? Thanks.

-Mike
Technically what you're suggesting is possible based on the standard
but I think it's unlikely because it wouldn't make much sense as an
optimization. The reason simulators suspend execution is to be able to
reduce queue operations ie always @(a,b) would suspend at x= ... so
that the consequences of it can be resolved quickly. To me it seems
that a LIFO stack would be much more efficient here so initial would
suspend because of a=... then always would suspend because of x=...
and when the third block (not shown) is done, the simulator would get
back to always finish it, then initial and then continue with more
events in the queue.
In this scenario what you're suggesting does not happen. If the
simulator makes different choices it may. Of course if someone comes
up with a multi-threaded verilog simulator all bets are off and we
need completely new algorithms to make things faster and be
"compliant" with verilog-xl; probably that's why we have very few
multi-threaded verilog simulators.

Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services
http://www.dspia.com
 
Hi Kal,

Muzaffer Kal wrote:
Of course if someone comes
up with a multi-threaded verilog simulator all bets are off and we
need completely new algorithms to make things faster and be
"compliant" with verilog-xl; probably that's why we have very few
multi-threaded verilog simulators.

Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services
http://www.dspia.com

In fact before posting I was also thinking shortly about potential
multithread simulators, Seeing, that the MIPs of a processor don't
increase that much, but that there's more and more multicore CPUs, this
might well something we see in the not to far future.


I'd guess, such simulator might break a lot of verilog code if only
following the Verilgo standard.

Things would probably work out though. if such kind of 'cross modifying'
always blocks were forced to simulate always in the same thread.

Simplest would probably be to split threads only on synchronous boundaries.


bye
 
On Apr 5, 8:54 am, News123 <news...@free.fr> wrote:
Hi Kal,

Muzaffer Kal wrote:
Of course if someone comes
up with a multi-threaded verilog simulator all bets are off and we
need completely new algorithms to make things faster and be
"compliant" with verilog-xl; probably that's why we have very few
multi-threaded verilog simulators.

Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services
http://www.dspia.com

In fact before posting I was also thinking shortly about potential
multithread simulators, Seeing, that the MIPs of a processor don't
increase that much, but that there's more and more multicore CPUs, this
might well something we see in the not to far future.

I'd guess, such simulator might break a lot of verilog code if only
following the Verilgo standard.

Things would probably work out though. if such kind of 'cross modifying'
always blocks were forced to simulate always in the same thread.

Simplest would probably be to split threads only on synchronous boundaries.

bye
I would actually be surprised to see at multi-threaded simulator, at
least if the justification is performance. I'd personally rather be
able to use my extra cores to spawn more constrained-random simulation
instances, or whatever, and don't really sit around waiting for single
simulations to finish running. Maybe I'm the exception?

-Mike
 
Hi Michael,


Michael Katelman wrote:
I would actually be surprised to see at multi-threaded simulator, at
least if the justification is performance. I'd personally rather be
able to use my extra cores to spawn more constrained-random simulation
instances, or whatever, and don't really sit around waiting for single
simulations to finish running. Maybe I'm the exception?
Hi Michael.

I guess you're right in 90% if the cases.
Mostly it's just better to run multiple simulations of a regression.

And perhaps it doesn't make sense to write special multithreaded
simulations for the other 10%.


Concerning the other 10% though:

There are simulations, (for example in the multimedia accelerator
domain, that are being used during development and that can be quite
time consuming. 30min to a few hours)

In order to validate a small change in a complex system it might be
useful to have a an iteration cycle (code change plus one simulation/
verification) wich is 2x - 4x shorter.


N.
 
On Sun, 5 Apr 2009 12:23:04 -0700 (PDT), Michael Katelman
<katelman@gmail.com> wrote:
I would actually be surprised to see at multi-threaded simulator, at
least if the justification is performance. I'd personally rather be
able to use my extra cores to spawn more constrained-random simulation
instances, or whatever, and don't really sit around waiting for single
simulations to finish running. Maybe I'm the exception?
There are always cases where single execution performance is an
important criteria. One is during development/debugging phase where
the simulator is being used more or less in an interactive fashion and
edit/compile/debug cycle time is important.
The other is throughput per license. It's true that hardware is cheap
and one can add more cores to get more regressions but licenses still
cost money. Depending on how multi-core capable licenses would be
priced, it may still make sense to get a faster simulator (ie run it
over many cores) and get more regressions per time per license that
way.
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
On Apr 5, 9:08 pm, Muzaffer Kal <k...@dspia.com> wrote:
On Sun, 5 Apr 2009 12:23:04 -0700 (PDT), Michael Katelman

katel...@gmail.com> wrote:
I would actually be surprised to see at multi-threaded simulator, at
least if the justification is performance. I'd personally rather be
able to use my extra cores to spawn more constrained-random simulation
instances, or whatever, and don't really sit around waiting for single
simulations to finish running. Maybe I'm the exception?

There are always cases where single execution performance is an
important criteria. One is during development/debugging phase where
the simulator is being used more or less in an interactive fashion and
edit/compile/debug cycle time is important.
The other is throughput per license. It's true that hardware is cheap
and one can add more cores to get more regressions but licenses still
cost money. Depending on how multi-core capable licenses would be
priced, it may still make sense to get a faster simulator (ie run it
over many cores) and get more regressions per time per license that
way.
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
That's a really interesting insight into the development
process for new simulators. It reminds me of a product
introduced to save on electric bills at hotels. The
device does not actually save electricity, but causes
the electric usage in any 15 minute period to be capped.
Why? Because the electric rate for large institutions
is based on peak demand measured over - drumroll... -
a 15 minute period!

So here you're pointing out that actually 100% of the
use cases of a simulator would benefit from multi-
threading, if only to reduce licensing cost.

Regards,
Gabor
 
On Mon, 6 Apr 2009 16:29:29 -0700 (PDT), hairyotter
<marco.bramb@gmail.com> wrote:

Thank you everybody for all the insights, I am finding this very
interesting as well.

However, I think I might use some clarification.


using the example above:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

As already reported, the verilog standard (11.4.2 in 1364-2005)
explicitly states that execution can be suspended, and that the order
of interleaved execution is nondeterministic.
However, I have a "problem" with this.
What if, for whatever reason:

- a = 1 is executed and the initial suspended
- the always process is triggered, the x = a+b executed and then the
process suspended
- the initial is resumed, executes b=1, but the always is no longer
listening to a.

End result, x wrong, y correct.

Please note: I do not see a reason in the world why a simulator would
want to do this, it's just that the verilog standard allows for it, so
I'm wondering how would you get out safely.
If you really have to, the safe way is to write:

always @(a or b) begin
x = a + b;
end

always @(a or b) begin
y = a + b;
end

which is how real hardware behaves.


--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
Hi Mike,

Just another viewpoint:

I have (and my customers as well) simulations that, at RTL level, take
from several hours to a couple of days EACH.

I agree that if you're just running regressions it might be more
important to run as many as possible in parallel, but when you're
still debugging a testcase, getting to the end as quickly as possible
becomes mandatory.

At the same time, at this point we have 16-core machines easily.
If I could allocate 4 regressions on each machine, ecah taking 4 cores
and speeding up ~4x, the turnaround time of a last-minute ECO would be
much faster, provided management can be convinced to buy enough CPUs

However, it will cost much less to invest in more processing than
waiting a week for the regressions to end.
And if you have no speedup you can have as many machines as you want,
but no speedup.

However, I do not know what percentage of companies do big chips,
let's say > 40Mgates + 100Mbit sram or edram

Ciao, Marco

I would actually be surprised to see at multi-threaded simulator, at
least if the justification is performance. I'd personally rather be
able to use my extra cores to spawn more constrained-random simulation
instances, or whatever, and don't really sit around waiting for single
simulations to finish running. Maybe I'm the exception?

-Mike
 
I not entirely convinced yet that the big three will come out with a
marvelous licensing plan.
I have seen something going more or less on the right direction, but
not there yet

Ciao, Marco.

So here you're pointing out that actually 100% of the
use cases of a simulator would benefit from multi-
threading, if only to reduce licensing cost.
 
Thank you everybody for all the insights, I am finding this very
interesting as well.

However, I think I might use some clarification.


using the example above:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

As already reported, the verilog standard (11.4.2 in 1364-2005)
explicitly states that execution can be suspended, and that the order
of interleaved execution is nondeterministic.
However, I have a "problem" with this.
What if, for whatever reason:

- a = 1 is executed and the initial suspended
- the always process is triggered, the x = a+b executed and then the
process suspended
- the initial is resumed, executes b=1, but the always is no longer
listening to a.

End result, x wrong, y correct.

Please note: I do not see a reason in the world why a simulator would
want to do this, it's just that the verilog standard allows for it, so
I'm wondering how would you get out safely.

Thanks, Marco.
 
Hi Muzaffer,

thank you for your reply.

However, I respectfully disagree.

Or: I do agree that that is the way the code behaves in silicon, but I
disagree that I have to do it in the first place and that it would
solve the issue.

Again, verilog allows totally "random" execution.
This means that even in your example the first always could be stopped
after the assignment, then go back and execute "b" (before the always
is armed again) and the second always executed only after both a and b
are updated.
Again, wrong assigement.

Let this be clear: I DO KNOW that _I_ am making a mistake in my
interpretation of the standard, or that some other precautions are
taken by the simulator vendors, but I do not know which these are.

Actually, I do know how I would take care of that, but I'm trying to
understand if there is anybody who knows the standard sufficiently
well (or wrote some sim code) who can point me to where my mistake in
interpretation is.

Ciao, Marco.



On Apr 6, 5:47 pm, Muzaffer Kal <k...@dspia.com> wrote:
On Mon, 6 Apr 2009 16:29:29 -0700 (PDT), hairyotter



marco.br...@gmail.com> wrote:
Thank you everybody for all the insights, I am finding this very
interesting as well.

However, I think I might use some clarification.

using the example above:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

As already reported, the verilog standard (11.4.2 in 1364-2005)
explicitly states that execution can be suspended, and that the order
of interleaved execution is nondeterministic.
However, I have a "problem" with this.
What if, for whatever reason:

- a = 1 is executed and the initial suspended
- the always process is triggered, the x = a+b executed and then the
process suspended
- the initial is resumed, executes b=1, but the always is no longer
listening to a.

End result, x wrong, y correct.

Please note: I do not see a reason in the world why a simulator would
want to do this, it's just that the verilog standard allows for it, so
I'm wondering how would you get out safely.

If you really have to, the safe way is to write:

always @(a or b) begin
 x = a + b;
end

always @(a or b) begin
y = a + b;
end

which is how real hardware behaves.

--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
On Tue, 7 Apr 2009 21:55:31 -0700 (PDT), hairyotter
<marco.bramb@gmail.com> wrote:
Again, verilog allows totally "random" execution.
This means that even in your example the first always could be stopped
after the assignment, then go back and execute "b" (before the always
is armed again) and the second always executed only after both a and b
are updated.
This is not correct. A blocking assignment with no delay returns
immediately at which point the always is armed again. With a single
blocking assignment per always block (ie a single statement), your
example will execute correctly as "always" will be waiting at @(a or
b) when b is updated.

Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services
http://www.dspia.com
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


This shows up in the -2001 version of the standard as well. I do
not know of any simulator that interrupts a behavioral process at
any time other then at time control constructs. To do so would cause
utter chaos.

The problem is that the atomicity of execution is the only form
of synchronization that a Verilog programmer has. Without it,
cycle-based simulation would be nearly impossible. No compiler
intentionally violates that atomicity, and in the few cases where
Icarus Verilog did, I was handed a plate full of bug reports.

You'll have to ask some committee members why that paragraph is
there, but I think you will find that all the Verilog simulator
implementers are careful to not interrupt execution outside of
timing constructs. If you think you've found an instance, then
please do tell.

hairyotter wrote:
Thank you everybody for all the insights, I am finding this very
interesting as well.

However, I think I might use some clarification.


using the example above:

initial begin
a = 1;
b = 1;
end

always @(a or b) begin
x = a + b;
y = a + b;
end

As already reported, the verilog standard (11.4.2 in 1364-2005)
explicitly states that execution can be suspended, and that the order
of interleaved execution is nondeterministic.
However, I have a "problem" with this.
What if, for whatever reason:

- a = 1 is executed and the initial suspended
- the always process is triggered, the x = a+b executed and then the
process suspended
- the initial is resumed, executes b=1, but the always is no longer
listening to a.

End result, x wrong, y correct.

Please note: I do not see a reason in the world why a simulator would
want to do this, it's just that the verilog standard allows for it, so
I'm wondering how would you get out safely.

Thanks, Marco.

- --
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 v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFJ3L/ZrPt1Sc2b3ikRAvFsAKCd0rWL3bM1sKS7GWJaDSTXR/94wgCeMlrd
AlRrXvWrwn4bALzv6Gfw4oY=
=bvPC
-----END PGP SIGNATURE-----
 
On Fri, 3 Apr 2009 16:08:09 -0700 (PDT)
Michael Katelman <katelman@gmail.com> wrote:

On Apr 3, 5:55 pm, Jason Zheng <Xin.Zh...@jpl.nasa.gov> wrote:

If you read the Verilog standard more carefully, you'll notice that
there is a guarantee that this won't happen. x and y will always be
2 in Verilog. Think of it this way: once a=1 starts, the always
block cannot be triggered until b=1 finishes.

--
And now for something completely different.

Thank your for your demeaning response! However, both the post I
linked and the standard (section 9.9) disagree with your assertion
that the initial block must finish before the always block is
triggered. Who to believe? You have your considerable aplomb, but the
synopsys engineer and standard writers have some authority as well I
SHOULD THINK!

Contrary to your baseless assertion about my knowledge of the
standard, I have spent a considerable amount of time reading it. It's
not the clearest document. The purpose of my post wasn't to get
exasperated answers, but rather some thoughtful justification based on
the language of the standard why it should do what you say, or why it
should do something else. I'm not interested in building hardware
(otherwise I would just write predicatable Verilog) but I am
interested in understanding the semantics at a deeper level.
Mike,

You are right. I was basing on what I thought was on the 1995 standard
which turns out to be false. I didn't mean to make my post demeaning,
however. My apologies.

~Jason
 
On Wed, 8 Apr 2009 10:59:33 -0700 (PDT), Michael Katelman
<katelman@gmail.com> wrote:
....
Along these lines, Marco and Muzaffer's back-and-forth on

always @(a or b) begin
x = a + b;
end

is really the key question, at least in my mind. If you think of each
always block as having a sort of "program counter", then the question
is where are the legal spots for it to point? If I understand
correctly, Marco's interpretation is that there are two spots, the @(a
or b) and the x = a + b, and Muzaffer is treating the @(a or b) begin
x = a + b end as a single spot.
Here is what the always looks like for me:

always begin
@(a,b); // this is a timing control
x = a + b; // this is an executable statement
end

Using your terminology I think the PC can point to only executable
statements ie it points to after @(a,b) but that thread of execution
is suspended. When @(a,b) triggers, the next statement executes
immediately because it has no other timing controls, drops out of
always and gets suspended when it sees @(a,b) again but at that point
is pointing to the executable statement. @(a,b) is like a label not an
instruction (at least as far as I understand this).

"Another source of nondeterminism is that statements without time-
control constructs in behavioral
blocks do not have to be executed as one event."

The subtle thing that I'm wondering about is this: does the above
sentence imply that statements WITH A TIME CONTROL construct must be
executed as a single event?
I thought about this pretty hard too. I should say that Standardese is
probably my 4th language but I think what it is trying to say is that
"statements with a time control are not subject to this statement at
all" ie if a time control exists there can be no hope of atomicity ie
even the ones without a time control can not be expected to execute as
one event. If there is a time control the scheduler is bound to break
them up and execute them according to the strict requirements of the
time control. If there are none (time controls) one might be inclined
to assume atomicity but they "do not have to be executed as one
event".
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
Stephen Williams <spamtrap@icarus.com> writes:

This shows up in the -2001 version of the standard as well. I do
not know of any simulator that interrupts a behavioral process at
any time other then at time control constructs. To do so would cause
utter chaos.
Having also implemented a simulator (a cycle based one, based
primarily on the '95 standard), there were some cases where we would
break always blocks into fragments and execute them independently.
However, the conditions on when we would do so were fairly subtle.
The language did not require atomicity (and the intereactions of
always blocks and continuous assignments give one good reasons to
sometimes violate it), but the conditions as I recall are quite
non-intuitive about what you can rearrange (and what things are
deterministic across a variety of simulators). There are relevant
rules, although not all in one place, and they interact, and then
there is how much latitude the simulators exercise within those rules.

In the example as mentioned, atomicity is likely preserved. However,
if there is another path that can change a or b, through wires and
perhaps across module boundaries, things can become less secure,
especially if there is a race or glitch involved.
 

Welcome to EDABoard.com

Sponsor

Back
Top