variable vs signal

Guest
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
 
On Mar 17, 11:22 am, benr...@gmail.com wrote:
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.
 
"Dave" <dhschetz@gmail.com> wrote in message
news:349f4551-833a-46bd-9049-401050d8afe5@b1g2000hsg.googlegroups.com...
On Mar 17, 11:22 am, benr...@gmail.com 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
 
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

On Mar 17, 9:11 am, benr...@gmail.com wrote:
Thank you Dave! You enlightened me a little.
Ben
 
Dave
On Mar 17, 11:22 am, benr...@gmail.com wrote:
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.
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
 
On Mar 17, 3:40 pm, Jim Lewis <j...@synthworks.com> wrote:
Dave

On Mar 17, 11:22 am, benr...@gmail.com wrote:
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.

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.
 
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.

<benradu@gmail.com> wrote in message
news:28d90ee3-4b75-4d16-b052-3704b8f220b0@i29g2000prf.googlegroups.com...
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
 
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
 
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.



"Andy" <jonesandy@comcast.net> wrote in message
news:6ff6ce56-ea31-4710-85a4-14bc6adfc93f@e39g2000hsf.googlegroups.com...
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
 
David Binnie wrote:

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
 
Sorry wrong 1s and 2s were typos,

but didn't know that about order of varables.

ta,

db
 
On Mar 20, 2:56 pm, Mike Treseler <mike_trese...@comcast.net> wrote:
David Binnie wrote:
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
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
 
On Mar 20, 7:50 pm, Andy <jonesa...@comcast.net> wrote:

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
 
On Mar 20, 7:50 pm, Andy <jonesa...@comcast.net> wrote:
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.
kennheinrich@sympatico.ca wrote:
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
 
Kenn posted in
news:cd914add-97b3-49f2-a5ff-50a15cad13fb@p73g2000hsd.googlegroups.com
in "Re: variable vs signal" on Thu, 20 Mar 2008 17:38:41 -0700 (PDT):
|----------------------------------------------------------------------|
|"On Mar 20, 7:50 pm, Andy <jonesa...@comcast.net> wrote: |
| |
|> |
|> 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
 

Welcome to EDABoard.com

Sponsor

Back
Top