![]() |
|
|
|||||||
![]() |
VHDL - 'event attribute & modelsim 6.0 problem |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
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 |
|
|
|
|
#2 |
|
Posts: n/a
|
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 |
|
|
|
#3 |
|
Posts: n/a
|
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 |
|
|
|
#4 |
|
Posts: n/a
|
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 |
|
|
|
#5 |
|
Posts: n/a
|
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 |
|
|
|
#6 |
|
Posts: n/a
|
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 |
|
|
|
#7 |
|
Posts: n/a
|
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 |
|
|
|
#8 |
|
Posts: n/a
|
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 |
|
|
|
#9 |
|
Posts: n/a
|
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 |
|