Me and Variables Again !!!

L

LC

Hi,

Last time I posted about this your collective help was great
and educated me well into the use of variables versus signals
Albeit it looks that I'm destined to have issues about
that.

I have this part of code that generates pulses at the end
of write on a serial bus. It generates one "ser_valid" pulse
each transfer in addition it generates a "trig_soft" pulse
if the system is at a specific mode.

---

If sv_sr is a SIGNAL all works just fine.

If sv_sr is a VARIABLE the <number 1> works just
the same but the <number 2> doesn't (trig_soft remains at '0', always)

!!! Scratched my head and gave up...
WHY why why !!?!

(needless to say that the work progressed using a SIGNAL
but my mind is not in peace ;-)

---

soft_trigger: PROCESS (clock)

BEGIN
IF (clock='1' AND clock'EVENT) THEN

sv_sr <= sv_sr(0)&sld; -- commented if Var.
-- sv_sr := sv_sr(0)&sld; -- commented if Sig.

IF (sv_sr="10") -- number 1
THEN ser_valid <='1';
ELSE ser_valid <='0';
END IF;

IF (sv_sr="10" AND mode=SOFT_TRG) -- number 2
THEN trig_soft <='1';
ELSE trig_soft <='0';
END IF;

END IF;

END PROCESS soft_trigger;

---


Many thanks.


Luis C.
 
A

Andy

To clarify what Alan wrote, the two versions (signal and variable)
would work identically if both the variable and signal assignment are
moved to the end of the process. Moving the signal assignment has no
affect, except that when it is changed to a variable assignment, the
updated value is not seen until the next clock cycle, just as if it
had been a signal.

Another way to look at this whole thing is that it is not so much
where/when the assignment to a variable occurs, but where/when the
subsequent references to (reads of) that variable occur. In the above,
you would not so much be moving the assignment statements to the end,
but moving the variable references to the beginning, such that they
return the value from the previous clock cycle (if and only if you
need a register to get the clock-cyclic behavior you need). Multiple
references to the same variable can create both combinatorial and
registered logic, based on where/when those references occur relative
to the assignment(s).

Andy
 
L

LC

Andy said:
To clarify what Alan wrote, the two versions (signal and variable)
would work identically if both the variable and signal assignment are
moved to the end of the process. Moving the signal assignment has no
affect, except that when it is changed to a variable assignment, the
updated value is not seen until the next clock cycle, just as if it
had been a signal.

Another way to look at this whole thing is that it is not so much
where/when the assignment to a variable occurs, but where/when the
subsequent references to (reads of) that variable occur. In the above,
you would not so much be moving the assignment statements to the end,
but moving the variable references to the beginning, such that they
return the value from the previous clock cycle (if and only if you
need a register to get the clock-cyclic behavior you need). Multiple
references to the same variable can create both combinatorial and
registered logic, based on where/when those references occur relative
to the assignment(s).

Andy

Many Thanks,
I think I understood most of what you and Alain said.
But I'm still in pain ;-) as I did not get to the
bottom of this particular piece of code.

Lets just deal with the variable use scenario.

in my code there is only one assignment of a value
and it is in the beginning

and then two reads of the variable "sv_sr" are
done one after the other

no other assignments or anything else in between.


why at read nr1 it has one value

and at read nr2 it has another ?



Please be patient with me :)


Luis C.
 
L

LC

I know this will sound rude :) but it can't have a different value at
both places, the value must be the same. You can prove it by writing the
value out e.g.

use std.textio.all;
use ieee.std_logic_textio.all;

-- rest of entity and architecture

soft_trigger: PROCESS (clock)
variable L : LINE;
BEGIN
IF (clock='1' AND clock'EVENT) THEN

-- sv_sr <= sv_sr(0)&sld; -- commented if Var.

write(L, string'("nr1 = "));
write(L, sv_sr);
IF (sv_sr="10") -- number 1
THEN ser_valid <='1';
ELSE ser_valid <='0';
END IF;

write(L, string'(" nr2 = "));
write(L, sv_sr);
writeline(OUTPUT, L);
IF (sv_sr="10" AND mode=SOFT_TRG) -- number 2
THEN trig_soft <='1';
ELSE trig_soft <='0';
END IF;
sv_sr := sv_sr(0)&sld; -- commented if Sig.

END IF;

END PROCESS soft_trigger;
I guess the value of mode is significant...

Alan

Alain, many thanks for your help.

I know for sure that if sv_sr is a signal the NR2 starts
to work as expected and there was nothing else changed
anywhere in the code.

and

you must be right saying that value should be the
same in both NR1 and NR2 (no doubt about, now...I've
seen and I believe, tks :) )

and

by the time sv_sr equals "10", mode was already stable
and equal SOFT_TRG ages ago (so shows the simulator)

so this become an interesting puzzle !!!


crappy tools !!??!!! maybe.

yeap... good idea, I'll try this bit of code with a different set of tools.


Again, tks for helping.

Luis C.
 
A

Andy

Alain, many thanks for your help.

I know for sure that if sv_sr is a signal the NR2 starts
to work as expected and there was nothing else changed
anywhere in the code.

and

you must be right saying that value should be the
same in both NR1 and NR2 (no doubt about, now...I've
seen and I believe, tks :) )

and

by the time sv_sr equals "10", mode was already stable
and equal SOFT_TRG ages ago (so shows the simulator)

so this become an interesting puzzle !!!

crappy tools !!??!!! maybe.

yeap... good idea, I'll try this bit of code with a different set of tools.

Again, tks for helping.

Luis C.- Hide quoted text -

- Show quoted text -

Is this misbehavior observable in HW, or in gate-level/full-timing
simulation, and/or in RTL simulation? If either or both of the 1st
two, I would suspect an improperly synchronized input (sdl or mode) or
a timing problem (how fast is your clock?). Using the variable
(depending on where you assign and read it) may eliminate a register
that is created by the signal version, and that register may be
correcting your synchronization (of sdl). If the 3rd is happening,
you have a tool problem in your simulator, or your code is not exactly
as posted. You could try nesting the 2nd if-then inside the first, and
get rid of the 2nd comparison to "10", but this should not make any
difference.

Andy
 
L

LC

Andy said:
Is this misbehavior observable in HW, or in gate-level/full-timing
simulation, and/or in RTL simulation? If either or both of the 1st
two, I would suspect an improperly synchronized input (sdl or mode) or
a timing problem (how fast is your clock?). Using the variable
(depending on where you assign and read it) may eliminate a register
that is created by the signal version, and that register may be
correcting your synchronization (of sdl). If the 3rd is happening,
you have a tool problem in your simulator, or your code is not exactly
as posted. You could try nesting the 2nd if-then inside the first, and
get rid of the 2nd comparison to "10", but this should not make any
difference.

Andy

Hi Andy,

This happens in gate-level/full-timing simulation.

After some experimentation I have now an new set
of interesting info, and specifically one that
tells a lot :)
Behaviour changed to normal some fits after when I changed
something totally unrelated to this that changed dramatically
the FPGA fit... and stayed behaving well from that moment on.

(ask me if I trust it now !!! :)

Clock is 200MHz but the SCK,SDA and SLD run at 5MHz or less
hence my comment of mode and etc being stable for ages.
However since mode was clocked into a register that might
be related with the issue.
Funny enough, as mode is a two bit signal I tried it
through all individual 4 combinations "00" "01" "10" and "11"
and it failed all so was not the value of mode that was wrong
but the logic generated that was invalid and returned always
false...

this got to be very wrong.

now I can't reproduce the problem anymore, unless I use that
specific old_version from two days ago ;-)

---

While I had the abnormal behavior moving the variable
assignment to the bottom (as suggested) made no difference.
and nesting the two IFs did not work as well.

---

This was quite entertaining... :-(
As I was imagining a coding fault from me
the usual and most probable !


Thanks for your help, it was very helpful
after all, and I learned a lot.

Luis C.

p.s.(privately I can tell you what fpga family, vendor and tool chain
I was using if you are interested to know.)
 
A

Andy

Yep, synchronization strikes again! That, and it looks like you may
have had some timing issues which should have shown up in static
timing analysis, assuming you had the constraints set properly.

You must only sample an asynchronous multi-bit value when you KNOW
that all bits are valid. Sometimes a separate flag is available to
tell you that, other times you need to get creative and look at all
the bits to see where they are stable, and sample there. In other
words, a stable value should last 200 ns in your case. If you can't
determine the middle of that window from the source clock, then edge
detect each of the bits at 200 MHz, and wait until all have been
stable for 100 ns to clock them all into your fast clock domain.

Andy
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top