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.
:
Gesperrt durch Moderator
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"
Der Retter der Nation schrieb: > Ich brauche den hier: > Beitrag "Frequenzumsetzer 1000 : 999" Ich schlage vor, wir führen die Diskussion in einem dieser beiden Threads fort. In diesem Sinne mache ich den hier dicht.