Xilinx ZYNQ/ARTIX7 Invert Clock ohne Skew

Für das HDL-Design, das ich derzeit für einen Zynq-SoC entwickle, muss ich ein Taktsignal wegen eines vertauschten Differenzpaars auf Platinenebene invertieren.

Die Verwendung von "NOT" zum Invertieren fügt dem Pfad eine LUT hinzu und führt als solche zu einer Verzerrung von mindestens 500 ps zwischen der invertierten und der ursprünglichen (die auch auf einen anderen Differenzausgang gelegt wird. Und das ist in unserem Fall zu viel).

Gibt es eine Möglichkeit, ein Taktsignal so zu invertieren, dass der Versatz zwischen dem Original und der invertierten Kopie minimal ist?

Ich habe eine mögliche Lösung mit dem ODDR-Grundelement gefunden, aber dies scheint eher eine Problemumgehung als eine Lösung zu sein.

Vielen Dank im Voraus.

Ist es eine Möglichkeit, die Verzerrung einzuschränken und nur die Synthese ihre Arbeit erledigen zu lassen, indem sie eine zusätzliche Verzögerung in das Originalsignal einfügt?
Können Sie einen verzögerungsfreien Puffer mit einer PLL-Ressource implementieren?
@DonFusili Könnte eine Möglichkeit sein, bisher habe ich so etwas noch nie ausprobiert. Ich werde dem nachgehen und mich bei Ihnen melden.
@SpehroPefhany Die Verwendung einer PLL-Ressource kommt wahrscheinlich nicht in Frage, da es sich bereits um die Ausgabe einer PLL handelt. Es ist zwar möglich, es zu invertieren, indem man die Phase auf 180 stellt. Die Phase wird bereits dynamisch gesteuert und sollte so beibehalten werden. Ich werde dem nachgehen und mich bei Ihnen melden.
@Thomas, das die Phase um 180 Grad ändert und dynamisch kontrolliert hält, schließt sich nicht gegenseitig aus.
Ich nehme an, Sie haben bereits eine Lösung gefunden, wollten aber nur anmerken: Führt eine Negation eines Signals (durch LUT-basierte Logik) nicht unbedingt die Möglichkeit von Störungen in den Übergängen ein? Mehrere andere Antworten / Kommentare scheinen darauf hinzudeuten, dass es funktionieren wird (und sie weisen nur darauf hin, dass es sich um eine unbequeme / komplizierte Lösung handelt); scheint mir, dass es nicht funktionieren kann. Übersehe ich etwas?

Antworten (2)

Bei Xilinx-Geräten ist die Verwendung eines ODDR tatsächlich die empfohlene Methode, um ein Taktsignal an einem Pin auszugeben, insbesondere wenn Sie enge Timing-Beschränkungen haben. Tun Sie dies sowohl für clkals auch clk180, und beide haben das gleiche, wiederholbare Timing. Es ist überhaupt kein Workaround.

Siehe Kommentar im Xilinx-Forum hier von einem Xilinx-Ingenieur:

ODDR behält den Arbeitszyklus bei und bietet den bestmöglichen Pfad. Kein Routing des Takts auf irgendeiner Verbindung, der Takt verbleibt auf den globalen Taktressourcen, wo sie hingehören.

Es wird auch im Xilinx 7-Series Select IO-Benutzerhandbuch , Seite 128, Abschnitt „OLOGIC-Ressourcen“ > „Uhrweiterleitung“ erwähnt:

Der Ausgangs-DDR kann eine Kopie der Uhr an den Ausgang weiterleiten. Dies ist nützlich, um einen Takt und DDR-Daten mit identischen Verzögerungen zu verbreiten und um mehrere Takte zu erzeugen

Sie könnten mit dem Ausgleich von LUT-Verzögerungen mit anderen LUTs, ODELAY und Einschränkungen herumspielen, aber dies wird nicht an die Einfachheit oder zeitliche Vorhersagbarkeit der ODDR-Methode heranreichen.

Sie könnten versuchen, beiden Ausgängen dieselbe Verzögerung hinzuzufügen. Der Trick besteht darin, eine Logik einzuführen, die nicht wegoptimiert werden kann, sondern eine LUT-Verzögerung hinzufügt.

Sie sind wahrscheinlich mit der Verwendung von EXOR-Gattern vertraut, um ein Signal bedingt zu invertieren.

Ich würde beiden Ausgangsports eine EXOR-Funktion hinzufügen. Das "Steuer"-Signal des einen EXOR ist hoch, das andere nicht. Das Steuersignal in jedes EXOR-Gatter muss so sein, dass es sich ändern kann . zB ein Register, in das Sie eine Eins oder Null schreiben können . Sie werden das niemals tun, aber die Synthesewerkzeuge wissen es nicht, also muss es das EXOR-Gatter behalten. Es kann es nicht wegoptimieren.


Gestern habe ich versucht zu verhindern, dass die Logik wegoptimiert wird, indem ich verschiedene Xilinx-Einschränkungen verwendet habe, aber ich bin gescheitert. Am Ende habe ich die oben beschriebene sichere Methode verwendet, aber ich habe einen Eingangspin verwendet, um sicherzustellen, dass die nicht invertierende LUT nicht wegoptimiert wird:

//
// Same delay path for o1 and o2 
// where o2 = ~o1
//
module keep (
   input  clk,
   input  reset_n,
   input  never_changes, // Always low 
   output o1,o2
  );

reg [1:0] count;

   // Some (arbitrary) test registers
   always @(posedge clk or negedge reset_n)
   begin
      if (!reset_n)
        count <= 2'b0;
      else
        count <= count + 2'b01;
   end  

/* 
   This did not work:   
   XOR2 X1(.I0(count[1]),.I1(1'b0),.O(o1));
   // synthesis attribute optimize of X1 is off
   XOR2 X2(.I0(count[1]),.I1(1'b1),.O(o2));
   // synthesis attribute optimize of X2 is off
 */
 // This can't fail: Note that never_changes should be low
   assign o1 = never_changes ^ count[1];
   assign o2 = ~count[1];

endmodule   

Das ist das Ergebnis der Ausgaben nach place & route:Geben Sie hier die Bildbeschreibung ein

Ich dachte auch an etwas wie das Hinzufügen einer LUT zum nicht invertierten Signalpfad, konnte aber keine Möglichkeit finden, eine einzuführen. Es könnte schwierig sein, das Synthesizer-Tool davon abzuhalten, es zu optimieren. Ich werde es versuchen und mich wieder melden. Danke!
Dies wird funktionieren, scheint aber eine verschleierte Problemumgehung zu sein, wenn der Zynq-SoC über ODelay-Primitive verfügt.
Das in Ihrem obigen Code zu verwendende Attribut wäre keep, not optimize.