45

I had always used this for detecting a rising edge:

if (clk'event and clk='1') then

but this can also be used:

if rising_edge(clk) then

Reading this post, rising_edge(clk) is recommended, but there is also a comment indicating that rising_edge(clk) could lead to wrong behaviour.

I can't decide which one to choose for the future, going on with (clk'event and clk='1') or adopting rising_edge(clk).

Any real-world expereince on these two? Any preferences?

Thanks!

Diego Herranz
  • 2,857
  • 2
  • 19
  • 34
  • Can "if(rising_edge(clk))" be used inside a subprogram body? –  Jul 04 '16 at 10:12
  • 1
    @VineetDeoraj Of course it can. In some contexts it may not make sense or be synthesisable (e.g. if the subprogram is called in a process triggered by a different clock) but that's another matter. –  Aug 15 '16 at 11:25
  • Somewhat related - [wait until rising_edge(clk) vs if rising_edge(clk)](https://stackoverflow.com/q/32717040). – Henke Apr 05 '21 at 13:56

3 Answers3

39

rising_edge is defined as:

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

FUNCTION To_X01  ( s : std_ulogic ) RETURN  X01 IS
BEGIN
    RETURN (cvt_to_x01(s));
END;

CONSTANT cvt_to_x01 : logic_x01_table := (
                     'X',  -- 'U'
                     'X',  -- 'X'
                     '0',  -- '0'
                     '1',  -- '1'
                     'X',  -- 'Z'
                     'X',  -- 'W'
                     '0',  -- 'L'
                     '1',  -- 'H'
                     'X'   -- '-'
                    );

If your clock only goes from 0 to 1, and from 1 to 0, then rising_edge will produce identical code. Otherwise, you can interpret the difference.

Personally, my clocks only go from 0 to 1 and vice versa. I find rising_edge(clk) to be more descriptive than the (clk'event and clk = '1') variant.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • 7
    At simulation startup, if your clock goes from 'U' to '1', rising_edge(clk) will be false, but the hand-written edge detection "event and 1" will be true. In this specific case, rising_edge would be safer. – wap26 Mar 04 '13 at 16:22
  • Would `if (clk'last_value='0' and clk='1') then` accomplish the same thing? – Nate Apr 05 '15 at 17:59
  • 1
    This is controversial comment - it is good, since it gives clear definition of rising_edge() mechanics; It's quite wrong by being ambivalent to the advantages of rising_edge() for 'H' to 1 and '1' to L transitions. My optinion - no good reason to use 'event and 1' construct - fully agree with Iain Waugh's answer. – vleo May 08 '15 at 15:17
17

The linked comment is incorrect : 'L' to '1' will produce a rising edge.

In addition, if your clock signal transitions from 'H' to '1', rising_edge(clk) will (correctly) not trigger while (clk'event and clk = '1') (incorrectly) will.

Granted, that may look like a contrived example, but I have seen clock waveforms do that in real hardware, due to failures elsewhere.

15

Practical example:

Imagine that you are modelling something like an I2C bus (signals called SCL for clock and SDA for data), where the bus is tri-state and both nets have a weak pull-up. Your testbench should model the pull-up resistor on the PCB with a value of 'H'.

scl <= 'H'; -- Testbench resistor pullup

Your I2C master or slave devices can drive the bus to '1' or '0' or leave it alone by assigning a 'Z'

Assigning a '1' to the SCL net will cause an event to happen, because the value of SCL changed.

  • If you have a line of code that relies on (scl'event and scl = '1'), then you'll get a false trigger.

  • If you have a line of code that relies on rising_edge(scl), then you won't get a false trigger.

Continuing the example: you assign a '0' to SCL, then assign a 'Z'. The SCL net goes to '0', then back to 'H'.

Here, going from '1' to '0' isn't triggering either case, but going from '0' to 'H' will trigger a rising_edge(scl) condition (correct), but the (scl'event and scl = '1') case will miss it (incorrect).

General Recommenation:

Use rising_edge(clk) and falling_edge(clk) instead of clk'event for all code.

Iain Waugh
  • 151
  • 1
  • 2
  • 1
    Your example successfully demonstrates the fallacy of design descriptions not utilizing device pin buffers. In real life you aren't going to propagate anything but 'X', '0' or '1' to the clock input of a flip flop when it's reset is not asserted. The problem is not caused by using a particular IEEE Std 1076.6-2004 approved method for edge sensitive sequential logic representation. The question being whether a particular vendor is going to allow a TO_X01(scl) as formal or the like. –  Aug 09 '13 at 04:38