Zeitbeschränkung für Bussynchronisierschaltungen

10

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_pathder 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?

Ben Voigt
quelle
1
Dies wäre auf der vorgeschlagenen FPGA-Design-Website besser, aber dieser Vorschlag hat die Beta noch nicht erreicht.
Ben Voigt
Können Sie die Uhrdefinitionen für src_clk und dest_clk veröffentlichen? Sind sie in irgendeiner Weise verwandt (synchrone Vielfache)? Wenn es sich um nicht verwandte Uhren handelt, ist es in dieser Situation typisch, set_false_path zu verwenden.
Andy
@ Andy: Ich habe einige Details hinzugefügt. Vielen Dank für Ihre Hilfe.
Ben Voigt

Antworten:

9

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_clkund slow_clkwie 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:

set_false_path -from [get_clocks fast_clk] -to [get_clocks slow_clk]
set_false_path -from [get_clocks slow_clk] -to [get_clocks fast_clk]

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_pathwird 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.

set_multicycle_path 2 -from [get_clocks slow_clk] -to [get_clocks fast_clk] -end -setup
set_multicycle_path 1 -from [get_clocks slow_clk] -to [get_clocks fast_clk] -end -hold

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 -holdEinstellung 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 -endzu -start:

set_multicycle_path 2 -from [get_clocks fast_clk] -to [get_clocks slow_clk] -start -setup
set_multicycle_path 1 -from [get_clocks fast_clk] -to [get_clocks slow_clk] -start -hold

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.

set_max_delay 10 -from [get_clocks fast_clk] -to [get_clocks slow_clk]
set_max_delay 10 -from [get_clocks slow_clk] -to [get_clocks fast_clk]

Möglicherweise möchten Sie dies set_min_delayfür Halteprüfungen koppeln oder die Standard-Halteprüfung beibehalten. Möglicherweise können Sie auch set_false_path -holdHalteprü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:

1     2     3
4   5   6   7

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 -enddie 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.

Andy
quelle
2

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
1

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.

fbo
quelle
Wie würde das aussehen? set_false_path -from ready_spin -to ready_spin_q2? Und set_false_path -from data -to rx_data?
Ben Voigt
set_false_path -from src_clk -to ready_spinIch bin nicht sicher, ob es angemessen ist, den falschen Pfad für Daten festzulegen, da Sie ihn nicht synchronisieren.
fbo
0

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).

Superkatze
quelle
Wäre es nicht set_multicycle_pathdie 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ührt data. Ich denke, ich könnte dort speziell DFF-Blöcke instanziieren :(
Ben Voigt
@BenVoigt: Ich denke, "set_multicycle_path" wird häufiger verwendet, um dem Timing-Validator mitzuteilen, dass eine Kette kombinatorischer Logik zwischen zwei Verriegelungspunkten N (Tc) -Ts-Tp (N-fache Zykluszeit minus Abtastzeit minus Verriegelung) aufnehmen darf Laufzeit) statt nur Tc-Ts-Th. Ich weiß nicht, wie so etwas mit dem Einrasten durch verschiedene Uhren interagieren würde.
Supercat