Forum: FPGA, VHDL & Co. inferring latches - was ist hier die Ursache?


von Andi M. (andi6510) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich überarbeite gerade ein etwas älteres Verilog-Projekt und möchte dort 
die Anzahl der Warnings mal wieder auf ein akzeptables Niveau bringen. 
Das ganze findet unter Quartus Prime 22.1 lite statt.

An einer Sache beisse ich mir leider die Zähne aus:
Warning (10240): Verilog HDL Always Construct warning at 
registers.v(22): inferring latch(es) for variable "r_flash_addr", which 
holds its previous value in one or more paths through the always 
construct
(Im Anhang findet ihr registers_.v - ein Auszug aus der genannten 
registers.v - die Zeilennummer in der Warning habe ich an registers_.v 
angepasst)

Diese warning kommt genau so für die reg variablen r_flash_addr, 
r_flash_ctrl, r_flash_data_out, r_flash_write, r_flash_autoinc, 
r_flash_ctrl_wr, r_flash_data_wr, r_reconfig
aber NICHT für die anderen reg variablen, die in diesem always construct 
verwendet werden.

Wo liegt also das Problem? Sicher weise ich nicht allen r_* variablen in 
jedem Zweig des doch etwas verschachtelten if/case Konstrukts einen Wert 
zu. Aber das ist ja nichts Ungewöhnliches, dass man Register updated, 
wenn eine Bedingung erfüllt ist. Und ein (synchrones) latch-Verhalten 
ist ja sogar gewünscht. Aber wieso warnt mich Quartus davor? Und wenn 
die Warning aus der Kategorie "kann man ignorieren" ist, würde ich 
trotzdem gerne verstehen, warum sie gerade in diesem speziellen Fall 
getriggert wird.

Und ja ich weiss, der Code ist gruselig. Er ist über die Zeit 
"gewachsen" und gehört auch dringend aufgeräumt. Aber da werdet ihr mich 
sicher noch ein paarmal drauf hinweisen, wofür ich mich schon jetzt 
bedanke.
Noch viel mehr bin ich auf wirklich sachdienliche Beitraege gespannt! 
;-)

Andi

von Gustl B. (gustl_b)


Lesenswert?

Nimm mal die negative Flanke von rstb raus. Ob der Reset aktiv ist wird 
ja sowieso nochmal abgefragt.

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


Lesenswert?

Gustl B. schrieb:
> Nimm mal die negative Flanke von rstb raus. Ob der Reset aktiv ist wird
> ja sowieso nochmal abgefragt.
Das Weglassen des Resets in der Sensitivliste macht implizit aus einem 
asynchronen Reset einen synchronen Reset.

Und spätestens dann darf natürlich keine Warnung mehr kommen...

von T.U.Darmstadt (Gast)


Lesenswert?

Lothar M. schrieb:
> Das Weglassen des Resets in der Sensitivliste macht implizit aus einem
> asynchronen Reset einen synchronen Reset.

Warum ist das so? Weil dann ein Register entsteht?
Ist aber meine ich eine etwas diffuse Methode, latches zu vermeiden, 
oder?

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


Lesenswert?

Thomas U. schrieb:
> Weil dann ein Register entsteht?
Ja.

Und wenn dann die Meldung weg ist, dann hat es was mit dem asynchronen 
Reset zu tun.

> Ist aber meine ich eine etwas diffuse Methode, latches zu vermeiden,
> oder?
Ja, sicher. Aber ich würde den Reset eh komplett rausmachen und mich auf 
die Initialwerte verlassen. Das FPGA wird beim Start sowieso Register 
für Register mit definierten Werten vorbelegt.

von Gustl B. (gustl_b)


Lesenswert?

Lothar M. schrieb:
> Das Weglassen des Resets in der Sensitivliste macht implizit aus einem
> asynchronen Reset einen synchronen Reset.

Im Grunde ja, aber ... das ist keine Sensitivitätsliste, sondern da wird 
neben einer echten Taktflanke auch noch die Flanke vom Reset verwendet. 
Also in vhdl wäre das ein if falling_edge() then ...
Und das wird wohl so nicht gebaut weil das nicht geht oder weil erkannt 
word, dass der Reset kein Takt ist.

von Andi M. (andi6510) Benutzerseite


Lesenswert?

Gustl B> Nimm mal die negative Flanke von rstb raus
Also, das negedge vom reset zu entfernen ist nicht zielführend. Danach 
glaubt die Synthese, dass es sich um einen reinen Logikblock handelt und 
will alle anderen Signale im always block auch noch in der sensitivity 
list haben. Das fuerhrt zu nichts

Lothar M.> Aber ich würde den Reset eh komplett rausmachen und mich auf
Lothar M.> die Initialwerte verlassen.
äh, ich möchte aber, das die Register bei einem externen Reset 
zurückgesetzt werden und nicht nur beim Konfigurieren des FPGA. Den 
Reset werde ich daher ganz sicher nicht weglassen!

Lothar M.> Das Weglassen des Resets in der Sensitivliste macht implizit 
aus
Lothar M.> einem asynchronen Reset einen synchronen Reset.
Lothar M.> Und spätestens dann darf natürlich keine Warnung mehr 
kommen...
Stimmt! Wenn ich den Reset ganz aus der sensivity list entferne, sind 
die Warnings weg. Damit habe ich den Reset fuer genau diesen Block jetzt 
also synchron gemacht. Das ist glaube ich auch ganz OK so, denn das rstb 
Signal wird ohnehin vom externen Reset Signal noch in die clkb-domain 
eingesynct. Der Reset ist daher also schon mehr oder weniger synchron.

Ich verstehe trotzdem noch nicht, warum ich die Warning in diesem 
speziellen Fall bekommen habe. Ich habe im Design hunderte solche always 
Blöcke mit genau diesem asynchronen reset. Ich habe nirgends inferred 
latches gemeldet bekommen. Nur hier! Warum? Und warum nicht für alle 
reg-Variablen im always block? Es bleibt für mich ein Rätsel.

von Gustl B. (-gb-)


Lesenswert?

Andi M. schrieb:
> Also, das negedge vom reset zu entfernen ist nicht zielführend.

Ich meinte schon das ganze " or negedge rstb" rausnehmen.

Andi M. schrieb:
> sensivity list

Das ist es aus meiner Sicht nicht.

Kannst du mal den kompletten Code posten? Ich würde das gerne auch
simulieren können. Und vielleicht nach VHDL übersetzen ...

: Bearbeitet durch User
von Andi M. (andi6510) Benutzerseite


Lesenswert?

Gustl B.> Kannst du mal den kompletten Code posten?
Leider nein :-(

von Gustl B. (-gb-)


Lesenswert?

OK, auch kein Problem.

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


Lesenswert?

Gustl B. schrieb:
> da wird neben einer echten Taktflanke auch noch die Flanke vom Reset
> verwendet
Das ist zwar seltsam, dass der Reset augenscheinlich flankensensitiv 
aussieht, aber das ist halt einfach Verilog:
- Beitrag "Re: ständig Fehlermeldung bei Verilog Code"
- Beitrag "Re: Verilog Sensitivitätsliste"
- Beitrag "Re: Frage zur Lernkurve VHDL vs. Verilog"

Andi M. schrieb:
> äh, ich möchte aber, das die Register bei einem externen Reset
> zurückgesetzt werden und nicht nur beim Konfigurieren des FPGA.
Brauchst es das Design auch? Oder brauchst du das nur während der 
Entwicklung?

: Bearbeitet durch Moderator
von Andi M. (andi6510) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Brauchst es das Design auch? Oder brauchst du das nur während der
> Entwicklung?
Das Design verlangt dies.

von Markus W. (mwww)


Lesenswert?

Andi M. schrieb:
> Gustl B.> Kannst du mal den kompletten Code posten?
> Leider nein :-(

Ein minimum working example wäre schon schick. Den obigen Code zu einem 
module machen und zeigen, dass sich das Verhalten damit reproduzieren 
lässt. Evtl. siehst du ja dann schon selbst ein Problem oder es wirft 
die Warnung gar nicht, so dass wir den Fehler anhand dieses Auszugs nie 
identifizieren könnten.

Worüber ich bei Verilog-Syntax gelegentlich stolpere, ist das begin und 
end (zumindest mein Editor zeigt die jeweilige Zugehörigkeit nicht so 
schön wie bei der Verwendung von Klammern). Entweder man vergisst es 
komplett, und dann wird nur die erste Zeile nach der Anweisung als 
zugehörig interpretiert; oder man setzt das end zu früh.

Mal angenommen, das end zu deinem clock-Block wäre zu früh, dann steht 
der Rest halt nicht synchron im Prozess und es baut einen Latch.

von -gb- (Gast)


Lesenswert?

Lothar M. schrieb:
> Andi M. schrieb:
>> äh, ich möchte aber, das die Register bei einem externen Reset
>> zurückgesetzt werden und nicht nur beim Konfigurieren des FPGA.
> Brauchst es das Design auch? Oder brauchst du das nur während der
> Entwicklung?
... aber nicht auf der Flanke des Resetsignals oder?

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


Lesenswert?

G. B. schrieb:
> ... aber nicht auf der Flanke des Resetsignals oder?
Nochmal: genau so, mit "negedge" oder "posedge", sieht in Verilog die 
Beschreibung eines Low- bzw. Highaktiven asynchronen Resets aus. Lies 
die Links.

So ungewohnt und unlogisch sich das liest: es ist einfach eines der 
Dinge, die man wissen muss und die bei Verilog halt einfach so sind.

Ich finde das auch sehr "tuitiv" (was das Gegenteil von "intuitiv" ist, 
so wie "tolerant" das Gegenteil von "intolerant" ist).

von DSGV-Violator (Gast)


Angehängte Dateien:

Lesenswert?

>> äh, ich möchte aber, das die Register bei einem externen Reset
>> zurückgesetzt werden und nicht nur beim Konfigurieren des FPGA.
>Brauchst es das Design auch? Oder brauchst du das nur während der
>Entwicklung?


>> Brauchst es das Design auch? Oder brauchst du das nur während der
>> Entwicklung?
> Das Design verlangt dies.

Was verlangt die Spec. aka Design?

Einen Flanken-sensitiven Reset?
Oder genügt das das FF auf ein externes Sugnal Pegelgesteuert hin 
einendefinierten Zustand (0 oder 1) annimmt.

Letzteres könnte man auch bei einem FF ohne dedizierten Reseteintgang 
erreichen, beispielsweise DD-FF mit Muxer?

Dort hat Xilinx ab p. 337 auf über 100 Seiten u.a. Verilog-Beispiele 
geliefert wie man die verschiedenen FF-Typen vom D-FF bis zum FJKSRE so 
coded, das der Synthesizer auch das geforderte macht. Also was forderst? 
Ein Register mit externen Reset? Erfüllt ein FDCP deine Anforderungen? 
Dann nimm den dort genannten Verilog Code.

Eine (ungeprüfte) Verhaltensbeschreibung ist im Anhang, enrnohmen aus 
https://www.physi.uni-heidelberg.de/~angelov/VHDL/VHDL_SS09_Teil10.pdf .


*****
>Ich finde das auch sehr "tuitiv" (was das Gegenteil von "intuitiv" ist,
>so wie "tolerant" das Gegenteil von "intolerant" ist).

Naja, das gesprochenen Wort ist nicht den harten Regeln der Logik wie 
bspw. Negation unterworfen. Als "Gegen-wort/-phrase" von intuitiv ("auf 
Vermutung beruhend") könnte man IMHO da eher "Nachrecherchiert" oder 
"verlangt auswendiges Lernen" setzen. Auswendig Lernen ist nicht so 
bequem wie "seinem Bauchgefühl folgen" oder "aus den Finger saugen", 
aber eben oft notwendig.

https://de.wiktionary.org/wiki/intuitiv

von Vancouver (vancouver)


Lesenswert?

Der Code ist vermutlich nicht vor dir und deswegen willst du möglichst 
wenig ändern, das ist verständlich. Aber das Problem ließe sich 
vermutlich relativ leicht finden, wenn du den absurd komlizierten 
always-Block zerlegen würdest, indem die ganze kombiatorische Logik in 
eine eigene always-Umgebung kommt und der getaktete always-Block nur 
die Register enthält. So verlangen es die meisten Verilog-Designguides 
(außer bei sehr einfachen Designs) und das aus gutem Grund.

Zum Reset: Bist du sicher, dass der Reset einfach komplett 
einsynchronisiert wird, oder nur die inaktive (also steigende) Flanke? 
Manche Designs müssen auch Reset-fähig sein, wenn der Takt ausfällt oder 
noch nicht da ist, und dann verbietet sich ein synchroner Reset. In 
diesem Fall wird nur die "Rückseite" des Resets synchonisiert 
(https://www.embedded.com/asynchronous-reset-synchronization-and-distribution-challenges-and-solutions/) 
um Metastbilitäten zu vermeiden.

Abgesehen davon würde ich mich auf keinen Fall darauf verlassen, dass 
das Problem der obskuren Latches gelöst ist, nur weil dann die 
Fehlermeldung verschwindet, wenn du einen synchronen Reset verwendest.

von J. S. (engineer) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Thomas U. schrieb:
>> Weil dann ein Register entsteht?
> Ja.

Das scheint einigen nicht so klar zu sein. Jüngst gab es eine Diskussion 
im Rahmen einer Projektbewerbung, da wollte ein Schlaumeier unbedingt 
testen, ob ich wüsste, wie solche latches entstehen. Mein Beispiel war 
genau dieses, das Weglassen eines Registers durch mangelnde 
Beschreibung. Er war wehemend der Meinung dass das nicht gehe und 
dadurch nichts passieren könne. War ein Physiker, der sich VHDL selber 
beigebracht hat. :-)

Vancouver schrieb:
> Manche Designs müssen auch Reset-fähig sein, wenn der Takt ausfällt oder
> noch nicht da ist,
ja, die Panik vom vor sich hin schludernden FPGA, dessen Ausgänge nicht 
definiert sind, weil die PLL nicht will oder noch nicht kann. Schaut man 
sich mal an, wie lange ein FPGA beim power up lädt und praktisch nicht 
in der Schaltung ist und wie schnell ein Oszillator anfängt, dann 
bleiben von den Sekunden des Tiefschlafs bis zum Erwachen gerade einige 
us, in denen ein solcher Reset überhaupt noch einen kleinen Unterschied 
macht. Wenn man die Elektronik so baut, dass sie mit einem schlafenden 
FPGA klarkommt, also die Ausgänge steuert und damit alles innendrin 
abhängt, braucht man keine gewaltigen Resetbäume und die auch nicht 
asynchron.

> In diesem Fall wird nur die "Rückseite" des Resets synchonisiert
was auch schon resourcen verbraucht und zusammen mit dem aysynch Part 
noch mehr verbrutzelt ohne wirklichen Wert. Ein FPGA dessen PLL nicht 
will und das nicht synchron arbeitet, kann auch nach dem schönsten reset 
nicht mehr weiterarbeiten, von daher ist das eh Wuppe. Wichtiger ist ein 
PLL-unabhängier Anlauf- und Überwachungsschaltkreis, der power on 
losläuft,  die Ausgänge bedient und PLLs bootet (und alles andere, was 
so in Blockdiagrammen an MCU- und AXI Gedöhns instanziiert wird).

Vancouver schrieb:
> um Metastbilitäten zu vermeiden.
Naja, die MS sind eher unwahrscheinlich - es geht einfach um den 
Resetbaum an sich und den Umstand, dass auch ganz ohne Meta das Signal 
an unterschiedlichen Stellen anders eingetaktet wird und damit ungültige 
Zustände entstehen, weil die vielen lokalen FFs es zu leicht anderen 
Zeiten "sehen". Das passiert im Übrigen auch beim Resetten selber: Je 
nach Länge der Kombinarik in einer Schaltung, produziert der aysnch 
reset auch kurz ungültige Zustände und so kann man beim resetten 
durchaus Hazzards an den Ausgängen sehen, die es im synchronen Fall 
nicht gäbe.

Daher: Primär die Ausgänge des FPGAs steuern und gut ist. Dann brauchen 
viele Schaltungsteile keinen Reset und schon gar keinen asynchronen.

: Bearbeitet durch User
von Vancouver (vancouver)


Lesenswert?

Jürgen S. schrieb:
> ja, die Panik vom vor sich hin schludernden FPGA, dessen Ausgänge nicht
> definiert sind, weil die PLL nicht will oder noch nicht kann. Schaut man
> sich mal an, wie lange ein FPGA beim power up lädt und praktisch nicht
> in der Schaltung ist und wie schnell ein Oszillator anfängt,

Es gibt schlichtweg Designs, die solche Anforderungen haben, weil sie 
sonst keine Sicherheitszertifizierung bekommen. Und manchmal muss erst 
ein Microcontroller booten und die PLL konfigurieren, bevor der FPGA 
loslegen kann. Und machmal möchte man eben nur Teile des FPGAs resetten, 
während der Rest weiterlaufen soll. Und manchmal möchte man hinterher 
wissen, welches Ereignis für den Reset verantwortlich war, und es dazu 
in einem Register speichert. Und manchmal verwendet man FPGA als 
Prototyping für ASICs, und bei denen klappt der Trick mit dem 
Neukonfigurieren nicht. Und machmal möchte man ein Design einfach nur 
plattformumabhängig halten. In allen anderen Fällen braucht man keinen 
Reset.

Jürgen S. schrieb:
> was auch schon resourcen verbraucht und zusammen mit dem aysynch Part
> noch mehr verbrutzelt ohne wirklichen Wert.

Wenn die drei zusätzlichen FFs ein Problem sind, ist das Design ohnehin 
schon reichlich auf Kante genäht, dann hast du andere Probleme...

von -gb- (Gast)


Lesenswert?

Vancouver schrieb:
> Und machmal möchte man eben nur Teile des FPGAs resetten,
> während der Rest weiterlaufen soll.

asynchron??

von T.U.Darmstadt (Gast)


Lesenswert?

Lothar M. schrieb:
> Ja, sicher. Aber ich würde den Reset eh komplett rausmachen und mich auf
> die Initialwerte verlassen. Das FPGA wird beim Start sowieso Register
> für Register mit definierten Werten vorbelegt.

Beim Xilinx allemal. Beim Altera war das aber doch anders? Die 
propklamieren doch ihren asynchronen Eingang für die FlipFlops.

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


Lesenswert?

T.U.Darmstadt schrieb:
> Beim Altera war das aber doch anders? Die propklamieren doch ihren
> asynchronen Eingang für die FlipFlops.
Auch bei Altera/Intel können die Flipflops schon lange mit Initalwerten 
vorbelegt werden:
- Beitrag "Re: Initialwert und Reset"

Und das, was im Code oben als Resetwerte angegeben ist, sind also 
eigentlich genau solche Initialwerte.

Ein Reset ist das, was im FPGA laufend passiert: ein Zähler oder ein 
Register oder ein Flipflop wird zurückgesetzt. Dafür ist der 
Reset-Eingang am Flipflop da. Und dafür sollte der Code dann so 
geschrieben sein, dass passend zum verwendeten FPGA was Effizientes 
herauskommt:
- 
https://www.mikrocontroller.net/articles/VHDL#Synchroner_oder_asynchroner_Reset?
- https://www.mikrocontroller.net/articles/Reset_f%C3%BCr_FPGA/CPLD
- Beitrag "Re: Hardware mit VHDL "richtig" beschreiben."

: Bearbeitet durch Moderator
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.