trayres
trayres

Reputation: 532

Odd VHDL question: rising_edge(CLK) not firing

I have a large simulation testbench which is exercising the interface between two Kintex Ultrascale FPGAs. I'm having the oddest problem: I can't get a rising_edge(CLK) statement to fire.

There are multiple instances of this in the design: I'll trace down a logic path, and end up discovering a rising_edge(whatever) that isn't firing.

Here is the kicker: Replacing rising_edge with CLK'EVENT and CLK='1' causes the logic to fire correctly, but I can't go through a thousand source files to replace them all and then push it to the team repo - that'd be absurd (plus the code is valid, and has been used multiple times, so making a change like that would be a huge waste of time).

A rising_edge is also equivalent to CLK'LAST='0' and CLK'EVENT and CLK='1' - this statement also doesn't fire. So it must be that CLK'LAST='0' isn't satisfied, right? (If CLK'EVENT and CLK='1' fires, and the addition of CLK'LAST='0' does not fire, then it must be that last item causing the problem).

However, I look at the delta-view, and I can see no intermediate values between 0 and 1 - no intermediate high-Z states, no undefined signal, nothing. It looks perfect.

I have tested this with several different Modelsim versions with the same result (just to make sure it wasn't a tool regression).

What, in the world, could be causing this?

The only thing I can think of that's non-standard is that I'm using external names to drive the clock/data a few layers up the hierarchy, but they're updating the expected value to the waveform window.

Could the use of the external names to force values somehow cause the edge to be missed, even though the signals look right (even down to the deltas?) or would it cause some kind of waveform window disparity? What is causing the CLK'LAST to be effectively lost?

Thanks all!

Upvotes: 3

Views: 886

Answers (2)

user_007
user_007

Reputation: 320

I assume you are using VHDL force on these hierarchical signals. If so, I have encountered the same issue using ModelSim. I'm not sure if it's to do with ModelSim's implementation of support for VHDL-2008 or what exactly.

Since finding this, I typically use the ModelSim force command via a TCL macro rather than VHDL, as the ModelSim command seems to behave more predictably (including being recognized by rising/falling_edge()) and (without having IEEE 1076 available to reference) I believe it supports more options than the VHDL version.

Upvotes: 1

Renaud Pacalet
Renaud Pacalet

Reputation: 29167

If the type of CLK is not bit, e.g. if it is std_ulogic or std_logic then no, rising_edge(CLK) is not equivalent to:

CLK'EVENT and CLK='1'

or:

CLK'LAST='0' and CLK'EVENT and CLK='1'

rising_edge(CLK) also involves 'L' and 'H'; it returns true for any transition from '0' or 'L' to '1' or 'H'. That is, any of:

'L' -> 'H'
'L' -> '1'
'0' -> 'H'
'0' -> '1'

While CLK'EVENT and CLK='1' evaluates as true for any of:

'U' -> '1'
'X' -> '1'
'0' -> '1'
'Z' -> '1'
'W' -> '1'
'L' -> '1'
'H' -> '1'
'-' -> '1'

So a transition from 'H' to '1', for instance, is not a rising edge for rising_edge(CLK) but it is one for CLK'EVENT and CLK='1'. And, conversely, a transition from '0' to 'H' is a rising edge for rising_edge(CLK) but not for CLK'EVENT and CLK='1'.

Another potential reason for this issue is far less likely: you are using a custom version of the rising_edge function...

Upvotes: 6

Related Questions