Moin,
Wenn ich 2 Clocks aus einer PLL_ADV eines Spartan6 hab', beide 50%
dutycycle, 0% phase, eine doppelt so hoch wie die andere, also z.b. fuer
clkx1 wird die VCO Frequenz durch 14 geteilt, fuer clkx2 durch 7.
Und ich hab' 2 Lanes, die mit der langsamen clk Daten anliefern; also
z.b. sowas:
1
if rising_edge(clkx1) then
2
lane0 <= ...
3
lane1 <= ...
4
end if;
Diese Daten will ich jetzt auf eine "fastlane" mit der doppelten Clk
zusammenmultiplexen. Ist sowas dann OK - irgendwie hab' ich da etwas
Bauchgrummeln?
die Clocks aus der PLL sind synchron (sollte zumindest so konfiguriert
werden), du kannst also mit der schnellen Clock die langsame abtasten
und umgekehrt.
Zu beginn sollte man jedoch eine Art "trigger" von der langsamen auf die
schnelle domain schicken, um die Position der Datenströme zu erkennen.
Oder du hast eine Reset-Schaltung die darauf Wert legt.
Ansonsten hast du einen Datenshift wie man im Bild bei dat1 und dat1*
sieht.
Deshalb nicht auf die Pegel der Taktleitungen schauen, sondern direkt
die Daten sampeln ohne CDC-Synchronizer.
Moin,
Jetzt wo ich's so vor mir seh' kommen mir mehr Zweifel:
1.) Die Daten auf Lane0 und Lane1 sind ja immer zu den selben
Zeitpunkten gueltig, d.h. die Unterscheidung in dem Bild nach dat1 und
dat1* ist mir unklar.
2.) Wenn ich die langsame clk durch die 2x schnellere clk abtaste, dann
sollte die doch eher 180° Phasenverschiebung (in den PLL-Einstellungen)
haben, wenn jeweils bei rising_edge() was passieren sollte. Sonst tastet
die schnelle Clk die langsame ja auch jeweils in ihren Flanken ab.
Wenn ich im UG382 das letzte Bild im .pdf, das Application Example
anguck', dann nehmen die wohl auch jeweils die rising edge als
referenzpunkt her.
Grmpf. wenn man sowas nicht andauernd macht....
Gruss
WK
Dergute W. schrieb:> Jetzt wo ich's so vor mir seh' kommen mir mehr Zweifel
Zweifel sind immer gut, dagegen hilft schon mal eine Testbench ;)
Dergute W. schrieb:> 1.) Die Daten auf Lane0 und Lane1 sind ja immer zu den selben> Zeitpunkten gueltig, d.h. die Unterscheidung in dem Bild nach dat1 und> dat1* ist mir unklar.
Inwiefern meinst du gültig? Ich wollte in dem Bild die zwei Fälle
darstellen. Denn wann wird auf der schnellen Taktdomäne das neue Datum
gesetzt?
Da ich deinen Generator nicht kenne, könnte das Datum auch einen Takt
(Clk1) versetzt gesetzt werden. dat1* ist einfach die Darstellung für
den Fall mit einem Taktversatz.
Dergute W. schrieb:> 2.) Wenn ich die langsame clk durch die 2x schnellere clk abtaste, dann> sollte die doch eher 180° Phasenverschiebung (in den PLL-Einstellungen)> haben, wenn jeweils bei rising_edge() was passieren sollte. Sonst tastet> die schnelle Clk die langsame ja auch jeweils in ihren Flanken ab.
Das ist ein Trugschluss. Man stelle sich das Problem mit der Übernahme
vor, dass clk1 und clk2 identisch wären bzw. dass es nur einen Takt
gibt. So ist das auch im synchronen Design. Der Router gewährleistet
hierbei, dass der Takt mit der richtigen Verzögerung ankommt.
Wenn nun Clk1 und Clk2 synchron definiert sind (das ist die
Standarddefinition), dann kann man sich auch auf die Übernahme
verlassen. Voraussetzung dafür ist aber noch, dass clk1 und clk2 an
ihrem Definitionspunkt auch wirklich synchron zueinander sind. Das gilt
für eine PLL, jedoch nicht für einen Flipflop-Taktteiler. Letzteres ist
ein anderes Thema.
Es würde auch mit 180° Versatz gehen, jedoch hat es mehrere Nachteile.
Es müssen beide Taktdomänen weiterhin synchron zueinander sein. Das
Übernahmefenster ist nicht mehr eine ganze Periode von clk1, sondern nun
eine Halbe, wodurch das Timing noch schwieriger ist.
Vorsichtig auch beim Simulieren. Die Takte sollten nicht mehr durch
irgendwelche Zuweisungen in der architecture beeinflusst werden, da die
Übernahme auf das Delta-Delay genau sein muss.
Also dann nicht sowas machen:
1
clka<=clk1;-- fügt Delta-Delay hinzu.
Dergute W. schrieb:> Wenn ich im UG382 das letzte Bild im .pdf, das Application Example> anguck', dann nehmen die wohl auch jeweils die rising edge als> referenzpunkt her.
Das würde ich auch so annehmen, aber man sieht nur die Takte.
Auch nach meinem Gefühl ist das nicht schön, einen Clock in einem If zu
benutzen, wenn man es auch vermeiden kann. Es soll ja keinen UART geben
mit Flankendetektion und so.
1
ifrising_edge(clkx2)then
2
lane1or2<=notlane1or2;
3
iflane1or2='0'then
4
fastlane<=lane0;
5
else
6
fastlane<=lane1;
7
endif;
8
endif;
Place&Route sollte von sich aus wissen, dass diese beiden Clocks in
Phase zu einander stehen, ansonsten kann das mit einer "generated_clock"
constraint (Tool abhängig) definiert werden.
Das Timing zwischen lane0 und fastlane muss die höhere Taktfrequenz von
clkx2 erfüllen (sollte das Tool automatisch so rapportieren).
Das Timing zwischen lane1 und fastlane kann mit einer "multi_cycle = 2"
contraint noch entspannt werden.
Du tastest ja nicht die eine clock mit der anderen ab, sondern deren
Daten.
Es ist richtig, dass hier ein Flankenproblem auftaucht, aber das führt
nur zu einer verschärften Problematik bei der Jitterbetrachtung durch
die Synthese, weil sie nun den Jitter beider Takte berücksichtigen muss.
Das führt dazu, dass weniger Zeit zwischen den beiden extremen Werten
der Taktflanken liegt und die Timingreserve sinkt. Real macht das aber
nicht so arg viel aus.
Wenn das tool sagt, dass das ok ist, reicht es. Gfs. braucht man einen
MAX_PATH-Constraint, um sicherzustellen, dass die Übergabe der Daten
konsistent ist. Es muss dafür gesorgt werden, dass die Daten, nach der
Flanke des Taktes eins, binnen der maximalen Periode das Taktes 2
vorhanden sind.
Das funktioniert auch bei nicht einfachen Taktverhältnissen, wie z:B:
3:4, solange sichergestellt ist, dass bei der kleinst möglichen Reserve
(1/4) immer noch genug Zeit ist, für die Kombinatorik. Natürlich geht
das irgendwann nicht mehr.