Why usign a Variable here won't work ?

L

LC

Hi,

I'm puzzled...

This code in (1) works great (function kind of obvious, to generate one
clock-width pulse every rise transition of a trigger signal).

while the code in (2) does not work. No errors/warnings
only fails to produce logic that works as expected.
(I originally thought of using this version (2) since
"tv_sr" is absolutely local to this process... but
stepped into this strange issue)(or pure ignorance !!!)

Anyone take out of the dark, please ??
Thanks.

(I'm using QuartusII-8.1)


Luis C.



(1)
....etc...
SIGNAL tv_sr: STD_LOGIC_VECTOR (1 downto 0);
....etc...
sample_trigger: PROCESS(clock)
BEGIN
IF (clock='1' AND clock'EVENT)
THEN
tv_sr(0) <= trig_in;
tv_sr(1) <= tv_sr(0);

IF (tv_sr="01") THEN trig_smp <='1';
ELSE trig_smp <='0';
END IF;
END IF;
END PROCESS sample_trigger;


(2)
....etc...
sample_trigger: PROCESS(clock)
VARIABLE tv_sr: STD_LOGIC_VECTOR (1 downto 0);
BEGIN
IF (clock='1' AND clock'EVENT)
THEN
tv_sr(0) := trig_in;
tv_sr(1) := tv_sr(0);

IF (tv_sr="01") THEN trig_smp <='1';
ELSE trig_smp <='0';
END IF;
END IF;
END PROCESS sample_trigger;
 
D

Dave

Hi,

I'm puzzled...

This code in (1) works great (function kind of obvious, to generate one
clock-width pulse every rise transition of a trigger signal).

while the code in (2) does not work. No errors/warnings
only fails to produce logic that works as expected.
(I originally thought of using this version (2) since
"tv_sr" is absolutely local to this process... but
stepped into this strange issue)(or pure ignorance !!!)

Anyone take out of the dark, please ??
Thanks.

(I'm using QuartusII-8.1)

Luis C.

(1)
...etc...
SIGNAL  tv_sr:  STD_LOGIC_VECTOR (1 downto 0);
...etc...
sample_trigger: PROCESS(clock)
BEGIN
        IF (clock='1' AND clock'EVENT)
        THEN
                tv_sr(0) <= trig_in;
                tv_sr(1) <= tv_sr(0);

                IF (tv_sr="01")       THEN    trig_smp <='1';
                                ELSE    trig_smp <='0';
                END IF;                                
        END IF;
END PROCESS sample_trigger;

(2)
...etc...
sample_trigger: PROCESS(clock)
VARIABLE tv_sr: STD_LOGIC_VECTOR (1 downto 0);
BEGIN
        IF (clock='1' AND clock'EVENT)
        THEN
                tv_sr(0) := trig_in;
                tv_sr(1) := tv_sr(0);

                IF (tv_sr="01")       THEN    trig_smp <='1';
                                ELSE    trig_smp <='0';
                END IF;                                
        END IF;
END PROCESS sample_trigger;

Variables and signals behave in fundamentally different ways.
Basically, a signal assignment does not update the signal's value
immediately, but instead delays the update until the end of the
process. A variable assignment updates the variable's value
immediately. This difference means that a variable does not always
imply a register, though it may be in a clocked process.
 
M

Mike Treseler

LC said:
while the code in (2) does not work. No errors/warnings
only fails to produce logic that works as expected.

It works like I would expect.
Try tracing code.
IF (clock='1' AND clock'EVENT)
THEN
tv_sr(0) := trig_in;

-- tv_sr(0) has value trig_in
tv_sr(1) := tv_sr(0);

-- tv_sr(0) has value trig_in so "00" or "11"
IF (tv_sr="01") THEN

-- can't happen


-- Mike Treseler
 
C

Chris Abele

Dave said:
Variables and signals behave in fundamentally different ways.
Basically, a signal assignment does not update the signal's value
immediately, but instead delays the update until the end of the
process. A variable assignment updates the variable's value
immediately. This difference means that a variable does not always
imply a register, though it may be in a clocked process.

As Dave says a variable is updated immediately, so the sequence
[tv_sr(0) := trig_in;] followed by [tv_sr(1) := tv_sr(0);] means that
tv_sr(0) and tv_sr(1) are both set to trig_in. Consequently the test
[IF (tv_sr="01")] can never be true, and you'll never get an output pulse.

I think that if you swap the order of the assignment statements this
might work, but the output pulse will occur one time step sooner than it
will in your example (1).

That's my best guess, anyway.

Chris
 
L

LC

Thanks for your help.

Following your valuable help I thought it should
be also possible using variables and I tried as
follows:

tv_sr := tv_sr(0)&trig_in;

and it works fine.

--

Is it bad practice to write things this
way or the other way (with signals) ? or is irrelevant ?

(I'm trying to build a more solid way of
thinking about VHDL code writing
in the hope of having less and less issues)

Again, Many thanks.

Luis C.
 
K

KJ

Is it bad practice to write things this
way or the other way (with signals) ? or is irrelevant ?

As a general statement, it is not relevant whether you use variables
or signals. Your goals should be:
1. The code functionally performs what it is expected to perform.
This rule must always be met, no exceptions.
2. Is easy to understand. If variables happen to make it easier in a
particular case, use variables. If signals make it easier, use
signals.

Since it appears that the whole reason you ran into this is because
you were trying to make a signal more 'local' to the only place in the
architecture where it is intended to be used, let me point out two
other places where signals can be declared that localizes there usage
in the same fashion that variable are local to a process. VHDL has
'generate' and 'block' statements within which a signal can be
declared which is visible only within the block or generate in the
same way that a variable is visible only within a process. The syntax
for how you declare signals within a generate or block is shown
below. As you can see, the effort is really no different than it is
for a variable. Bottom line is that whether you use a signal or a
variable should depend on rule #2 above and not on limiting the scope
or visibility of the signal/variable.

SOME_BLOCK : block
signal My_Local_Signal: std_ulogic;
begin
-- Put all your code here, concurrent statements or processes
-- Try it out by putting all of the code for the entire arch-
-- itecture inside a block
end SOME_BLOCK;

SOME_GENERATE : if (1=1) generate
signal My_Local_Signal: std_ulogic;
begin
-- Put all your code here, concurrent statements or processes
-- Try it out by putting all of the code for the entire arch-
-- itecture inside a block

-- Note: Generate statements can also be of the form
-- "for i in 1 to 4 generate" as well as the "if" conditional
-- form shown above.
end SOME_GENERATE;

(I'm trying to build a more solid way of
thinking about VHDL code writing
in the hope of having less and less issues)

You violated rule #1 by not verifying that form (2) was equivalent to
(1) by using a simulator. The best way to get "a more solid way of
thinking about VHDL code writing" is by writing code and using a
simulator to verify that the design functions as intended. It is far
quicker than debugging on any form of live hardware. Having said that
though, posting questions here can also lead to learning new
techniques and best practices of those who've already climbed the
learning curve...not to mention finding out about the best prices on
Nike shoes and Gucci bags.

Kevin Jennings
 
L

LC

Kevin, Very valuable tips many tks.
> You violated rule #1 by not verifying that form (2) was equivalent to
> (1) by using a simulator.

yep.. Guilty I admit (I'm an hardware guy)
Naturally the carpenter first attempt uses wood... only
after some failures he considers iron as a solution ;-)

lc.
 
N

Nicolas Matringe

LC a écrit :
Kevin, Very valuable tips many tks.


yep.. Guilty I admit (I'm an hardware guy)
Naturally the carpenter first attempt uses wood... only
after some failures he considers iron as a solution ;-)
Well I think most of the people in this newsgroup consider themselves as
harware guys, and we certainly all use a simulator :)

Nicolas
 
M

Mike Treseler

Brian said:
Which means that to achieve the desired semantics (use the previous value, then
update the variable), you have to describe the task backwards...

I might say, "describe the task from the top down" ;)

tv_sr(1) := tv_sr(0);

tv_sr(0) := trig_in;

I like to combine lines when possible to
simplify assignment ordering.
In this case, something like

rise_v := bool2bit(tv_sr_v = "01");
tv_sr_v := tv_sr_v(0) & trig;

-- Mike Treseler
 
M

Mike Treseler

LC said:
I thought it should
be also possible using variables and I tried as
follows:

tv_sr := tv_sr(0)&trig_in;

and it works fine.

Well done.
I did the same thing.
Is it bad practice to write things this
way or the other way (with signals) ? or is irrelevant ?

Mostly irrelevant.
It depends how much interest I have in the craft of
vhdl simulation and synthesis.
If I found that a nuisance, I might stick
with structural code and just power through it.
If I found it fun, I might gild the lilly a bit.

(I'm trying to build a more solid way of
thinking about VHDL code writing
in the hope of having less and less issues)

Sounds like you're on your way.
Good luck.

-- Mike Treseler



_____________________________________________
library ieee;
use ieee.std_logic_1164.all;
entity rise is

port (reset,clock : in std_ulogic;
trig : in std_ulogic;
rise : out std_ulogic
);
end entity rise;

-- Thu Nov 12 12:39:15 2009 M.Treseler
architecture synth of rise is
begin
sample_trigger : process(reset, clock) is

function bool2bit (arg : boolean) return std_ulogic
is variable ret_v : std_ulogic;
begin
case arg is
when true => ret_v := '1';
when others => ret_v := '0';
end case;
return ret_v;
end function bool2bit;

variable tv_sr_v : std_logic_vector (1 downto 0);
variable rise_v : std_ulogic;
begin
if reset = '1' then
-- reset variables here
tv_sr_v := (others => '0');
rise_v := '0';
elsif rising_edge(clock) then
-- update output regs here
rise_v := bool2bit(tv_sr_v = "01");
-- update input regs here
tv_sr_v := tv_sr_v(0) & trig;
end if;
rise <= rise_v; -- update ports here for free reset wiring
end process sample_trigger;
end architecture synth;
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top