Ich habe eine Bussynchronisationsschaltung zum Weiterleiten eines breiten Registers über Taktdomänen.
Ich werde eine vereinfachte Beschreibung bereitstellen, wobei die asynchrone Rücksetzlogik weggelassen wird.
Die Daten werden auf einer Uhr generiert. Updates sind viele (mindestens ein Dutzend) Taktflanken voneinander entfernt:
PROCESS (src_clk)
BEGIN
IF RISING_EDGE(clock) THEN
IF computation_done THEN
data <= computation;
ready_spin <= NOT ready_spin;
END IF;
END IF;
END PROCESS;
Das Steuersignal für frische Daten, das NRZI-codiert ist (ein gültiges Wort auf dem Bus entspricht also einem Übergang auf dem Steuersignal). Das Steuersignal durchläuft eine DFF-Kette, die als Synchronisierer fungiert.
PROCESS (dest_clk)
BEGIN
IF RISING_EDGE(dest_clk) THEN
ready_spin_q3 <= ready_spin_q2;
ready_spin_q2 <= ready_spin_q1;
ready_spin_q1 <= ready_spin;
END IF;
END PROCESS;
Die Synchronisationsschaltung führt eine kurze Verzögerung ein, die dem Datenbus genügend Zeit zur Stabilisierung bietet. Der Datenbus wird direkt ohne Metastabilitätsrisiko abgetastet:
PROCESS (dest_clk)
BEGIN
IF RISING_EDGE(dest_clk) THEN
IF ready_spin_q3 /= ready_spin_q2 THEN
rx_data <= data;
END IF;
END IF;
END PROCESS;
Dies kompiliert und funktioniert gut, wenn es zu einem Cyclone II-FPGA synthetisiert wird. TimeQuest meldet jedoch Verstöße gegen die Setup- und Haltezeit, da der Synchronizer nicht erkannt wird. Schlimmer noch, sagt das Quartus-Handbuch
Konzentrieren Sie sich darauf, die Pfade zu verbessern, die den schlechtesten Durchhang aufweisen. Der Monteur arbeitet am härtesten auf Wegen mit dem schlechtesten Durchhang. Wenn Sie diese Pfade korrigieren, kann der Monteur möglicherweise die anderen fehlerhaften Timing-Pfade im Entwurf verbessern.
Daher möchte ich meinem Projekt die richtigen zeitlichen Einschränkungen hinzufügen, damit Quartus seine Fitter-Bemühungen für andere Bereiche des Designs ausgibt.
Ich bin mir ziemlich sicher, dass dies set_multicycle_path
der richtige SDC-Befehl (Synopsis Design Constraint) ist, da die Datenleitungen mehrere Zyklen der Zieluhr haben, um sich zu stabilisieren, aber ich kann keine vollständigen Beispiele finden, die diesen Befehl verwenden, um die Logik der Taktdomänenkreuzung zu beschreiben .
Ich würde mich sehr über eine Anleitung zum Schreiben von SDC-Zeiteinschränkungen für Synchronisierer freuen. Wenn Sie ein Problem mit diesem Ansatz sehen, lassen Sie es mich bitte auch wissen.
Uhrendetail:
Externer Taktgenerator: Zwei Kanäle, refclk = 20 MHz, refclk2 = refclk / 2 (10 MHz und verwandte).
Altera PLL: src_clk = refclk * 9/5 = 36 MHz
Altera PLL: dest_clk = refclk2 * 10 = 100 MHz
Ich habe auch Daten in die andere Richtung, mit 100 MHz src_clk und 36 MHz dest_clk.
TL; DR: Was sind die korrekten SDC-Zeiteinschränkungen für den obigen Code?
Antworten:
Ich habe keine Erfahrung mit Quartus, also behandeln Sie dies als allgemeinen Rat.
Bei der Arbeit an Pfaden zwischen Taktdomänen erweitern Timing-Tools die Uhren auf das am wenigsten verbreitete Vielfache ihrer Perioden und wählen das nächstgelegene Kantenpaar aus.
Wenn ich bei Pfaden von einem 36-MHz-Takt (27,777 ns) zu einem 100-MHz-Takt (10 ns) meine schnellen Berechnungen korrekt durchgeführt habe, beträgt das nächste Paar ansteigender Flanken 138,888 ns im Quelltakt und 140 ns im Zieltakt. Das ist effektiv eine 900-MHz-Einschränkung für diese Pfade! Abhängig von der Rundung (oder für Uhren ohne Beziehung) kann es schlimmer kommen.
Es gibt mindestens drei Möglichkeiten, Einschränkungen für diese Struktur zu schreiben. Ich werde die Uhren rufen
fast_clk
undslow_clk
wie ich denke, ist das zur Veranschaulichung klarer.Option 1: Deaktivieren Sie das Timing mit
set_false_path
Die einfachste Lösung besteht darin
set_false_path
, das Timing zwischen den Uhren zu deaktivieren:Dies ist nicht unbedingt korrekt, da für die ordnungsgemäße Funktion des Synchronisierers zeitliche Anforderungen gelten. Wenn die physische Implementierung die Daten relativ zum Steuersignal zu stark verzögert, funktioniert der Synchronisierer nicht. Da sich jedoch keine Logik auf dem Pfad befindet, ist es unwahrscheinlich, dass die Zeiteinschränkung verletzt wird.
set_false_path
wird häufig für diese Art von Struktur verwendet, selbst in ASICs, bei denen der Kompromiss zwischen Aufwand und Risiko bei Fehlern mit geringer Wahrscheinlichkeit vorsichtiger ist als bei FPGAs.Option 2: Lockern Sie die Einschränkung mit
set_multicycle_path
Sie können für bestimmte Pfade mit zusätzliche Zeit einplanen
set_multicycle_path
. Es ist üblicher, Mehrradpfade mit eng verwandten Uhren zu verwenden (z. B. Interaktion zwischen 1X- und 2X-Uhren), aber dies funktioniert hier, wenn das Tool dies ausreichend unterstützt.Die Standardkantenbeziehung für das Setup ist Einzelzyklus, d
set_multicycle_path 1
. H. Diese Befehle ermöglichen einen weiteren Zyklus der Endpunktuhr (-end
) für Setup-Pfade. Die-hold
Einstellung mit einer Nummer eins, die unter der Einrichtungsbeschränkung liegt, ist fast immer erforderlich, wenn mehrere Zykluspfade festgelegt werden. Weitere Informationen finden Sie weiter unten.Um Pfade in die andere Richtung ähnlich einzuschränken (Lockerung der Beschränkung um eine Periode der schnelleren Uhr), wechseln Sie
-end
zu-start
:Option 3: Anforderung direkt mit angeben
set_max_delay
Dies ähnelt dem Effekt von
set_multicycle_path
, erspart jedoch das Durchdenken der Kantenbeziehungen und des Effekts auf Haltebeschränkungen.Möglicherweise möchten Sie dies
set_min_delay
für Halteprüfungen koppeln oder die Standard-Halteprüfung beibehalten. Möglicherweise können Sie auchset_false_path -hold
Halteprüfungen deaktivieren, wenn Ihr Tool dies unterstützt.Wichtige Details der Kantenauswahl für Mehrzykluspfade
Betrachten Sie dieses einfache Beispiel mit einer 3: 2-Beziehung, um die Halteeinstellung zu verstehen, die mit jeder Setup-Anpassung gekoppelt wird. Jede Ziffer repräsentiert eine steigende Taktflanke:
Bei der Standard-Setup-Prüfung werden die Kanten 2 und 6 verwendet. Bei der Standard-Halteprüfung werden die Kanten 1 und 4 verwendet.
Durch Anwenden einer Mehrzyklusbeschränkung von 2 mit wird
-end
die Standardeinstellung für Einrichtungs- und Halteprüfungen angepasst, um die nächste Kante nach der ursprünglichen Verwendung zu verwenden. Dies bedeutet, dass bei der Einrichtungsprüfung jetzt die Kanten 2 und 7 und bei der Halteprüfung die Kanten 1 und 5 verwendet werden. Für zwei Bei dieser Taktfrequenz ist diese Einstellung sinnvoll. Jeder Datenstart entspricht einer Datenerfassung. Wenn die Erfassungskante um eins verschoben wird, sollte sich auch die Halteprüfung um eins verschieben. Diese Art von Einschränkung kann für zwei Zweige eines einzelnen Takts sinnvoll sein, wenn einer der Zweige eine große Verzögerung aufweist. Für die Situation hier ist jedoch eine Halteprüfung unter Verwendung der Flanken 1 und 5 nicht wünschenswert, da die einzige Möglichkeit, dies zu beheben, darin besteht, dem Pfad einen gesamten Taktzyklus der Verzögerung hinzuzufügen.Die Mehrzyklus-Haltebeschränkung von 1 (für Halten ist die Standardeinstellung 0) passt die Flanke des Zieltakts uesd für Halteprüfungen um eine Flanke rückwärts an. Die Kombination von 2-Zyklus-Setup-MCP und 1-Zyklus-Halte-MCP-Einschränkungen führt zu einer Setup-Prüfung unter Verwendung der Kanten 2 und 7 und einer Halteprüfung unter Verwendung der Kanten 1 und 4.
quelle
Ich kenne die Antwort für Altera nicht, aber in Xilinx Land können Sie die Zeitverzögerung von einer Uhrdomäne zur nächsten einstellen. Sie müssen die Mathematik ausarbeiten (sie ist designabhängig), aber es ist normalerweise die kürzeste der beiden Taktperioden. Stellen Sie sich diese Zeit als den maximalen Versatz zwischen zwei beliebigen Signalen (einschließlich Ihres Steuersignals) vor, und Sie können herausfinden, ob Ihre Synchronisationsschaltung damit umgehen kann.
set_mulicycle_path ist nicht die richtige Verwendung, da dies normalerweise Fälle betrifft, in denen sich Quelle und Ziel in derselben Taktdomäne befinden. Auch hier stütze ich mich auf meine Xilinx-Erfahrung, sodass Ihr Kilometerstand variieren kann.
quelle
Ich denke, es ist sicher, einen set_false_path über den Synchronizer zu setzen.
Sie können auch "set_global_assignment -name SYNCHRONIZER_IDENTIFICATION AUTO" in das qsf einfügen, um Quartus dabei zu helfen, den Synchronizer zu erkennen.
quelle
set_false_path -from ready_spin -to ready_spin_q2
? Undset_false_path -from data -to rx_data
?set_false_path -from src_clk -to ready_spin
Ich bin nicht sicher, ob es angemessen ist, den falschen Pfad für Daten festzulegen, da Sie ihn nicht synchronisieren.Ich vermute, das Problem ist, dass, obwohl Sie vielleicht wissen, dass sich die Bussignale in der Nähe des Punktes, an dem sie verriegelt sind, nicht ändern werden, die Software dies nicht weiß. Am besten teilen Sie der Software explizit mit, dass die eingehenden Bussignale mit der Busuhr synchronisiert sind, und deaktivieren Sie alle Optimierungen vor dem Ort, an dem Sie sie tatsächlich verriegeln (ein Optimierer könnte theoretisch Ihre Schaltung durch eine äquivalente ersetzen wenn die Eingänge wirklich synchron wären, die aber für eine Schleife geworfen werden könnten, wenn sie sich in Taktzyklen ändern, die die von Ihnen gezeichnete Schaltung nicht interessieren würde).
quelle
set_multicycle_path
die Möglichkeit, dem Synthesizer / Timing-Analysator mitzuteilen, wie oft sich die Quellensignale ändern können? Und ich bin mir nicht sicher, was Sie unter "Busuhr" verstehen. Hier kreuzt ein Signalbus die Uhrendomänen. Welche Uhr nennen Sie also die "Busuhr"? Ich denke, Sie haben Recht, dass es immer noch zu Metastabilitäten kommen kann, wenn der Synthesizer in Zeiten, in denen ich nicht aktualisiere, Störungen einführtdata
. Ich denke, ich könnte dort speziell DFF-Blöcke instanziieren :(