clk événement vs rising edge()

j'ai toujours utilisé ce pour la détection d'un front montant:

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

mais cela peut aussi être utilisé:

if rising_edge(clk) then

Lecture ce post,rising_edge(clk) est recommandé, mais il y a aussi commentaire indiquant que rising_edge(clk) pourrait conduire à un mauvais comportement.

je ne peux pas décider lequel choisir pour l'avenir, en allant sur (clk'event and clk='1') ou en adoptant rising_edge(clk).

toute expà © rience rà © elle sur ces deux? Des préférences?

Merci!

33
demandé sur Diego Herranz 2013-03-04 19:36:18

3 réponses

rising_edge est défini comme suit:

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'   -- '-'
                    );

si votre horloge va seulement de 0 à 1, et de 1 à 0, alors rising_edge produira le code identique. Sinon, vous pouvez interpréter la différence.

personnellement, mes horloges ne vont que de 0 à 1 et vice versa. J'ai trouver rising_edge(clk) pour être plus descriptifs que l' (clk'event and clk = '1') variante.

33
répondu Bill Lynch 2013-03-04 16:11:54

le commentaire lié est incorrect : 'L' à '1' produira un bord Ascendant.

en outre, si votre signal d'horloge passe de 'H' à '1',rising_edge(clk) (correctement) de ne pas déclencher alors que (clk'event and clk = '1') (à tort).

certes, cela peut ressembler à un exemple artificiel, mais j'ai vu des formes d'onde d'horloge faire cela dans le matériel réel, en raison d'Échecs ailleurs.

14
répondu Brian Drummond 2013-03-04 16:31:03

exemple concret:

Imaginez que vous modélisez quelque chose comme un bus I2C (signaux appelés SCL pour l'horloge et SDA pour les données), où le bus est à trois états et les deux filets ont une faible traction. Votre banc d'essai doit modéliser la résistance de traction sur le PCB avec une valeur de "H".

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

vos périphériques maître I2C ou esclaves peuvent conduire le bus à '1 'ou' 0 'ou le laisser seul en assignant un'Z'

Attribution d'un '1' à la SCL net va provoquer un événement, parce que la valeur de SCL a changé.

  • Si vous avez une ligne de code qui s'appuie sur (scl'event and scl = '1'), alors vous aurez un faux déclenchement.

  • Si vous avez une ligne de code qui s'appuie sur rising_edge(scl), puis vous n'aurez pas de fausse gâchette.

continuer l'exemple: vous assignez un' 0 'à SCL, puis un'Z'. Le filet passe à "0", puis à "H".

ici, aller de '1' à '0' ne déclenche aucun des deux cas, mais passer de '0' à ' H ' déclenchera un rising_edge(scl) condition (correct), mais le (scl'event and scl = '1') cas manquer (incorrect).

Recommandation Générale:

Utiliser rising_edge(clk) et falling_edge(clk) au lieu de clk'event pour tout le code.

9
répondu Iain Waugh 2013-08-06 23:45:41