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.
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 clk
als 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
keep
, not optimize
.
DonFusili
Spehro Pefhany
Thomas
Thomas
DonFusili
Cal-Linux