'event attribute & modelsim 6.0 problem

N

Nicolas Matringe

Guest
Hello all

I have a process (without sensitivity list) with a wait condition on two
signals followed by a falling edge test (see following code excerpt)
What happens is that the falling edge remains true as long as the signal
doesn't change. Further investigations showed that the 'event attribute
remained true after the signal had changed, instead of being true only
for one simulation cycle.
What went wrong with ModelSim ? (or have I been misunderstanding the
'event attribute for many years ?)

code snippet :

process
begin
...
wait on sig1, sig2;
if falling_edge(sig1) then
...
end process

Function falling_edge returned "true" even after an event on sig2 but
not on sig1.

Nicolas
 
Nicolas Matringe wrote:

Hello all

I have a process (without sensitivity list) with a wait condition on
two signals followed by a falling edge test (see following code
excerpt) What happens is that the falling edge remains true as long
as the signal doesn't change. Further investigations showed that the
'event attribute remained true after the signal had changed, instead
of being true only for one simulation cycle.
What went wrong with ModelSim ? (or have I been misunderstanding the
'event attribute for many years ?)

code snippet :

process
begin
...
wait on sig1, sig2;
if falling_edge(sig1) then
...
end process

Function falling_edge returned "true" even after an event on sig2
but not on sig1.
What version of ModelSim are you using?

I whipped up a small testcase and it runs OK in version 6.2d:

ENTITY test IS
END ENTITY test;

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ARCHITECTURE arch OF test IS
SIGNAL s1: std_ulogic;
SIGNAL s2: std_ulogic;
BEGIN
s1 <= '0', '1' AFTER 1 ns, '0' AFTER 3 ns, '1' AFTER 5 ns,
'0' AFTER 7 ns;
s2 <= '0', '1' AFTER 2 ns, '0' AFTER 4 ns, '1' AFTER 6 ns,
'0' AFTER 8 ns;

p: PROCESS IS
BEGIN
WAIT ON s1, s2;

REPORT "fe(s1)=" & boolean'IMAGE(falling_edge(s1)) &
", fe(s2)=" & boolean'IMAGE(falling_edge(s2)) &
", s1'EVENT=" & boolean'IMAGE(s1'EVENT) &
", s2'EVENT=" & boolean'IMAGE(s2'EVENT) &
".";
END PROCESS p;
END ARCHITECTURE arch;

The result:

# ** Note: fe(s1)=false, fe(s2)=false, s1'EVENT=true, s2'EVENT=true.
# Time: 0 ps Iteration: 1 Instance: /test

# ** Note: fe(s1)=false, fe(s2)=false, s1'EVENT=true, s2'EVENT=false.
# Time: 1 ns Iteration: 0 Instance: /test

# ** Note: fe(s1)=false, fe(s2)=false, s1'EVENT=false, s2'EVENT=true.
# Time: 2 ns Iteration: 0 Instance: /test

# ** Note: fe(s1)=true, fe(s2)=false, s1'EVENT=true, s2'EVENT=false.
# Time: 3 ns Iteration: 0 Instance: /test

# ** Note: fe(s1)=false, fe(s2)=true, s1'EVENT=false, s2'EVENT=true.
# Time: 4 ns Iteration: 0 Instance: /test

# ** Note: fe(s1)=false, fe(s2)=false, s1'EVENT=true, s2'EVENT=false.
# Time: 5 ns Iteration: 0 Instance: /test

# ** Note: fe(s1)=false, fe(s2)=false, s1'EVENT=false, s2'EVENT=true.
# Time: 6 ns Iteration: 0 Instance: /test

# ** Note: fe(s1)=true, fe(s2)=false, s1'EVENT=true, s2'EVENT=false.
# Time: 7 ns Iteration: 0 Instance: /test

# ** Note: fe(s1)=false, fe(s2)=true, s1'EVENT=false, s2'EVENT=true.
# Time: 8 ns Iteration: 0 Instance: /test

--
Paul.
www.aimcom.nl
email address: switch x and s
 
Paul Uiterlinden a écrit :
What version of ModelSim are you using?
6.0c
I didn't have time to test your case or to investigate any further, I
had found a workaround anyway.

I'll try and have a look when I have 5mn spare.

Nicolas
 
sig1 and sig2 aren't elements of the same aggregate (i.e. bits of the
same SLV), are they?

If that is the case, it seems like there is a feature of the language
that whenever one bit of a vector changes, it causes an event on the
entire vector, which in turn propagates to events on each bit. So,
sig(1)'event will be true if a change occurred on sig(2), even though
sig(1) itself did not change. However, IINM, rising_edge() should be
checking previous state as well as current state of the signal, in
which case it would return false if there was an event with no value
change on sig(1).

This can be handled by concurrently assigning temporary signals to the
bits you want, and using those (assuming you can tolerate the delta
delay for the concurrent assignments).

Andy


Nicolas Matringe wrote:
Hello all

I have a process (without sensitivity list) with a wait condition on two
signals followed by a falling edge test (see following code excerpt)
What happens is that the falling edge remains true as long as the signal
doesn't change. Further investigations showed that the 'event attribute
remained true after the signal had changed, instead of being true only
for one simulation cycle.
What went wrong with ModelSim ? (or have I been misunderstanding the
'event attribute for many years ?)

code snippet :

process
begin
...
wait on sig1, sig2;
if falling_edge(sig1) then
...
end process

Function falling_edge returned "true" even after an event on sig2 but
not on sig1.

Nicolas
 
Nicolas Matringe wrote:

Paul Uiterlinden a écrit :
What version of ModelSim are you using?

6.0c
I didn't have time to test your case or to investigate any further,
I had found a workaround anyway.

I'll try and have a look when I have 5mn spare.
I really would be surprised if things really are as you said in your
first post. The style you use is something that use a lot myself. I
never have had a problem with that. Please let us know what you find.

--
Paul.
www.aimcom.nl
email address: switch x and s
 
Andy wrote:

sig1 and sig2 aren't elements of the same aggregate (i.e. bits of
the same SLV), are they?
Ah, interesting point. However:

I modified my test and combined the two separate signals into a single
vector. It does not change anything. It still works the same.

If that is the case, it seems like there is a feature of the
language that whenever one bit of a vector changes, it causes an
event on the entire vector, which in turn propagates to events on
each bit. So, sig(1)'event will be true if a change occurred on
sig(2), even though sig(1) itself did not change.
That's not true. I do not have the LRM or any other VHDL book at hand
at the moment. However, I seem to recall the LRM claims the opposite:
if there is an event on any of the members making up the aggregate,
the whole aggregate is said to have an event (and not all the other
members).

However, IINM,
rising_edge() should be checking previous state as well as current
state of the signal, in which case it would return false if there
was an event with no value change on sig(1).
Indeed:

FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
BEGIN
RETURN (s'EVENT AND (To_X01(s) = '0') AND
(To_X01(s'LAST_VALUE) = '1'));
END;

This can be handled by concurrently assigning temporary signals to
the bits you want, and using those (assuming you can tolerate the
delta delay for the concurrent assignments).
It's not necessary.

The only thing that you cannot do is use a variable or loop index on
the vector to find out which bit(s) had an event. So this is not
possible:

WAIT ON vec;
FOR i IN vec'RANGE LOOP
-- ** Error: Attribute "event" requires a static signal prefix
IF vec(i)'EVENT THEN
...
END IF;
END LOOP;

You have the use a variable, store the previous state an compare the
bits in the loop. I never understood why this limitation exists.

--
Paul.
www.aimcom.nl
email address: switch x and s
 
Paul Uiterlinden a écrit :

I really would be surprised if things really are as you said in your
first post. The style you use is something that use a lot myself. I
never have had a problem with that. Please let us know what you find.
I too was very surprised, hence my posting here.
I was also surprised, when stepping the simulation through this portion
of code, that it entered the falling_edge function.

Nicolas
 
Andy a écrit :
sig1 and sig2 aren't elements of the same aggregate (i.e. bits of the
same SLV), are they?
No they are not.


If that is the case, it seems like there is a feature of the language
that whenever one bit of a vector changes, it causes an event on the
entire vector, which in turn propagates to events on each bit.
As Paul already said, the attributes are signal attributes, whether this
signal is an array or not.

Nicolas
 
Paul,

Thanks for the clarification. I checked the LRM (2000), and I believe
your interpretation is correct. For some reason, I remember being told
a long time ago not to use bits of a vector for clocks, because they
would not simulate as expected. Maybe that was just an old wives' tale,
or maybe it had to do with non-static prefixes. Nevertheless, it is not
the source of your problem anyway (you're not using bits of a vector
for this).

Good luck,

Andy


Paul Uiterlinden wrote:
Andy wrote:

sig1 and sig2 aren't elements of the same aggregate (i.e. bits of
the same SLV), are they?

Ah, interesting point. However:

I modified my test and combined the two separate signals into a single
vector. It does not change anything. It still works the same.

If that is the case, it seems like there is a feature of the
language that whenever one bit of a vector changes, it causes an
event on the entire vector, which in turn propagates to events on
each bit. So, sig(1)'event will be true if a change occurred on
sig(2), even though sig(1) itself did not change.

That's not true. I do not have the LRM or any other VHDL book at hand
at the moment. However, I seem to recall the LRM claims the opposite:
if there is an event on any of the members making up the aggregate,
the whole aggregate is said to have an event (and not all the other
members).

However, IINM,
rising_edge() should be checking previous state as well as current
state of the signal, in which case it would return false if there
was an event with no value change on sig(1).

Indeed:

FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
BEGIN
RETURN (s'EVENT AND (To_X01(s) = '0') AND
(To_X01(s'LAST_VALUE) = '1'));
END;

This can be handled by concurrently assigning temporary signals to
the bits you want, and using those (assuming you can tolerate the
delta delay for the concurrent assignments).

It's not necessary.

The only thing that you cannot do is use a variable or loop index on
the vector to find out which bit(s) had an event. So this is not
possible:

WAIT ON vec;
FOR i IN vec'RANGE LOOP
-- ** Error: Attribute "event" requires a static signal prefix
IF vec(i)'EVENT THEN
...
END IF;
END LOOP;

You have the use a variable, store the previous state an compare the
bits in the loop. I never understood why this limitation exists.

--
Paul.
www.aimcom.nl
email address: switch x and s
 

Welcome to EDABoard.com

Sponsor

Back
Top