Ich stehe vor folgendem Problem:
Ich habe eine FPGA-Schaltung, die mit einem Oszillator gespeist wird,
der auf 60 MHz läuft und es mit PLLs gestattet, die drei benötigten
Hauptfrequenzen herzustellen. Um dem benötigten Standard zu genügen,
kommen als Daten für die Aussenwelt ganz ganau 64,000 kHz heraus. Die
Genauigkeit schwankt mit dem eingehenden Quarz, könnte z.B. auch bei
63,99 liegen, ist aber vollkommen akzeptabel.
Nun sollen die Daten mit einem Elektronik-Modul der anderen Abteilung
verarbeitet werden, das ebenfalls eine FPGA-Schaltung enthält, welches
ebenfalls aus einem 60MHz-Quarz gespeist wird. Dieses hat auch seine
Unsicherheiten, was aber auch wunderbar akzetabel und fein ist, weil das
Modul ausgangsseitig auch eine gewisse Toleranz hat. Durch Messungen
konnte ich "exakt" 60kHz ermitteln und habe mir gedacht, die Module
einfach zu synchen, indem ich sie auf einen Quarz hänge. Dann liessen
sich die Ausgänge mit jeweils 60kHz wunderbar mischen und verbeiten, bzw
umschalten.
Jetzt kommt's:
Ein Blick in das Innere des FPGA-Designs zeigt, dass dort andere
Zwischenfrequenzen zur seriellen Übertragung gebraucht werden und diese
komplett anders erzeugt werden, um mit einer PLL auszukommen, wobei
systematisch nicht 64kHz sondern 64,064064 kHz erzeugt werden.
Das ist stand alone locker in der Spec, verhindert aber, dass ich die
Module direkt auf Taktebene synchen kann. Wenn ich die an dieselbe
Frequenz hänge, laufen die ja mit fast 1 Promille auseinander. Damit es
klappt, müsste ich also einen Quarz dranhängen, der 59,959x irgendwas an
Frequenz hat. Abgesehen davon, dass ich keinen finde, muss ich das noch
synchen.
Ich kann aber keine PLL mit 64kHz aufziehen und vor dort wieder
"hochgehen". Ich sehe es auch als schwierig an, das Design komplett
umzubauen, dass das eine Modul asynchron arbeitet und mit FIFOs
arbeitet, weil es dann immer irgendwo zu einem Sprung kommt.
Wie bekomme ich es hin, dass ich den zweiten Quarz direkt analog ein
bischen nach unten ziehen kann?
Das Ganze sollte so wenig wie möglich jittern.
Was du da vor hast, klingt in meinen Ohren nach Murks..
In dem Moment, wo du zwei Quarze verwendest, bist du asynchron. Selbst
wenn die Quarze auf exakt der gleichen Frequenz oszillieren würden.
Sie tun das in der Realität nie. Denn spätestens bei
Temperaturschwankungen driften sie wieder auseinander und phasengleich
sind sie sowieso niemals.
Also: zwei getrennte Quarze sind wie zwei getrennte Taktdomänen zu
betrachten und somit asynchron. Daher sind die Methoden nötig, um mit
asynchronen Signalen umzugehen. Da wirst du vermutlich nicht
drumrumkommen.
Warum nicht statt des 60MHz-Oszillators eine PLL nehmen, die von den
Ausgangsfrequenzen beider Geräte gesteuert wird? Diese sollte es dann
doch hin bekommen, dass die Ausgangsfrequenzen möglichst gleich sind.
Der Retter der Nation schrieb:> Ein Blick in das Innere des FPGA-Designs zeigt, dass dort andere> Zwischenfrequenzen zur seriellen Übertragung gebraucht werden und diese> komplett anders erzeugt werden, um mit einer PLL auszukommen, wobei> systematisch nicht 64kHz sondern 64,064064 kHz erzeugt werden.
Ich würde mein Design so auslegen, dass es mit mindestens 1MHz oder noch
wesentlich schneller läuft, dann hätte ich Zeit für das nötige
Oversampling des externen Signals.
> sondern 64,064064 kHz erzeugt werden.
Ist das dann wirklich ein Takt oder ist das ein Clock-Enable für ein
wesentlich schneller getaktetes Design?
Denn das beste wäre, das Design so wie Bahnhofsuhren oder die
Zeilenablenkung eines Röhrenfernsehers auszulegen: der interne Prozess
ist so schnell, dass er immer vor dem nächsten externen Takt fertig ist.
Und dann wird vom externen Takt wieder ein interner Zyklus angetriggert.
Bleibt der externe Takt aus, läuft (wenn überhaupt nötig) ein interner
Zähler mit z.B. 63kHz an seinen Überlauf und triggert das Modul trotzdem
an.
Moin,
wenn es wirklich diese zwei Clocks sein müssen, du aber an "Deiner"
Domäne eher drehen kannst, würde ich die klassische Taktrückgewinnung
("Clock recovery") aus der Audio-Video-Welt implementieren. Bei der
geringen Frequenz brauchst Du da vermutlich nicht mal die riesen Logik
oder gar PLLs, wenn deine 64 khz auch bisschen jittern dürfen. Wie
Lothar bereits sagte: Nur bisschen schneller als die andern laufen
musste :-)
Klar, kann ich das manuell synchen, aber dann muss ich dummerweise die
FPGA-Firmware genau der Baugruppe anfassen, die ich nicht anfassen will,
weil sie von der anderen Abteilung kommt. Wir hätten dann eine eigene
Firmware nur für unsere APP und das ist nicht erwünscht. Ist halt
blöde, wenn man immer den Reparaturbetrieb für Baugruppen machen muss,
die von anderen "mit genialen Ideen" irgendwann in grauer Vorzeit mal
eben schnell hingefummelt wurden!
Wie oben angeraten, beide PLLs aus einer Domain zu speisen, geht ja
nicht, wegen der ungünstigen Teilerverhältnisse. Ich muss die 60 MHz der
ersten Baugruppe mit geringem Jitter in 64/64,064064 verwandeln, also
mit exakt 0,999000 multiplizieren. Optimal wäre, den Takt im ersten
(meinem) FPGA zu erzeugen und dann einfach auszugeben und auf die andere
Baugruppe zu geben. Die rennt dann langfristig genau so schnell und
nimmt die Daten mit dem richtigen Speed.
Beschreibe doch einfach mal, welche Schnittstellen davon betroffen sind.
Also welche Schnittstellen sind an dem unveränderbaren Design
vorgegeben( inkl. Datenrichtung).
Schlumpf schrieb:> Beschreibe doch einfach mal, welche Schnittstellen davon betroffen sind.> Also welche Schnittstellen sind an dem unveränderbaren Design> vorgegeben( inkl. Datenrichtung).
Eben! Da oben wird munter von 2 FPGAs mit 60MHz geredet, dann aber
wieder von 60kHz. Wenn das wirklich nur kHz sind, dann muss halt einer
der beiden Teilnehmer einen '60kHz timer-strobe' zum anderen schicken.
Dann entsteht zwar immer noch ~1 Promille Jitter, aber die beiden
Designs lassen sich voll (Langzeit-)synchronisieren.
Oder hab' ich das Problem komplett falsch verstanden?
Also, die Takte werden so erzeugt:
Ich:
60.000.000 x 8 = 480.000.000 / 3 = 160.000.000 = externer Sampletakt 1
480.000.000 / 10 = 48.000.000 = Systemtakt
von 48 MHz runter / 375 -> 128 kHz und daraus 64kHz Time Tick
sind 64.000,000 kHz
Die konkurrente Baugruppe mit anderem Baustein:
60.000.000 x 16 = 960.000.000 / 5 -> 192.000.000,0 primary clock 1
960.000.000 / 15 -> 64.000.000,0 primary clock 2
960.000.000 / 45 -> 21.333.333,3 secondary clock 1
Dann den 21.333.333 / 3 macht ein 111 step signal für das
Schieberegister, welches mit 64.064,064 kHz rausgeht. Der Taktzähler
zählt bis 332.
Die Zwischenfrequenz von 960MHz könnte ich in meinem Design noch
hinbekommen, aber die krumme Frequenz nicht. Das Problem ist, dass ein
anderer Schaltungsteil die 9 fache Frequenz braucht umd die Bits zu
erzeugen:
192.000 / 333 = 576.576,5 kHz / 9 = 64,064kHz.
Ich kann das mit meiner PLL nicht vereinen, ohne auch meine Takte
minimal zu ändern, andererseits aus der bestehenden Schaltung nicht die
111x64,00kHz erzeugen bzw nicht die 9 x 64kHz.
Wie wäre es, wenn du deine Teiler etwas anpasst?
auf deiner Seite teilst du einmal durch 375 und einmal durch 2. Wenn du
stattdessen einen Teiler von 749 (107 und 7) verwenden könntest, bist du
bei 0,03 Prozent Abweichung! (Ideal wäre ein Teiler von 749,25...)
Ist das eigentlich eine "starre" Serielle Übertragung (SPI oä)? Dann
müsste dir doch die "fremde" Baugruppe einen Bittakt vorgeben können,
mit dem du dein Senderegister rausschiebst??? Und wenn es ein UART ist,
müsste der aber auch mit bis zu 3% Drift leben können, weil auf jedem
Startbit neu synchronisiert wird.
_.-=: MFG :=-._
Also ich hätte gfs. eine Lösung für Dich, die auch nicht gewaltsam ist,
denn wir müssen hier zwei Fälle unterscheiden:
1) Den Quarz analog hinzuziehen
Für eine Regelschaltung hatte ich den Fall, dass eine
selbstoszillierende Anordnung (Elektronik) in der Frequenz so
beeinflusst werden musste, dass zu einem gegebene Zeitpunkt eine
bestimmte Phasenlage erreicht wurde und dies bei allen Schaltungen der
Baugruppe. Dies kann dadurch erfolgen, dass man den Schwingkreisen
permanent Energie zuführt oder entzieht, um sie zu regeln, wobei sie
gezielt verstimmt werden. Das ist im Prinzip so wie bei analogen
Sysnthesizern.
In dem Fall der Oszillatoren würde man von dem einen mit einem harten =
hochverstärkenden Ausgang über einen Widerstand auf den zweiten
Oszillator gehen, um ihn hinzuziehen. Das funktioniert in gewissen
Grenzen und führt auch zu stabilen Verhältnissen.
Wenn ich Dein Problem richtig erfasst habe, dürfte Dir das aber nichts
nutzen, weil Du offenbar eine andere Frequenz brauchst, daher die andere
Idee:
2) Die Frequenz digital zu modulieren
Du musst einen Taktausgang definieren und diesen per umschaltbarem Delay
immer weiter nach hinten schieben und ihn so zu verlangsamen, wie beim
Dopplereffekt. Wenn Du die Umschaltung mit einer festen Frequenz
vornimmst, ist der Zusammenhang fest definiert.
Wenn es wirklich so ist, dass Du genau 1/1000stel weniger brauchst,
nimmst Du Dir das programmierbare Delay der FPGA-IO Pins und verzögerst
das ausgehende Tatksignal in z.B. 10 Stufen um jeweils 1/10 der
Taktperiode und tust dies jeden 100sten Takt. Dann kommt hinten im
Mittel 1/1000 weniger raus. Den Takt verwendest du anstatt des zweiten
Oszillators.
Wenn du keine programmierbaren IOs hast, musst du es manuell machen und
über LUTs arbeiten wie ich das hier mal ausgeführt habe:
http://www.96khz.org/oldpages/frequencyshifter2.htm
Die Schaltung erzeugt jeweils einen Jitter in Form eines Phasensprungs
von bis zu 1/16 Takt (in Deinem Fall ein 1/10tel). Es kann sein, dass
das die PLL der Folgeschaltung nicht mitmacht. Unter Umständen musst du
damit die PLL rauswerfen und gleichzeitig die Constraints entsprechend
eng setzen, um mit dem Jitter klarzukommen oder eine Mischung aus beiden
Verfahren anwenden.
Gfs ist es auch möglich, die neu erzeugte Frequenz auf ein 60 MHz
Bandfilter zu geben und dieses schwingen zu lassen und einfach einen
Schmitt-Trigger dahinter zu hängen, damit sich die Phasensprünge etwas
glätten und Du doch wieder Deine FPGA-PLL nehmen kannst.
Die letzte Möglichkeit, die ich hätte, wäre eine DDS mit der geringeren
Frequenz zu nehmen und einen Sinus auszugeben, ihn dann richtig gut zu
filtern und wieder per Schmitt-Trigger auf den zweiten FPGA. Dabei wäre
es sicher zweckmässig, eine geringere Frequenz zu nehmen, z.B. von nur
15MHz und die interne PLL des FPGAs anzupassen. Die DDS-Sinusschwinung
ist einfacher zu filtern und dürfte auf jeden Fall gehen.
Ich habe mit einem solchen Verfahren schon Phasenmodulationen auf 20ps
genau hinbekommen. Das sollte für deine komischen 60kHz reichen :-)
Jürgen Schuhmacher schrieb:> Die Frequenz digital zu modulieren
Ich habe mir Deine Seite angesehen, muss aber sagen, dass ich es nicht
zu 100% verstehe. Wie garantiere ich, dass dort ganz genau 1 Promille
(und ich meine ganz exakt 1 Promille) weniger Frequenz rauskommt?
Die Verzögerungen im FPGA, die sich durch Delays und lookup-Tabellen
machen lassen, sind doch niemals so genau zu timen.
Die andere Idee mit der DDS und dem Filter ist mir schon einleuchtender.
Allerdings ist mir das dann doch etwas zu aufwändig.
Ich hatte in einem anderen Forenbereich einen Tipp mit einer PLL
bekommen. Die werde ich jetzt zunächst verfolgen!
Irgendwie meine ich, dass es möglich sein müsste, mit 2 PLLen im FPGA
alle benötigten Takte auszugeben. Die Verhältnisse sind doch jeweils
ganzzahlig und sollten sich auch parallel erzeugen lassen. Die 480 sind
doch genau die Hälfte von 960. Also alles mal 2.
Das Problem ist nicht die ersatzweise Erzeugung der Frequenzen, wie sie
momentan verwendet werden, sondern die Erzeugung der neuen verstimmten
Frequenzen, so wie ich sie brauche, damit hinten genau dieselben 64khz
rauskommen.
Die einzige Möglichkeit wäre, MEIN Design falsch laufen zulassen und
etwas höher zu gehen, als 60MHz. Aber dann müsste ich ja auch eine neue
Taktfrequenz erzeugen und zusätzlich noch einen synchronisierenden Takt
von hinten holen.
Ich brauche den hier:
Beitrag "Frequenzumsetzer 1000 : 999"