Forum: FPGA, VHDL & Co. Latches vermeiden?


von Peter B. (funkheld)


Lesenswert?

Müssen in dieser IF-Abfrage unten "Else" rein um Latches zu vermeiden ?

Danke.
Gruss
1
 if clk'event and clk='1' then 
2
      if (c=1) then               
3
        x <= not x;              
4
      end if; 
5
6
      if (c=200000) then               
7
        x <= not x;              
8
      end if;
9
      
10
      if (c=200000) then      
11
        y <= not y;               
12
      end if;
13
14
      if (c=400000) then      
15
        y <= not y;               
16
      end if;
17
      
18
      c <= c+1;
19
  end if;

von Georg A. (georga)


Lesenswert?

Nein. Ein getakteter Prozess (clk'event ... oder "korrekter" mit 
rising/falling_edge) erzeugt IMMER "echte" Flipflops 
(taktflankengesteuert/Master-Slave/... *) für ALLE Signale, denen was 
zugewiesen wird (oder werden könnte).

Kritisch sind Prozesse die auf "alles" reagieren und nicht nur auf eine 
Flanke. **)

*) Latches vs. Flipflop: Üblicherweise sagt man zu pegelgesteuerten 
Speichergliedern (zB. RS) "Latches", zu flankengesteuerten 
(edge-triggered) nur "Flipflop". Leider wird FF auch gern als 
Oberbegriff für alles benutzt.

**) Die Phobie vor Latches bei FPGAs kommt daher, dass sie (meistens) 
nicht auf spezialisierte HW implementiert werden (wie FFs) sondern mit 
einem Feedback über die Verdrahtung. Das sorgt für recht 
unvorhersehbares Timing und potentiell Glitches. Letzteres haben 
Schaltungen mit Latches aber eh so an sich ;)

von greg (Gast)


Lesenswert?

Die üblichen Synthesetools warnen dich übrigens, wenn Latches inferiert 
werden. Also keine Panik, einfach die Logs prüfen, ggf. den Code schief 
von der Seite angucken und das Problem entdecken.

von peter (Gast)


Lesenswert?

Jup danke.

---------------------
Nein. Ein getakteter Prozess (clk'event ... oder "korrekter" mit
rising/falling_edge) erzeugt IMMER "echte" Flipflops
-----------------------

Wie sieht es aus wenn dieser Process eine Empfindlichkeitsliste hat ohne 
"clk" ?

Danke.
Gruss

von Duke Scarring (Gast)


Lesenswert?

peter schrieb:
> Wie sieht es aus wenn dieser Process eine Empfindlichkeitsliste hat ohne
> "clk" ?
Dann können Latch entstehen...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

peter schrieb:
> Wie sieht es aus wenn dieser Process eine Empfindlichkeitsliste hat ohne
> "clk" ?
Das kommt darauf an, ob im Prozess trotzdem ein 'event oder ein *_edge() 
abgefragt wird. Die Sensitivliste an sich ist NUR und AUSSCHLIESSLICH 
für die Simulation relevant!

: Bearbeitet durch Moderator
von peter (Gast)


Lesenswert?

-----------------------------------------
Die Sensitivliste an sich ist NUR und AUSSCHLIESSLICH
für die Simulation relevant!
-----------------------------------------

Ohne Sensitivliste und ohne Event wird der Process nicht compiliert. Es 
kommt ein Error. Wenn ich diese Sensitiv ohne Event mache , wird das 
Programm compiliert.

Danke.
Gruss

von Lattice User (Gast)


Lesenswert?

peter schrieb:
> -----------------------------------------
> Die Sensitivliste an sich ist NUR und AUSSCHLIESSLICH
> für die Simulation relevant!
> -----------------------------------------

Nicht ganz richtig.
Um Flipflops aus der Bechreibung abzuleiten wird eine Clock in der 
Sensitivityliste gebraucht. Wenn dieses Register einen asynchronen Reset 
haben soll, auch noch das Reset Signal.

Details dazu stehen in den Coding Guidlines des verwendeten 
Synthesetools.
1
process(clk)
2
begin
3
  if clk'event and clk='1' then 
4
    ff <= Sonstwas;
5
  end if;
6
end process;

oder moderner
1
process(clk)
2
begin
3
  if raising_edge(clk)then 
4
    ff <= Sonstwas;
5
  end if;
6
end process;

"Sonstwas" muss nicht in die Liste, denn auch der Simulator braucht den 
Prozess für eine funktionale Simulation nur bei der Clockflanke 
berechnet zu werden.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Lattice User schrieb:
> Um Flipflops aus der Bechreibung abzuleiten wird eine Clock in der
> Sensitivityliste gebraucht.
Nein.
Sowas wird tadellos synthetisiert aber vollkommen falsch simuliert:
1
  process (taster) begin     -- eine falsche Sensitivliste
2
    if rising_edge(clk) then
3
        toggle <= not toggle;
4
    end if;
5
  end process;

> Um Flipflops aus der Bechreibung abzuleiten wird eine Clock in der
> Sensitivityliste gebraucht.
Sowas wird tadellos synthetisiert und korrekt simuliert:
1
  process begin                  -- überhaupt keine Sensitivliste
2
    wait until rising_edge(clk); -- aber dafür ein wait
3
    toggle <= not toggle;
4
  end process;

peter schrieb:
> Ohne Sensitivliste und ohne Event wird der Process nicht compiliert.
Das ist eine andere Baustelle. Dass man natürlich syntaktisch eine 
Sensitivliste und/oder ein "wait" im Prozess braucht, ist im VHDL 
Standard definiert.

von peter (Gast)


Lesenswert?

Jup danke.

was heisst hier "moderner"? Ist das andere Fehlerbehaftet?
--------------------------
oder moderner
process(clk)
begin
  if raising_edge(clk)then
    ff <= Sonstwas;
  end if;
end process;
----------------------------

Danke.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

peter schrieb:
> was heisst hier "moderner"? Ist das andere Fehlerbehaftet?
Ein Übergang von 'U' nach '1' wird im ersten Fall als steigende Flanke 
gewertet. In der Funktion rising_egde() wird auch noch 
clk'last_value='0' abgefragt. Einfach mal die Funktion selber ansehen:
http://standards.ieee.org/downloads/1076/1076.2-1996/std_logic_1164-body.vhdl
http://stackoverflow.com/questions/15205202/clkevent-vs-rising-edge

: Bearbeitet durch Moderator
von Klaus F. (kfalser)


Lesenswert?

peter schrieb:
> Ohne Sensitivliste und ohne Event wird der Process nicht compiliert. Es
> kommt ein Error.
Klar:
Es gibt 2 Arten von Prozessen:
Ein Prozess braucht entweder eine Sensitivity List oder (mindestens) ein 
wait Statement.

VHDL ist wie schon oft geschrieben, eine Sprache für die Simulation von 
Hardware und die Hardware wird mit Prozessen modelliert.
Man stellt sich Hardware einfach als Blöcke vor.
Diese Blöcke haben Eingänge, und aus dem Zustand der Eingänge ergeben 
sich die Aufgänge.
Die Simulation braucht die Ausgänge nicht dauernd neu zu berechnen, das 
wäre unsinnig.
Nur wenn sich an den Eingängen etwas ändert, muss der Ausgang 
aktualisiert werden.
Das ist der Sinn einen Prozesses. Die Eingänge sind in der sensitivity 
list auflistet und der Prozess startet die Berechnung der Ausgänge wenn 
sich dort etwas ändert. Deshalb heißt sie auch sensitivity list, könnte 
auch trigger list heißen.
Der solcher Prozess startet am Beginn, führt alle Statements sequentiell 
aus und stoppt am Ende.
Ein solcher Prozess ohne sensitivity list macht somit keinen Sinn, da er 
niemals startet.

Bei der zweiten Veriante von Prozessen läuft der Prozess dauernd die 
Runde (salopp gesprochen) und startet beim Erreichen des letzten 
Statements wieder am Beginn.
Damit die Berechnung aber irgendwann aufhört und die Simulation in der 
Zeit weiterrücken kann, müssen irgendwo im Prozess wait-Statements 
vorhanden sein, wo der Prozess stoppt und erst bei Erreichen eine 
bestimmten Bedingung weitergeführt wird.
Auch damit kann man FF simulieren und das wird in der Zwischenzeit von 
der Synthse auch unterstützt.

Liebe Experten: Eingige Details habe ich unterschlagen, also bitte nicht 
hauen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Klaus Falser schrieb:
> Eingige Details habe ich unterschlagen
Einen hätte ich noch...
> Damit die Berechnung aber irgendwann aufhört und die Simulation in der
> Zeit weiterrücken kann, müssen irgendwo im Prozess wait-Statements
> vorhanden sein, wo der Prozess stoppt
Das ist dann genau die Stelle, an der Signalen der zuletzt zugewiesene 
Wert übergeben wird. Einen kombinatorischen Prozess könnte ich also so 
schreiben:
1
    process (A,B,C) begin
2
      D <= A and B or C;
3
    end process;
Und dieser Prozess ist exakt verhaltensgleich mit:
1
    process begin
2
      wait on A,B,C; 
3
      D <= A and B or C;
4
    end process;
Nur leider lässt sich der zweite Fall nicht synthetisieren. XST z.B. 
meint dazu:
"Supported with one signal in the sensitivity list"

: Bearbeitet durch Moderator
von Josef G. (bome) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> Ein Übergang von 'U' nach '1' wird im ersten Fall als steigende Flanke
> gewertet. In der Funktion rising_egde() wird auch noch
> clk'last_value='0' abgefragt.

Der Unterschied hat aber doch wohl nur Auswirkungen auf die
Simulation (falls tatsächlich undefinierte Zustände auftreten),
nicht aber auf die Synthese. Oder sehe ich das falsch?

von peter (Gast)


Lesenswert?

Jup danke für die ausführliche Erklärung.

Gruss

von Duke Scarring (Gast)


Lesenswert?

Josef G. schrieb:
> Der Unterschied hat aber doch wohl nur Auswirkungen auf die
> Simulation (falls tatsächlich undefinierte Zustände auftreten),
> nicht aber auf die Synthese.
Ja, nur für die Simulation. Das der Takt in der Simulation undefiniert 
ist, sollte ein unwahrscheinlicher Fall sein.
Nichtsdestotrotz ist rising_edge besser lesbar und schon deswegen zu 
bevorzugen.

Duke

von Christoph Z. (christophz)


Lesenswert?

Duke Scarring schrieb:
> Ja, nur für die Simulation. Das der Takt in der Simulation undefiniert
> ist, sollte ein unwahrscheinlicher Fall sein.

Jedes Signal ist zu Beginn der Simulation undefiniert ('U').

von Klaus F. (kfalser)


Lesenswert?

Christoph Z. schrieb:
> Duke Scarring schrieb:
>> Ja, nur für die Simulation. Das der Takt in der Simulation undefiniert
>> ist, sollte ein unwahrscheinlicher Fall sein.
>
> Jedes Signal ist zu Beginn der Simulation undefiniert ('U').

Nö.
Man kann ein Signal auch initialisieren:
1
signal clk : std_logic := '0';

von Christoph Z. (christophz)


Lesenswert?

Klaus Falser schrieb:
>> Jedes Signal ist zu Beginn der Simulation undefiniert ('U').
>
> Nö.
> Man kann ein Signal auch initialisieren:signal clk : std_logic := '0';

Ok, erwischt. Wenn die Signale in der Testbench initialisiert werden, 
dann sind sie nicht 'U' zu Beginn.

Ich mache das aber nicht. Sehr bewusst nicht, da beim Einschalten eines 
Gerätes ja auch nicht sofort alle Signale die in den FPGA hineingehen 
definierte Zustände haben.

Ich mache das bewusst um die Realität besser ab zu bilden. Aber jetzt wo 
ich mir die Frage noch mals stelle bin ich mir nicht mehr Sicher, ob ich 
dadurch überhaupt einen Vorteil habe, gewisse Fehler zu finden oder 
nicht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christoph Z. schrieb:
> Ich mache das aber nicht. Sehr bewusst nicht, da beim Einschalten eines
> Gerätes ja auch nicht sofort alle Signale die in den FPGA hineingehen
> definierte Zustände haben.
> Ich mache das bewusst um die Realität besser ab zu bilden. Aber jetzt wo
> ich mir die Frage noch mals stelle bin ich mir nicht mehr Sicher, ob ich
> dadurch überhaupt einen Vorteil habe, gewisse Fehler zu finden oder
> nicht.
Richtig, denn du müsstest eigentlich einen Zufallsgenerator über diese 
"undefinierten" Eingänge laufen lassen. Ein 'U' gibt es im echten Leben 
nicht. Auch wenn das Design mit einem 'U' umgehen könnte, die reale 
Hardware kann es nicht. Es gibt nur eine '0' oder eine '1'. Und 
schlimmstenfalls einen ungünstigen Zeitpunkt für eines der beiden...

von greg (Gast)


Lesenswert?

Die Initialisierung von Signalen ist schon deshalb sinnvoll, weil sonst 
die Simulation u.U. bei Zeitpunkt 0 mit "metavalue detected" u.ä. um 
sich wirft. Einen Reset braucht man natürlich normalerweise trotzdem.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

greg schrieb:
> Einen Reset braucht man natürlich normalerweise trotzdem.
Normalerweise nicht. Eher ausnahmsweise...

von greg (Gast)


Lesenswert?

Lothar Miller schrieb:
> greg schrieb:
>> Einen Reset braucht man natürlich normalerweise trotzdem.
> Normalerweise nicht. Eher ausnahmsweise...

Naja, in der Testbench nicht, aber die Hardware möchte man doch häufig 
auch ohne Neukonfiguration des FPGA zurücksetzen können.

von Duke Scarring (Gast)


Lesenswert?

greg schrieb:
> die Hardware möchte man doch häufig
> auch ohne Neukonfiguration des FPGA zurücksetzen können.
Nö. Warum einen Reset einbauen, wenn eine Rekonfiguration das gleiche 
(und das viel besser) bewirkt? Bei BRAMs z.B. wird es problematisch, die 
haben gar keinen Reset.

Anders sieht die Sache aus, wenn später mal aus meinem Design ein ASIC 
werden würde.

Duke

von Georg A. (georga)


Lesenswert?

> Naja, in der Testbench nicht,

Eigentlich gerade in der Testbench, um zB. den sauberen Startup unter 
verschiedenen Bedingungen zu testen ;)

IMO hängt das auch stark vom Coding-Style bzw. der Art der Entwicklung 
ab.

Ich mache zB. nur was mit FPGAs, bislang hatte auch noch keines meiner 
diversen FPGAs einen externen (globalen) Reseteingang.

Trotzdem mache ich in den Prozessen immer if reset .. elsif rising_edge 
statt Defaultzuweisung bei der Signaldeklaration. Die ist nämlich 
einerseits zeilenmässig "weit" vom Prozess weg, andererseits ist sie 
eine konzentrierte Zusammenfassung des Startzustands für genau den 
Prozess. Sonst muss man die gesamte Deklaration scannen, ob bzw. wo es 
da einen Defaultwert gibt.

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.