Search code examples
vhdlfpgaclock

VHDL: using rising_edge with normal signals


If we generate a "clock_enable" signal just as suggested in this accepted answer: Is the use of rising_edge on non-clock signal bad practice? Are there alternatives?

Like:

signal mySignal_d : std_logic := '0'; 
signal clock_enable: std_logic;
mySignal_d <= mySignal when rising_edge(Clock); 
clock_enable <= not mySignal_d and mySignal; 

Is it ok to use rising_edge(clock_enable)? Or would it still be better to use:

if rising_edge(Clock) then
    if (clock_enable= '1') then

Is there a difference in behaviour of these two? If yes, then why? Is it about rising_edge implementation? Is there any literature or open-source implementation of rising_edge that would show exactly why rising_edge(clock_enable) would cause issues?


Solution

  • At any time you use "rising_edge(some_signal)" then in simulation you will get a behavior like a flipflop whose clock-input is connected to "some_signal" and as expected you will get a flipflop in synthesis.

    This is of course allowed, but you might get some unexpected problems in simulation and synthesis.

    When you connect a signal to the clock input of a flipflop you must guarantee that it has no spikes ("not mySignal_d and mySignal" is not spikefree). This is only possible, if the signal is a clock signal or if it is created by a the Q-output of a flipflop. In any other case (when the signal is created by some combinatorial logic) you may have spikes at the signal which could trigger the flipflop unexpectedly. This is not only a problem after synthesis but can also happen in simulation (for example caused by delta cycles).

    If you have created a spike free signal (by using the Q-output of a flipflop as a clock signal) and use it as a generated clock signal to trigger some flipflops, you must be aware that data paths between the 2 clock domains (original clock domain and generated clock domain) are difficult to handle in synthesis and timing closure. This is because the rising edge of the generated clock is delayed (to the rising edge of the original clock) by a flipflop switching time (and some wire delays). This delay is not stable but depends on temperature, voltage and process deviation. Of course there are synthesis and layout flows which can handle such a problem, but using them in the right way is often difficult and will not always give timing closure.

    So to answer your questions, it is not okay to use "rising_edge(clock_enable)", you should avoid it if possible.