J'avais toujours utilisé cela pour détecter un front montant:
if (clk'event and clk='1') then
mais cela peut aussi être utilisé:
if rising_Edge(clk) then
La lecture this post , rising_Edge(clk)
est recommandée, mais il y a aussi n commentaire indiquant que rising_Edge(clk)
pourrait provoquer un comportement incorrect.
Je ne peux pas décider lequel choisir pour l'avenir, continuer avec (clk'event and clk='1')
Ou adopter rising_Edge(clk)
.
Toute expérience réelle sur ces deux? Des préférences?
Merci!
rising_Edge est défini comme:
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 ne passe que de 0 à 1 et de 1 à 0, rising_Edge produira un code identique. Sinon, vous pouvez interpréter la différence.
Personnellement, mes horloges vont seulement de 0 à 1 et vice versa. Je trouve que rising_Edge(clk)
est plus descriptif que la variante (clk'event and clk = '1')
.
Le commentaire lié est incorrect: "L" à "1" produira un bord montant.
De plus, si votre signal d'horloge passe de 'H' à '1', rising_Edge(clk)
ne se déclenchera pas (correctement) pendant que (clk'event and clk = '1')
(incorrectement) le fera.
Certes, cela peut sembler être un exemple artificiel, mais j’ai vu des formes d’horloge le faire dans du matériel réel, en raison de défaillances constatées ailleurs.
Exemple pratique:
Imaginez que vous modélisez quelque chose comme un bus I2C (signaux appelés SCL
pour horloge et SDA
pour données), où le bus est à trois états et où les deux réseaux ont une faible remontée. Votre banc d’essai doit modéliser la résistance de rappel sur le PCB avec la valeur 'H').
scl <= 'H'; -- Testbench resistor pullup
Votre maître ou esclave I2C peut piloter le bus sur "1" ou "0" ou le laisser tranquille en affectant un "Z"
L'attribution d'un "1" au réseau SCL provoquera un événement, car la valeur de SCL a changé.
Si vous avez une ligne de code qui repose sur (scl'event and scl = '1')
, Vous obtiendrez un faux déclencheur.
Si vous avez une ligne de code qui repose sur rising_Edge(scl)
, vous n'obtiendrez pas de faux déclencheur.
En reprenant l'exemple, vous affectez un "0" à SCL, puis un "Z". Le réseau SCL passe à "0", puis revient à "H".
Ici, passer de '1' à '0' ne déclenche aucun cas, mais aller de '0' à 'H' va déclencher une condition rising_Edge(scl)
(correcte), mais le (scl'event and scl = '1')
le cas va manquer (incorrect).
Recommandation générale:
Utilisez rising_Edge(clk)
et falling_Edge(clk)
au lieu de clk'event
Pour tout le code.