Forum: FPGA, VHDL & Co. CLK'event oder rising_edge(clk)


von Holger (Gast)


Lesenswert?

Hallo,

lese grade VHDL-Synthese von Reichardt/Schwarz.

Dort wirt die Auswertung des Clock-Signals mittels

...
elseif CLK='1' and CLK'event then
...

beschrieben.


Hier im Forum wurde mir ein Programmbeispiel geschrieben mit

...
elseif rising_edge(clk) then
...

Letzteres wird im Buch gar nicht erwähnt. Welches sollte man nehmen?
Was sind die Vorteile/Nachteile.


Gruß
Holger

von FPGAkuechle (Gast)


Lesenswert?

Ooch da wird immer wieder heftig diskutiert, aber für mich ist
entscheidend was besser lesbar ist. Und ich denke lieber in:

"Falls steigende Flanke clk dann ..."

als

"falls Takt'ereignis und Takt = '1' dann ..."

also rising_edge() oder falling_edge() .

Beides sind Funktionen die zusätzlich zu clk'event and clk = '1'
(rising_edge) noch testen, ob der Wert vor dem event '0'
(rising_edge) war: clk'last_value = '0' .

clk'event and clk = '1' wird immer aktiv wenn clk eine '1'
zugewiesen wird, also auch wenn clk schon '1' führt.

Somit ist rising_edge() marginal "exakter".

Entscheidend ist aber die Lesbarkeit und daher hab ich mich für
rising_edge() entschieden. Damit hatte ich noch nie Syntheseprobleme.

von Holger (Gast)


Lesenswert?

Hallo,

eine gute und einleuchtende Erklärung! Vielen Dank!

Holger

von schlumpf (Gast)


Lesenswert?

Letztdendlich muss bei der Synthese das gleiche herauskommen. Du
beschreibst ein FF und damit wird auch ein FF instanziiert.
Also daher völlig egal, wie du es beschreibst.

von Axel (Gast)


Lesenswert?

"Letztdendlich muss bei der Synthese das gleiche herauskommen. Du
beschreibst ein FF und damit wird auch ein FF instanziiert.
Also daher völlig egal, wie du es beschreibst."

Nicht ganz. Unter Umständen verhält sich Deine Simulation anders als
die Realität.

Und solche Fehler sind besonders schön zu suchen.

Gruss
Axel

von schlumpf (Gast)


Lesenswert?

@Axel:
Darum schrieb ich auch "Synthese" und nicht "Simulation"

beide Schreibweisen instanziieren ein FF im FPGA
Was in der Simulation passiert, das ist natürlich ne ganz andere
Baustelle (aber das ist es in VHDL ja sowieso) gg

von Frank (Gast)


Lesenswert?

Meiner Meinung nach sind beide Angaben identisch. FPGAKüchle schreibt
zwar "clk'event and clk = '1' wird immer aktiv wenn clk eine '1'
zugewiesen wird, also auch wenn clk schon '1' führt."
jedoch ist zu beachten das da steht "if clk'event and clk='1'",
d.h. es passiert nur dann etwas wenn auf dem Clockpfad etwas passiert
und dabei die Clock auf '1' geht. Ist sie aber schon auf '1'
passiert schlichtweg nix weiter.
Frank

von Axel (Gast)


Lesenswert?

Schlumpf:

Für die Synthese ist es "egal", aber "völlig egal" beinhaltet auch
die Simulation :-))

Frank:

Ich könnte mir vorstellen, dass unterschiedliche Simulatoren das
unterschiedlich implementieren. In der Synthese dürfte das allerdings
egal sein.

Allerdings wäre es m. M. nach auch schlechter Coding Stil, wenn es da
in der Takterzeugung irgendwelche Unklarheiten geben könnte und der
'1' noch mal eine '1' zugewiesen würde. Von daher ist das wohl eher
eine theoretische Frage.

Gruss
Axel

von FPGAkuechle (Gast)


Lesenswert?

Ich hab mal in FAQ der COMP.lang.vhdl newsgroup nachgeschlagen (Text
unten):

-ob eine zuweisung von '1' auf ein Signal das bereits '1' ist ein
'event auslöst ist fraglich (hab aber ich mal so gelernt).
Könnt man ja mal testen ob

process
begin
s <= '1';
wait for 10 ns;
end process;

aller 10 ns einen s'event auslöst.

-es gibt aber noch weitere "falsche 'events" die rising_edge()
 ausfiltert und zwar bei std_logic die Übergange H-> '1',U -> '1'
oder X->1. Die würden in der anderen Variante auch ein Umschalten
auslösen.

-rising_edge wandelt die 'H' und 'L' (weak PullUp/Down) um, und
erkennt somit auch die Übergange '0' -> 'H' und 'L' -> 1.

(allerdings dürfte man wohl komm PullUp,Downs an einer taktleitung
haben.

Aber wie gesagt, für mich zählt Lesbarkeit, da nehme ich die bessere
Simulations-Echt Übereinstimmung als Extra mit.

So hier der FAQ Auszug:

4.2.42 rising_edge(clk) versus (clk'event and clk='1')
In general, there are two ways in VHDL to describe edge sensitive
elements (we assume that signal "clk" is of type std_logic):
The expression
clk'event and clk = '1'
returns true if signal "clk" has a transition and its new value is
'1'. If the previous value of "clk" is '0', then this expression
correctly detects a rising edge. However, any transition that ends at
'1' will be considered as a rising edge. Hence, changes from 'H'
(weak '1') to '1' will return true while transitions from '0' to
'H' evaluate to false. As a result, "clk'event and clk = '1'" is
only save if "clk" toggles between '0' and '1'.
rising_edge (clk)
is defined in package std_logic_1164 and returns true if signal "clk"
has a rising transition (to detect a falling edge use "falling_edge").
The function is implemented as follows:
     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;

It uses the function "To_X01" to compare the current and previous
value of "clk" making it more robust against "unusual" clock
values. "To_X01" maps 'H' to '1' and 'L' to '0'. Hence,
rising_edge also returns true for transitions from '0' to 'H' and
returns false for transitions from 'H' to '1' (as well as changes
from 'X' to '1').
For synthesis, there is usually no difference between both alternatives
as the synthesis tool assumes that transitions on clock signals are
"clean" (i.e., clock signals toggle between '0' and '1' only).
However, for simulation it is more save to use "rising_edge" (or
"falling_edge").

von FPGAkuechle (Gast)


Lesenswert?

#Meiner Meinung nach sind beide Angaben identisch. FPGAKüchle schreibt
#zwar "clk'event and clk = '1' wird immer aktiv wenn clk eine
'1'
#zugewiesen wird, also auch wenn clk schon '1' führt."
#jedoch ist zu beachten das da steht "if clk'event and clk='1'",
#d.h. es passiert nur dann etwas wenn auf dem Clockpfad etwas passiert
#und dabei die Clock auf '1' geht. Ist sie aber schon auf '1'
#passiert schlichtweg nix weiter.

Habs mal an modelsim getestet, Frank hat recht.

Zuweisen einer '1' an ein signal das bereits eine '1' führt ist
kein 'event.


SIGNAL toggle_test : boolean := false;
  SIGNAL toggle_test1 : boolean := false;
  SIGNAL toggle_source : std_logic;



PROCESS
  BEGIN
    toggle_source <= '1';
    toggle_test1 <= NOT toggle_test1;
    WAIT FOR 10.0 NS;
END PROCESS;

PROCESS(toggle_source)
  BEGIN
    if (toggle_source'event) AND (toggle_source = '1') then
    toggle_test <= NOT toggle_test;
  END if;
END PROCESS;



-> toogle_source wechselt nur einmal seinen wert (bei der  allerste
'1'-Zuweisung.

von FPGAkuechle (Gast)


Lesenswert?

Tüpfühler :-( heisst natürlich

-> toogle_test wechselt nur einmal seinen wert (bei der  allerste
'1'-Zuweisung an toggle_source.

(toggle_test1 wechselt dagegen aller 10 ns -> die '1'-Zuweisung wird
also wirklich aller 10 ns ausgeführt.





PROCESS(toggle_source)
  BEGIN
    if (toggle_source'event) AND (toggle_source = '1') then
    toggle_test <= NOT toggle_test;
  END if;
END PROCESS;

von Johnsn (Gast)


Lesenswert?

Die meisten Synthesetools würden die Anweisung "toggle_source <=
'1';
" im 1. Process auch wegoptimieren, vorausgesetzt die Entity wäre
synthesefähig.

Aber eine derartige Zuweisung darf auch nicht bei einem Taktsignal
passieren. Schließlich kann (darf) man auf sonst kein anderes Signal
ein 'event ausführen.

von -daniel- (Gast)


Lesenswert?

s'active true bei jeder zuweisung (1 auf 1 zB)
s'event true bei jedem wertwechsel (0 auf 100 zB)

zu beachten ist, dass "true" sind sie nur in einem delta cycle
und ausserdem sind processe event getriggert, dh heisst
man kommt nicht so einfach an die zeitpunkte wenn kein eine
transaktion ohne wertewechsel passiert. Deswegen wurde

s'transaction

erfunden, liefert einen bit type signal, der bei jeder
transaktion toggelt (und erlebt einen event dabei)

signal i: integer := 0;

i <= 1 after 0 ns, 1 after 10 ns, 2 after 20 ns, 2 after 100 ns;

monitor: process
    use std.textio.all;
    variable l: line;
begin
    wait on i'transaction;
    write(l, "transaktion @" & time'image(now));
    if i'event then
        write(l, " with event: i changed from " &
integer'image(i'last_value) & " to " & integer'image(s));
    end if;
    writeline(output, l);
end process;

aus dem kopf abgetippt => ohne gewähr

von Juergen Schuhmacher (Gast)


Lesenswert?

Solange man in der Abfrage auf Event und CLK=1 testet, ist es wohl egal.
Dieser Konstrukt bietet aber die Möglichkeit, auch auf ein Signal zu
testen, also CLK = SIGNAL und damit das FF in seiner Funktion
umzuschalten. Mit statisch "rising" geht das nicht.

von 123 (Gast)


Lesenswert?

Da die frage bestimmt noch 100 mal kommt währe hier der platz für eine
zusammenfassung:

http://www.mikrocontroller.net/articles/VHDL#CLK.3D.271.27_and_CLK.27event_oder_rising_edge.28.29

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.