variable vs signal

B

benradu

Hi everyone,
I have a simulation mismatch in Modelsim when using variables and
signals.
for example:
a variable supposed to take its value from another one in a process,
on the rising edge actually takes the value as it would be outside of
the process.
but if I take those variables and declare them as signals, then they
take the values as expected.
Sample code:
process(clk)
variable a : std_logic_vector(7 downto 0);
variable b : std_logic;
begin
if rising_edge(clk) then
a := my_signal;
b := a(7) and other_signal; -- b takes the value in the same clock
cycle as a
-- if signals, b
takes the value in the next clock cycle
end if;
end process;

Why this difference?
Thank you!
Ben
 
D

Dave

Hi everyone,
I have a simulation mismatch in Modelsim when using variables and
signals.
for example:
a variable supposed to take its value from another one in a process,
on the rising edge actually takes the value as it would be outside of
the process.
but if I take those variables and declare them as signals, then they
take the values as expected.
Sample code:
process(clk)
variable a : std_logic_vector(7 downto 0);
variable b : std_logic;
begin
if rising_edge(clk) then
a := my_signal;
b := a(7) and other_signal; -- b takes the value in the same clock
cycle as a
-- if signals, b
takes the value in the next clock cycle
end if;
end process;

Why this difference?
Thank you!
Ben

This is not a simulation mismatch. This is the difference between
signals and variables. Variables are updated immediately, and signals
are not updated until the process has been exited. So when "a :=
my_signal" is executed, a is immediately given the value of my signal,
and any references to 'a' will give the same value as a reference to
my_signal. If signals were used and the line were "a <= my_signal",
the value of 'a' would not change until the end of the process.
Therefore, and other references to 'a' in the process would give the
original value of 'a', not the value of my_signal. This is why another
register is inserted if 'a' is signal as opposed to a variable.
 
S

Shannon

When I began learning VHDL recently this subject turned out to be the
single most important concept. Really look at this until you
understand and know it cold. I still trip on it from time to time.
My suggestion is use a RTL viewer of your choice and compile a whole
bunch of simple, short pieces of code and look at what gets produced.
Change things back and forth from variables to signals and see what
changes.

Shannon
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
If you wan't to learn more about Variables vs. Signal must you try the interactive VHDL book, EVITA.
Specially chapter 6 do have some good examples.

Download free from Aldec.com

Regards
Jeppe
 
H

HT-Lab

Dave said:
On Mar 17, 11:22 am, (e-mail address removed) wrote:

This is not a simulation mismatch. This is the difference between
signals and variables. Variables are updated immediately, and signals
are not updated until the process has been exited. So when "a :=
my_signal" is executed, a is immediately given the value of my signal,
and any references to 'a' will give the same value as a reference to
my_signal. If signals were used and the line were "a <= my_signal",
the value of 'a' would not change until the end of the process.
Therefore, and other references to 'a' in the process would give the
original value of 'a', not the value of my_signal. This is why another
register is inserted if 'a' is signal as opposed to a variable.


In addition to Dave's comment I would suggest you use the list window in
Modelsim to learn about delta issues. Use the example below and make sure
you understand why it behaves like it does.


clk2 <= clk; -- Combinatorial clock assignment!

process (rst, clk)
begin
if(rst = '0')then
s0 <= '0';
elsif(clk'event and clk='1') then
s0 <= inp;
end if;
end process;

process (rst, clk2)
begin
if(rst = '0')then
s1 <= '0';
elsif(clk2'event and clk2='1') then
s1 <= s0;
end if;
end process;

Hans
www.ht-lab.com
 
J

Jim Lewis

Dave
This is not a simulation mismatch. This is the difference between
signals and variables. Variables are updated immediately, and signals
are not updated until the process has been exited. So when "a :=
my_signal" is executed, a is immediately given the value of my signal,
and any references to 'a' will give the same value as a reference to
my_signal. If signals were used and the line were "a <= my_signal",
the value of 'a' would not change until the end of the process.
Therefore, and other references to 'a' in the process would give the
original value of 'a', not the value of my_signal. This is why another
register is inserted if 'a' is signal as opposed to a variable.

I mostly agree, except I have a minor nit with:
"signals are not updated until the process has been exited"

This rule is ok for RTL code that at most uses one wait statement (for
expressing clock), however, it is not a very good rule when you
start to consider any code that has multiple wait statements - such
as a testbench.

A better rule is: A signal does not update until the process
suspends at either a sensitivity list or a wait statement.

Best,
Jim
 
D

Dave

Dave



I mostly agree, except I have a minor nit with:
"signals are not updated until the process has been exited"

This rule is ok for RTL code that at most uses one wait statement (for
expressing clock), however, it is not a very good rule when you
start to consider any code that has multiple wait statements - such
as a testbench.

A better rule is: A signal does not update until the process
suspends at either a sensitivity list or a wait statement.

Best,
Jim

Jim,

I know, I know. I thought about mentioning delta cycles, but felt that
this might have been outside of the OP's realm of knowledge, so I
tried to keep it simple. In doing so, I was somewhat inaccurate.
 
D

David Binnie

If you use a varable and signal in the same code, the synthesis tool will
'slow up' the signals to make the rules work.

Suggest use only signals if speed is important.
 
A

Andy

David,

Do you have any examples of how using variables with signals causes
the synthesis tool to "slow up" the signals? Or are you referring to
the fact that using a signal in a clocked process always results in a
register, and therefore a clock cycle delay, or "slowing" of the
result?

I have yet to see a case where using variables vs signals affected the
performance of the resulting synthesized circuit, other than if they
were not functionally the same in the first place (i.e. same cycle-by-
cycle behavior at each register).

Referencing a variable can result in either a registered or a
combinatorial value access, based on whether the variable had been
previously written within the same clock cycle.

Naturally, if variables are used to describe a complex operation in
one clock cycle, compared to using signals to describe the same
operation over multiple clock cycles, the latter will often operate at
higher maximum clock frequencies because there will be less logic
between successive registers. But if both techniques are used to
describe the same operation, over the same registers/cycles, the
results should not differ.

Andy
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
PHP:
process(clk)
   variable a : std_logic_vector(7 downto 0);
   variable b : std_logic;
begin
      if rising_edge(clk) then
          b := a(7) and other_signal; 
          a := my_signal;                   -- Note the order of statements
      end if;
 end process;

Try this - now it works ok, just by changing the order of statements :)

Your welcome
Jeppe
 
Last edited:
D

David Binnie

I just mean this:

architecture behv of sig_var is
signal sig_s1: std_logic;
begin
proc1: process(clock)
variable var_s1: std_logic;
begin
if clock'event and clock='1'
then var_s1 := d1;
sig_s1 <= d1;
res1 <= var_s1 xor d2;
res2 <= sig_s1 xor d2;
end if;
end process;
end behv;

With the variable in the code the signal path is one delay behind what it
would be otherwise.
 
M

Mike Treseler

David said:
I just mean this:

architecture behv of sig_var is
signal sig_s1: std_logic;
begin
proc1: process(clock)
variable var_s1: std_logic;
begin
if clock'event and clock='1'
then var_s1 := d1;

Statement order matters with variables.
var_s1 must be on the right before left
or this is a wire.

sig_s1 <= d1;
res1 <= var_s1 xor d2;
res2 <= sig_s1 xor d2;

We seem to have the ones and twos mixed up.
Both problems are fixed here:

http://home.comcast.net/~mike_treseler/sig_var.vhd

Note that both channels synthesize the same way here:

http://home.comcast.net/~mike_treseler/sig_var.pdf

-- Mike Treseler
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
Yes I agree - a signal will first get its value when the process ends. A variable will get its value immediatly.

But just try this:

PHP:
architecture behv of sig_var is
    signal sig_s1: std_logic;
begin
    proc1: process(clock)
         variable var_s1: std_logic;
    begin
         if clock'event and clock='1' then 

              sig_s1 <= d1;
              res1    <= var_s1 xor d2;
              res2    <= sig_s1 xor d2;
              var_s1 := d1;                   -- Note the order
          end if;
     end process;
end behv;

Your welcome
Jeppe
 
D

David Binnie

Sorry wrong 1s and 2s were typos,

but didn't know that about order of varables.

ta,

db
 
A

Andy

Statement order matters with variables.
var_s1 must be on the right before left
or this is a wire.


We seem to have the ones and twos mixed up.
Both problems are fixed here:

http://home.comcast.net/~mike_treseler/sig_var.vhd

Note that both channels synthesize the same way here:

http://home.comcast.net/~mike_treseler/sig_var.pdf

-- Mike Treseler

What Mike said...

Variables execute just like software. If the process has to wait for
the next clock cycle until a value propagates from one variable to
another, then the synthesis tool will insert a register to make that
clock cycle delay happen.

Unlike signal assignments in clocked processes, which always represent
storing data in a register, variables are different. It is the
REFERENCE to a variable, relative to when it was last assigned, that
causes that reference to be to a registered or combinatorial version
of the value.

If the variable is read BEFORE being written in a clock cycle, then
the read reference is to a REGISTERED value of the variable.

If the variable is read AFTER being written in a clock cycle, then the
read reference is to a COMBINATORIAL value of the variable.

In this way, multiple references to the same variable can represent
both registered and combinatorial values in the same process. If the
variable is conditionally written before being read, then the
conditional will also drive a mux to select the register or
combinatorial value for the subsequent variable reference.

It is important not to think of sequential vhdl code like a netlist;
think of it in terms of its cycle-by-cycle behavior, and that
determines what gets synthesized.

Andy
 
K

kennheinrich

It is important not to think of sequential vhdl code like a netlist;
think of it in terms of its cycle-by-cycle behavior, and that
determines what gets synthesized.

Andy

This is more true than many people realize. I've actually been to a
VHDL course where the instructor, sadly, was *absolutely certain* that
the moment you used a variable (instead of a signal) anywhere in a
process, it meant you were erroneously instantiating a register. You
can't just make sweeping generalizations like that; you have to take
Andy's advice: think what the code does when you execute it, and ask
if that will require a register or not.

- Kenn
 
M

Mike Treseler

This is more true than many people realize. I've actually been to a
VHDL course where the instructor, sadly, was *absolutely certain* that
the moment you used a variable (instead of a signal) anywhere in a
process, it meant you were erroneously instantiating a register.

That is unfortunate. It is easy to run a synthesis
for a simple example, and therfore silly to speculate
about it instead.

However, as Andy points out,
the reason for using variables
isn't to complicate the rules of
register inference, it is to hand
over this job to synthesis and to instead
debug by tracing code and watching for
expected values in simulation.

At some point, a design becomes to complicated
to play "where's the flip flop?"

-- Mike Treseler
 
C

Colin Paul Gloster

Kenn posted in
in "Re: variable vs signal" on Thu, 20 Mar 2008 17:38:41 -0700 (PDT):
|----------------------------------------------------------------------|
| |
|> |
|> It is important not to think of sequential vhdl code like a netlist;|
|> think of it in terms of its cycle-by-cycle behavior, and that |
|> determines what gets synthesized. |
|> |
|> Andy |
| |
|This is more true than many people realize. I've actually been to a |
|VHDL course where the instructor, sadly, was *absolutely certain* that|
|the moment you used a variable (instead of a signal) anywhere in a |
|process, it meant you were erroneously instantiating a register. You |
|can't just make sweeping generalizations like that; you have to take |
|Andy's advice: think what the code does when you execute it, and ask |
|if that will require a register or not. |
| |
| - Kenn" |
|----------------------------------------------------------------------|

May I ask who this was, and whether the instructor's employer of
the time continued to to employ the instructor?

Regards,
Colin Paul
 

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

Forum statistics

Threads
474,169
Messages
2,570,916
Members
47,458
Latest member
Chris#

Latest Threads

Top