Verilog AutoMode Problem ??

Guest
Hi all,

When I do

always @(/*AS*/)begin
x = a+y;
z = x+p;
end

this in automode expands to -

always @(/*AS*/a or y or p)begin
x = a+y;
z = x+p;
end

Clearly leaves "x" out of the sensitvity list. So when x is updated as
a result of a or y
changing - z is not.
Does anyone know if Automode was fixed and if so in what release ???

Thanks for your help,

Raj Mitra
 
I meant this is what is questionable -

always @(/*AS*/)begin
z = x + p;
x = a + y;
end

expands to -

always @(/*AS*/ a or y or p)begin
z = x + p;
x = a + y;
end

and this causes simulation to mismatch the desired intent.
 
It wouldn't help to have x in the event control. At the time that you
are assigning to x, the always block is not waiting at the event
control. It is performing the assignment. After it finishes the
assignment, it will loop back to the top of the always block and start
waiting at the event control again, after x has already changed. So it
will not evaluate again until p or a or y changes again.

If you manually put x into the event control, you will see that it
still doesn't work. You need to rewrite the body of your always block.
You need to evaluate x before using it, just as in a normal
programming language.
 
When I do

always @(/*AS*/)begin
x = a+y;
z = x+p;
end

this in automode expands to -

always @(/*AS*/a or y or p)begin
x = a+y;
z = x+p;
end

Clearly leaves "x" out of the sensitvity list. So when x is updated as
a result of a or y
changing - z is not.
Why do you believe z does not change when x does? The entire always
block is executed when any one of a, y, or p changes. Thus, when one
of those variables is changed, the always block first updates x and
then updates z. If your simulator isn't doing this, then there is
something else going on that you aren't showing us (or there is a bug
in your simulator).

Now, if you change x in another always block, then z will not get
updated, but running this always block would change the value of x
(from whatever your other always block changes it to) back to the sum
of a and y.

You do not need (nor even generally want x to be in the sensitivity
list for this always block), x is an output of the always block.

If you are getting some kind of pre/post-synthethsis mismatch from
this code, it would be useful to see more context. This code doesn't
look wrong and doesn't look problematic to synthesize.

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)
------------------------------------------------------------------------------
 
Sharp / Chris,
I am sorry I should make myself a little more clear -

always @(/*AS*/ a or y or p)begin
z = x + p;
x = a + y;
end

Here is my understanding -
- The block is evaluated procedurally each time a change is detected in
any of the signals in the sensitivity list. It is never evaluated
otherwise.
- Say "a" changed. Then "z" is updated with the old value of x first;
next "x" is updated. This is clearly not the desired effect.
- If we switch the order of the equations then x is updated first then
"z". This is the desired effect. This is what Sharp pointed out
that things should happen procedurally.
- Yes Sharp, I agree that putting "x" into the sensitivity list does
not change things. So AUTOMODE does the correct thing.
- So Chris, the above explanation points out that when "z" is updated,
it is updated with an older value of "x" since procedurally
the "x" update comes later to the "z" update. However, synthesis does
not care about "ordering" in the blocks and synthesizes
each equation as if they were "assign" statements. This could clearly
result in simulation mismatches bewteen gates and RTL.
-Why am I doing this ?? Well I have a piece of RTL infested with assign
statements and its killing my simulation runtimes. I need
to consolidate all my assign statements into procedural blocks and a
script helps achieve this. Of course I did not take into account
"equation" ordering as Sharp pointed out. This needs to be put into my
script.
-Thanks for your help follks...

-Raj
 
The statement that "The block is evaluated each time a change is
detected in any of the signals in the sensitivity list" is only
approximately true. It is true if those changes are made from outside
the block, while the block is waiting at the event control. In that
usual case, it is a convenient way to think about it. But if you make
changes from inside the procedural code, it is no longer a valid
description. Verilog does not have "sensitivity lists"; it has event
controls. It is the event control that detects a change in the
signals, and it only does so when you are waiting at it.

If you are going to group these assignments together this way, you will
need to sort them in order of their dependencies, as you said.

You also don't want to overdo this grouping, or it will actually start
hurting your simulation performance. Grouping may reduce the overhead
for switching between evaluations, but it may also cause you to do
unnecessary evaluation. Consider your example. If a or y changes,
then x will probably also change, and you will probably need to
evaluate "z = x + p" anyway. But if only p changes, then you are
evaluating "x = a + y" when you didn't have to. Group too many things
together, and this will start to cost you more than you are saving.
 
Aaah.. Right. Thanks for that insight. Based on your suggestion I am
going to
group the blocks by functionality. So whenever a block is evaluated,
the assignments
within are so chosen that they are likely to be updated.
That was very helpful...

-Raj
 
Raj wrote (in replying to Steve Sharp):
Aaah.. Right. Thanks for that insight. Based on your suggestion I am
going to
group the blocks by functionality. So whenever a block is evaluated,
the assignments
within are so chosen that they are likely to be updated.
That was very helpful...
First, sorry that I didn't see your post where the stmts were in the
"wrong" order, that would have made it clear that Steve's answer was
pointing out the correct problem.

By the way, what you are trying to do is to roughly recreate a
cycle-based simulator (as opposed to an event driven one). There are
tradeoffs there that are very subtle. We use an in-house cycle based
simulator and get very good (i.e. fast) results from it. However, it
is tuned to the chips we design and doesn't attempt to implement the
entire Verilog language (although the percentage that it does
implement keeps growing larger as we add more users).

However, given that your issue is slow simulation times, perhaps you
should try using another simulator to see if it isn't faster. I don't
know which simulator you are using, but I know even within event
driven simulators there are large differences in speed. There is even
a commercially available cycle-based simulator that appears quite fast
in the benchmarks I've seen. It is from Carbon Design.

If you want to continue to pursue this work by hand, what you want to
do is a "topolgical sort". Start all variables that are "state
devices", generally those are ones assigned in always blocks (usually
with edge sensitivity on some clock), call these variables "roots".
Now, find all the variables that only depend on root variables, call
these level 1 variables. Now, find the variables that depend only on
root and level 1 variables, call these level 2. Repreat this process,
until all variables have a level. If you overlook a state variable,
you will find a cyclic loop that you can't resolve, and you will have
to make that variable a root variable to get the process to work out.

Once you have done this, you have a dependency tree, so you know
which variables depend on which others, all the way back to your
clocks. You can further cluster this tree, by looking at sets of root
variables that are likely to change together. Your dependency tree
gives you the order you need to evaluate the variables in your always
blocks. The clustering gives you which variables you should put into
the same always block. Note, as Steve mentioned, if you make your
clusters too big, you may actually slow your simulation down.

If you write a program to do this, you have written the heart of the
"compilation phase" of a cycle based simulator.

To me the worst aspect of this, is that you might change the
functionality of the chip, as you did by accident when you reordered
the x and z assignments. If I were doing this, I would want to do
something that checks that I hadn't changed the design in the process,
e.g. a logical equivalency check. If you get your speed improvement
from switching simulators instead of changing the Verilog, you only
have to worry about the bugs in the new simulator, not ones you have
introduced by changing the design.

In any case, best of luck,
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)
------------------------------------------------------------------------------
 
Why not use:
always @* begin
x = a+y;
z = x+p;
end
or
always_comb begin
x = a+y;
z = x+p;
end
or
assign x = a+y;
assign z = x+p;
It seems almost all the functions provided by AutoMode has also been
provided by verilog2001 or system verilog, supported by all commercial
EDA tool for years.

T
 

Welcome to EDABoard.com

Sponsor

Back
Top