How do variables get synthesized in this case?

D

Duke

Hey,

I am new with using variables in VHDL and am wondering how it gets
synthesized in the following case:
If you understand it can you also please explain why it gets
synthesized the way you think it does?

process(a)
variable x: integer;
variable y:integer;
variable z:integer;
begin
x:= 1;
if (a=1) then
x:=2;
end if

for i in 0 to 4 loop
y := i+x;
if(y>d) then
y := y - d;
end if
end if

if(b = 2) then
z:= y;
end if
end process
 
M

Mike Treseler

Duke said:
Hey,

I am new with using variables in VHDL and am wondering how it gets
synthesized in the following case:

It doesn't.
Synthesis is port to port.
Add an entity.
And maybe a synchronous process for useful synthesis.

-- Mike Treseler
 
J

Jacko

Hi
(1) We can see that (a) is a signal, because the
process is sensitised to it.  By contrast, we
know nothing about (b) and (d).  If they are
signals rather than constants, then it would
probably be a cool idea to put them in the
sensitivity list too.  In fact, it's Bloody
Stupid (tm) to do otherwise.

It implies simulation will be differnt from produced logic, but not
necessarily create a different functioning. All reasonable sythesis
tools produce logic as though they had been included in the
sensitivity list, it's just easier.

It main effect is to produce wrong transition counts for simulation,
and possibly make power estimation density wrong. It does offer the
possible implicit optimizations of not performing function stste
changes if a signal changes which is not on the sensitivity list, as
per simulation.

Most synthesis tools ignore this possibility of power optimization.

The code given will optimize to nothing with most tools.

cheers jacko

p.s. I can hear the screams at BloodyStupid(tm) head office. The
typing , oooh the long names, the list growing, oooh no, not the list
arrrrgh!!
 
K

kennheinrich

Hey,

I am new with using variables in VHDL and am wondering how it gets
synthesized in the following case:
If you understand it can you also please explain why it gets
synthesized the way you think it does?

process(a)
variable x: integer;
variable y:integer;
variable z:integer;
    begin
      x:= 1;
      if (a=1) then
         x:=2;
      end if

      for i in 0 to 4 loop
          y := i+x;
          if(y>d) then
            y := y - d;
         end if
     end if

     if(b = 2) then
      z:= y;
    end if
end process

Duke,

As has been mentioned, this code will get optimized away. But what
you *might* have been asking (and I'm taking a shot in the dark here)
is, were you to have forced the simulator to explicitly keep the
process around, and trace what it did, what would you have seen? In
that case, the values you would see would be more or less consistent
with what you'd expect if x,y,z were plain ordinary variables in your
favorite imperative programming language (C or perl or whatnot) - the
fact that none of the values of any of the variables get re-used in
successive executions of the process means there's nothing
"interesting" going on from a synthesis point of view. By interesting,
I mean inferring latches or flip-flops.

And from a slightly more contrarian position: were "a","b" or "d" to
have been declared as impure 0-ary functions performing I/O (textio,
asserts, reports, etc), then one could argue that, from a *simulation*
point of view, that the process is not, in the strictest sense, navel-
gazing. But for synthesis, I concur with the majority opinion - your
code will simply vanish.

- Kenn
 
K

kennheinrich

Duke,

As has been mentioned, this code will get optimized away.  But what
you *might* have been asking (and I'm taking a shot in the dark here)
is, were you to have forced the simulator to explicitly keep the
process around, and trace what it did, what would you have seen? In
that case, the values you would see would be more or less consistent
with what you'd expect if x,y,z were plain ordinary variables in your
favorite imperative programming language (C or perl or whatnot) - the
fact that none of the values of any of the variables get re-used in
successive executions of the process means there's nothing
"interesting" going on from a synthesis point of view. By interesting,
I mean inferring latches or flip-flops.

And from a slightly more contrarian position: were "a","b" or "d" to

erratum: for "a","b", or "d" : read "b" or "d"
 
A

Andy

erratum: for "a","b", or "d" : read "b" or "d"





- Show quoted text -- Hide quoted text -

- Show quoted text -

Ignoring the impacts of optimization (deleting unused outputs, and
everything that only drives them), there are some problems with the
code.

Specifically, z is not always assigned a value, which would result in
a latch were z not to be optimized out in the first place, whether z
were a variable or signal. Latches are an inherent risk in
combinatorial processes. The same situation in a clocked process
merely results in a clock disable on a register, and/or (with
variables) a mux between the input and output of the register, where z
might be referenced subsequently. Interestingly, the output of the
implied clock-disabling feedback mux, before the register input, is
exactly what is needed for successive references to the conditionally
assigned variable.

Because y is overwritten in each loop iteration, the whole loop
collapses to just the last iteration of the loop, ignoring the
previous iterations. This has nothing to do with signals vs variables.
The typical impact on truly iterative loops of variables vs signals is
that since signals do not get updated until the process suspends,
there is no real iteration upon signals inside a loop (assuming there
are no wait statements in the loop). Since variables do update
immediately, iteration upon the variable is possible, it is just not
demonstrated in the example. Just remember that all loops not
containing wait statements are simply unrolled during synthesis. Not
all synthesis tools can handle loops with wait statements (i.e.
waiting on the next clock edge), but that is probably beyond the
intended scope of discussion.

Because sensitivity lists are ignored in synthesis, the synthesis of x
is unrelated to variable vs signal behavior. Were x a signal, the
synthesis result would assume x were also in the sensitivity list, and
the resulting behavior would be identical to that of a variable x. In
simulation, if x were a signal, and included in the process
sensitivity list, it would cause the process to immediately run again
with the updated value of x, thus allowing propagation to the
subsequent references to x within the process.

So, in effect, most of the behavior of the code, even ignoring the
effects of optimization during synthesis, really does not have much to
do with variable vs signal behavior.

Andy
 
K

kennheinrich

Ignoring the impacts of optimization (deleting unused outputs, and
everything that only drives them), there are some problems with the
code.

Specifically, z is not always assigned a value, which would result in
a latch were z not to be optimized out in the first place, whether z
were a variable or signal. Latches are an inherent risk in
combinatorial processes. The same situation in a clocked process
merely results in a clock disable on a register, and/or (with
variables) a mux between the input and output of the register, where z
might be referenced subsequently. Interestingly, the output of the
implied clock-disabling feedback mux, before the register input, is
exactly what is needed for successive references to the conditionally
assigned variable.

Of course, you're right. I missed seeing the loop in the def-use graph
for "z". I like the description of how two paths through the
dependency graph (one uninitialized, hence carried over from the last
execution, and one initialized, hence from current execution) has a
synthesis interpretation as a simple clock enable when used in a
clocked process.
 
J

Jacko

On Mon, 16 Mar 2009 15:50:35 -0700 (PDT), Jacko wrote:

[incomplete sensitivity list]
implies simulation will be differnt from produced logic,

Indeed.  That fits my understanding of Bloody Stupid
pretty well.

Just because simulation is lazy by not actually simulating the
netlist, you assume much.
Could you kindly translate that for me?  I have no
idea what you mean.  Either synthesis and simulation
match, or they don't.  You seem to be saying that
there is some third alternative.

Yes simulation tool support alternative of simulating netlist, so not
forgetting to alter some logic levels, or synthesis creates latches
which prevent unnecessay transistions, saving power, and the simulator
agrees with lazy evaluation. You will find a critical subset of
sensitivity which will always cause evaluation correctly, i.e. if a
signal is used later in a process, and assigned earlier in a process,
then it need not be in the list. For correct logic simulation, only
true dependant signals need to cause logic re-evaluation, i.e. the
process is performed correctly to the sensitivities supplied.
All tools I know do so, and produce a warning message
precisely because it is not "reasonable".

No, because it may not be what is expected. It may be reasonable.
Easy and wrong doesn't work for me.

Easier to list them all....
I can imagine asynchronous design techniques (latches) in which
asynch processes could be given incomplete sensitivity lists
to imply lack of state change on some signal transitions.
In a sense that's precisely what the standard clocked
process template does (in VHDL it is functionally unaffected
if you include all inputs in the senstivity list).  But
given the present state of the synthesis art, I'm not
keen to try that kind of asynchronous trick.

And the tool will refuse to do it, warn, and then give you the output
as though all were in the list.
Which is why we all want wildcard sensitivity lists for the
(few) occasions when we need combinational processes.
Respect to SystemVerilog for getting it right with
always_comb.  Boo-hiss to VHDL for holding out for
so many years against the obviously sensible
   process(all)
so that now it's probably too late and no-one will
take any notice of it.


tis sensible. it beats always() with the extra reserved word needed.
 
M

Martin Thompson

Jacko said:
On Mon, 16 Mar 2009 15:50:35 -0700 (PDT), Jacko wrote:

[incomplete sensitivity list]
implies simulation will be differnt from produced logic,

Indeed.  That fits my understanding of Bloody Stupid
pretty well.

Just because simulation is lazy by not actually simulating the
netlist, you assume much.

Isn't that backwards? VHDL is a simulation language. You simulate
your code until it works.

Then you run a synthesiser over the same code and it produces you a
netlist which (in theory) matches your code that you so carefully
wrote and verified.

(Clearly the word "you" in the above should be replaced by "other
engineers", or indeed "I" :)

If the synth doesn't translate that code into a functionally
equivalent netlist, how is that the simulator's fault? Of course we
just have to work with the fact that synth tools do what they do,
which leads me to avoid non-clocked processes wherever possible, but I
don't have to like it, or try and make out it's the way things
"should" work.

There are always going to be things that simulate that the synth can't
turn into a netlist, but is it valid for it just to go "well, here's
something a bit like it" flag a quick warning (in amongst a morass of
other warnings) and call "job done".

<rant>
And the example under discussion isn't even one where the synth-tool
*can't* do the job conforming to the language spec, it just chooses
not to! It's like a C-compiler changing 'i++' to '++i' "because
that's usually what people want to happen when they write that".
</rant>

(snip)
No, because it may not be what is expected. It may be reasonable.

Why is it reasonable to not work as the language spec defines it?

(snip)
Cheers,
Martin
 
J

Jacko

Jacko said:
On Mon, 16 Mar 2009 15:50:35 -0700 (PDT), Jacko wrote:
[incomplete sensitivity list]
implies simulation will be differnt from produced logic,
Indeed. That fits my understanding of Bloody Stupid
pretty well.
Just because simulation is lazy by not actually simulating the
netlist, you assume much.

Isn't that backwards? VHDL is a simulation language. You simulate
your code until it works.

In this case you will be suprised about the number of possible logic
transitions on any signal, when the do not propergate to change the
state of another signal. Most sythesizers will generate the logic
which has the extra state changes of signals (as it is easier).
Then you run a synthesiser over the same code and it produces you a
netlist which (in theory) matches your code that you so carefully
wrote and verified.

It will match your code in boolean logic function of registered values
if all critical sensitivities are included. It may not match your code
if you miss one, hence the warning. All non critical ones may produce
a warning, but would not change the functioning of the code.

So there are 3 types of referred to signal.

process(clk)
fart <= smelly;
nose <= fn(fart);
end process;

in this instance having fart in the sensitivity list is pointless but
still makes a warning.

with process(clk,smelly) everything will simulate correctly but still
cause a warning.

with process(clk,fart) changes in smelly would not be relevant, and
could be register delayed through clk.
(Clearly the word "you" in the above should be replaced by "other
engineers", or indeed "I" :)

If the synth doesn't translate that code into a functionally
equivalent netlist, how is that the simulator's fault? Of course we
just have to work with the fact that synth tools do what they do,
which leads me to avoid non-clocked processes wherever possible, but I
don't have to like it, or try and make out it's the way things
"should" work.

There are always going to be things that simulate that the synth can't
turn into a netlist, but is it valid for it just to go "well, here's
something a bit like it" flag a quick warning (in amongst a morass of
other warnings) and call "job done".

<rant>
And the example under discussion isn't even one where the synth-tool
*can't* do the job conforming to the language spec, it just chooses
not to! It's like a C-compiler changing 'i++' to '++i' "because
that's usually what people want to happen when they write that".
</rant>
umm.



Why is it reasonable to not work as the language spec defines it?

No. "why is it reasonable? *reasonable??* well you write the b**tard
thing then!!" :)

It may be reasonable to want such registration of values to prevent
such signal oscillation for power saving reasons, hence REASONable.

cheer jacko
 
M

Mike Treseler

Jacko said:
In this case you will be suprised about the number of possible logic
transitions on any signal, when the do not propergate to change the
state of another signal. Most sythesizers will generate the logic
which has the extra state changes of signals (as it is easier).

Every synthesizer I have used has generated a well
minimized netlist that matches my simulation.

It is up to me, of course,
to follow a reasonable synchronous template.

-- Mike Treseler
 
M

Martin Thompson

Jacko said:
In this case you will be suprised about the number of possible logic
transitions on any signal, when the do not propergate to change the
state of another signal. Most sythesizers will generate the logic
which has the extra state changes of signals (as it is easier).

I was talking about simulators, you're seem to continue to talk about
synthesisers...
It will match your code in boolean logic function of registered values
if all critical sensitivities are included.

That's what happens - I'm saying what I (and many others?) want to happen.
It may not match your code if you miss one, hence the warning. All
non critical ones may produce a warning, but would not change the
functioning of the code.

<snip tutorial>

Sorry - I know how VHDL works. There's even a specification for it -
if only all the tools followed it ;)

I put a lot of effort into verifiying my code in a simulator. I don't
want downstream tools to change how it works. What if I explicitly
don't want my circuit to respond to changes on one of those input
signals for some reason?

No. "why is it reasonable? *reasonable??* well you write the b**tard
thing then!!" :)

It may be reasonable to want such registration of values to prevent
such signal oscillation for power saving reasons, hence REASONable.

Are you saying that there are things which couldn't be accomplished if
the synthesier and the simulator worked in the same way?

What can't you do (that you can do now) if the synthesiser actually
used the sensitivity list in the same way as the simulator.

Cheers,
Martin
 
J

Jacko

I was talking about simulators, you're seem to continue to talk about
synthesisers...



That's what happens - I'm saying what I (and many others?) want to happen..


<snip tutorial>

Sorry - I know how VHDL works.  There's even a specification for it -
if only all the tools followed it ;)

I put a lot of effort into verifiying my code in a simulator.  I don't
want downstream tools to change how it works.  What if I explicitly
don't want my circuit to respond to changes on one of those input
signals for some reason?

<snip>










Are you saying that there are things which couldn't be accomplished if
the synthesier and the simulator worked in the same way?

What can't you do (that you can do now) if the synthesiser actually
used the sensitivity list in the same way as the simulator.

Cheers,
Martin

--
(e-mail address removed)
TRW Conekt - Consultancy in Engineering, Knowledge and Technologyhttp://www.conekt.net/electronics.html- Hide quoted text -

- Show quoted text -

Nothing!! nibzB.vhd not yet available will have the seperate D_I and
D_O and correct sensitivity to them. From my minimum state change
prospective.

cheers jacko

http://nibz.googlecode.com
 
D

Dave

It will match your code in boolean logic function of registered values
if all critical sensitivities are included. It may not match your code
if you miss one, hence the warning. All non critical ones may produce
a warning, but would not change the functioning of the code.

So there are 3 types of referred to signal.

process(clk)
  fart <= smelly;
  nose <= fn(fart);
end process;

in this instance having fart in the sensitivity list is pointless but
still makes a warning.

with process(clk,smelly) everything will simulate correctly but still
cause a warning.

with process(clk,fart) changes in smelly would not be relevant, and
could be register delayed through clk.

Correct me if I'm wrong here, but if 'fart' were not in the
sensitivity list, wouldn't it be that 'nose' wouldn't get the correct
value? Since 'fart' is not updated until a delta cycle later, the
process would need to fire again for 'nose' to get the results of the
function for the new 'fart'. But without 'fart' in the list, the
process won't fire upon 'fart' changing, and 'nose' represents the
value from the old 'fart'.

Dave
 
A

Andy

Correct me if I'm wrong here, but if 'fart' were not in the
sensitivity list, wouldn't it be that 'nose' wouldn't get the correct
value? Since 'fart' is not updated until a delta cycle later, the
process would need to fire again for 'nose' to get the results of the
function for the new 'fart'. But without 'fart' in the list, the
process won't fire upon 'fart' changing, and 'nose' represents the
value from the old 'fart'.

Dave

You are correct. Fart will not propagate from smelly to nose until a
clock cycle later (or as written, a half clock cycle, since the
process will fire on both rising and falling edges of the clock). This
may be one of the most common misunderstandings in all of vhdl, but if
it were not for this "feature" then race conditions would abound
throughout VHDL. Simple variables, since they are not shared between
processes, can safely update immediately without hazarding a race
condition.

Andy
 
A

Andy

Nothing!! nibzB.vhd not yet available will have the seperate D_I and
D_O and correct sensitivity to them. From my minimum state change
prospective.

cheers jacko

http://nibz.googlecode.com

If you simulated nibzA.vhd, you would see what the difference between
simulation and synthesis is WRT the following simplification of your
example:

process(smelly) is
begin
fart <= smelly;
nose <= fn(fart);
end process;

The combinatorial processes in nibzA.vhd exhibit this mistake a few
times too.

Andy
 
J

Jacko

If you simulated nibzA.vhd, you would see what the difference between
simulation and synthesis is WRT the following simplification of your
example:

process(smelly) is
begin
  fart <= smelly;
  nose <= fn(fart);
end process;

The combinatorial processes in nibzA.vhd exhibit this mistake a few
times too.

Andy

Yes, I have not ignored the warnings, they are still there. The fact
that sythesis in Quartus II 8.0 seems to not use the simulation
understanding is of small education on such a design.

On a large design, the power density limits of a material
semiconductor may be exceeded by such differing 'easy' sythesis vs.
'lazy' simulation outcomes.

So process(all) should be augmented with process(enough) or some such
suitable enumeration generic ting.

or maybe just process() which would appear to be a useless process
template.

cheers jacko

a.k.a. doc sith (dark side pesant revolutionary front :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top