Forum: FPGA, VHDL & Co. Signal von einer Taktebene auf eine andere übergeben


von Günter (. (dl4mea)


Lesenswert?

Servus miteinander (um das übliche 'Hallo' mal zu vermeiden)

Ich habe eine sicherlich dumme, aber auch berechtigte Frage zur Übergabe 
eines Signals (hier: 48 bit breiter vector) von einer Taktebene auf die 
andere. Lothar hats letztes so schön gesagt: "Im ersten Jahr VHDL gibt 
es nur einen Takt und nur Signale, keine Variablen".

Also, ich habe einen 48 bit breiten Zähler, der mit 100MHz getaktet 
wird, und nichts anderes als einen Timestamp mit 10ns Auflösung erzeugt.
Damit sollen Werte, die auf der anderen Taktebene mit 64MHz in ein FIFO 
geschrieben werden, markiert werden. Sprich, der Zähler geht parallel 
zum Datum ins FIFO hinein.
Beide Takte erzeuge ich mit der PLL des Cyclone II.

Frage:
1) Kann ich den Zähler direkt ans FIFO anschließen? Ich glaube nicht...
2) Wenn nein, welchen Zwischenspeicher brauche ich? Reicht da ein 
1-stufiges Register, oder brauche ich zwei?
3) Mit welchem Takt schreibe ich in den Zwischenspeicher? Mit dem 100MHz 
oder mit dem 64MHz? Oder, im Fall eines zweistufigen Registers, mit 
welchem Takt ins erste, mit welchem Takt ins zweite.

Danke für euere Hilfe!

ciao, Günter (dl4mea)

von Berater (Gast)


Lesenswert?

> die auf der anderen Taktebene mit 64MHz in ein FIFO
> geschrieben werden, markiert werden. Sprich, der Zähler
> geht parallel zum Datum ins FIFO hinein.

Das geht schon mal nicht, weil die beiden Domänen ja keinen festen Bezug 
haben. Es ginge nur, wenn man ein 25/16 Schema entwirft und dem 64 Takte 
berechnete Bruchteile der 25ns verabreicht, nämlich:

1 x 25/16
2 x 25/16
...
16x 25/16

tust du das nicht, dann treten die nicht/schlecht interpretierbaren 
Zeitsprünge zwischen Domänen schon beim "Markieren" auf.

Grundsätzlich muss Du den 10ns Zähler einfach mit den 64MHz einlesen, 
doppelt einsynchronisieren, wegen der Instabilität und der (wenn auch 
thereotischen) Metastabilität und den so gewonnen Wert als Zeitstempel 
speichern.

Die Konstellation 100/64 macht hier aber irgendwie keinen Sinn.

Bist du sicher, dass Du das meinst, was Du geschrieben hasT?

von Berater (Gast)


Angehängte Dateien:

Lesenswert?

und so sieht dann der Zähler@64MHz aus.

von Klaus F. (kfalser)


Lesenswert?

Am besten arbeitest Du mit 2 Fifos, eines für den 100 MHz Bereich, der 
den Zähler übernimmt, und eines für den 64 MHz Bereich, der die Werte 
übernimmt.
Wenn ein Capture-Event auftritt, wird EIN Fifo-Write Signal für das 100 
MHz Domain erzeugt, das dort einsynchronisiert wird und genau eine 
Schreiboperation auf das Fifo dort auslöst. Dieses Einsynchronisieren 
erzeugt dann zwar eine definierte Verzögerung zwischen Event und 
Schreiben, aber das kann man herausrechnen.

Das Auslesen der Fifos erfolgt dann im gleichen Taktdomain.

von Klaus F. (kfalser)


Lesenswert?

Berater schrieb:
> Grundsätzlich muss Du den 10ns Zähler einfach mit den 64MHz einlesen,
> doppelt einsynchronisieren, wegen der Instabilität und der (wenn auch
> thereotischen) Metastabilität und den so gewonnen Wert als Zeitstempel
> speichern.

Nein, einen Zählwert kann man nicht so direkt auf ein anderes 
Takt-Domain einsynchronisieren, da nützt auch die doppelte 
Synchronisation nichts.
Wenn beide Takte zufällig zusammenfallen kann es beim Einsynchronisieren 
nämlich passieren, dass 1 Bit aus dem Zählerstand vor dem 100 MHz 
Taktpuls und ein anderes Bit aus dem Zählerstand nach dem 100 MHz 
Taktpuls in das 64 Mhz domain übernommen wird. Das ergibt dann ein 
falsches Ergebnis.

Man kann immer nur einzelne Signale einsynchronisieren.
Was man machen kann ist ein Freeze-Signal aus dem 64 MHz Domain in das 
100 MHz Domain einzusynchronisiern, dieses kopiert den aktuellen 
Zählerstand in ein Zwischenregister, und dieses kann dann im 64 MHz 
Domain in aller Ruhe ausgelesen werden, weil es sich ja nicht ändert.

von T. M. (xgcfx)


Lesenswert?

Zählerwerte über asynchrone Taktdomains übergibt man am besten als 
Graycode, um die von Klaus Falser beschriebenen Probleme zu umgehen. 
Einsynchronisiert werden müssen sie natürlich trotzdem noch.

Siehe zB:
http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO2.pdf

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Günter (dl4mea) schrieb:
> Also, ich habe einen 48 bit breiten Zähler, der mit 100MHz getaktet
> wird, und nichts anderes als einen Timestamp mit 10ns Auflösung erzeugt.
> Damit sollen Werte, die auf der anderen Taktebene mit 64MHz in ein FIFO
> geschrieben werden, markiert werden. Sprich, der Zähler geht parallel
> zum Datum ins FIFO hinein.
Zu welchem Datum?
Womit wird der Zähler getaktet?
Wie wird das Datum übernommen?
Kannst du nicht "einfach" auf der 100MHz-Seite das Datum zusammen mit 
dem Zeitstempel in 1 breites statisches Wort packen und das mit einem 
Handshakesignal (oder einem DPRAM) über die Taktdomäne hinwegreichen?

Oder warum nimmst du nicht einfach einen Taktmanager und erzeugst 128MHz 
aus den 64 und übergibst den Zeitstempel mit 8ns Auflösung? Müssen das 
unbedingt 10ns sein?

von Berater (Gast)


Lesenswert?

Klaus, Du hast im Prinzip schon Recht, aber man braucht natürlich noch 
das Stabilitätskriterium für den Bus. Also entweder doppelt parallel 
speichern und zweimal fragen, wie man es täte, wenn man auf die linke 
Domain keinen Entwicklungseinfluss hätte - gfs überabtasten, ein Strobe 
verwenden oder man generiert mit 64er Takt nur einen Wert, der dann 
genügend lange stabil ist.

Ich hinterfrage aber nochmals den Sinn, einen Zeitstempel auf der 
falschen Seite zu generieren und dazu noch mit einer Domain, die gegen 
die Datendomain springt. Sinn macht es doch nur, die Domainen auf 
Datenebene synchron zu halten und nur auf Systemtaktebene die Sprünge zu 
veranstalten, sonst ja der Stempel keinen Wert. Sein Konzept ist schon 
faul.

Wenn es aber dennoch so sein muss, rate ich weiter zu meiner Methode, 
die Zählerstände nach dem 25/16 Schema zu berechnen und rüberzutakten. 
Das ist das Genaueste.

Deine FIFO-Lösung hat den Nachteil einer vergrößerten dynamischen 
Latenz. Je nachdem, wie die Taktflanken liegen, kann vom Übergang von 
einem auf einen anderen 64er Takt ein Sprung mal früher (also VOR dem 
25/16 Masstab) als auch danach ausgelöst werden. Daher springt der 
Zähler im Extremfall mit +/10ns + den eigenlichen Versatz, der bei 
+/-100/64 ns liegt.

von Günter (. (dl4mea)


Lesenswert?

Berater schrieb:
> Ich hinterfrage aber nochmals den Sinn, einen Zeitstempel auf der
> falschen Seite zu generieren und dazu noch mit einer Domain, die gegen
> die Datendomain springt. Sinn macht es doch nur, die Domainen auf
> Datenebene synchron zu halten und nur auf Systemtaktebene die Sprünge zu
> veranstalten, sonst ja der Stempel keinen Wert. Sein Konzept ist schon
> faul.
>
> Wenn es aber dennoch so sein muss, rate ich weiter zu meiner Methode,
> die Zählerstände nach dem 25/16 Schema zu berechnen und rüberzutakten.
> Das ist das Genaueste.

Danke für euere Mithilfe. Ich war ein paar Tage out-of-sync und konnte 
mich nicht beteiligen.

10ns ist in der Tat nur Bequemlichkeit wegen der Lesbarkeit. 128MHz wäre 
also machbar. Die Lösung mit dem 25/16 gefällt mir. Mit dem Graycode 
ists auch schlau. Es geht aber auch drum mal alles richtig zu machen 
wenns 10ns wären.

Eine Vorbedingung sollte sein, daß die Abfrage auf 64MHz jederzeit 
möglich ist und keiner Vorarbeit bedarf bzw. Zeitverzögerung bedarf. Der 
Zeitstempel wird parallel ins FIFO geschrieben, der Writestrobe ist nur 
einen 64MHz-Takt lang. Absolutwerte sind nicht nötig, der Zähler wird 
nur als Delta-Zeit verwendet. Ich versuchs mal so zu beschreiben damit 
es "low level" bleibt.

In meiner Vorstellung ist das Problem dort zuhause (weiter oben ja auch 
versuchts jemand zu visualisieren) daß der Takt, mit dem der 
100MHz-Zähler läuft, genau dann den Zähler erhöhen wird, wenn die 
64MHz-Ebene den Zähler abfragt und die einzelnen Bits nicht gleichzeitig 
kippen. Bei einem asynchronen Zähler kippen die niedrigeren Bits zuerst, 
die höchsten zuletzt. Bei einem synchronen Zähler bleiben noch immer 
interne Laufzeitunterschiede. Also würde ich manche Bits vor dem 
Erhöhen, manche danach lesen.

Wenn ich jetzt am Ende jedes Zählvorgangs den Zählwert im 100MHz process 
in ein Register schreibe und dieses auf der 64MHz-Ebene abfrage, dann 
habe ich zwar den Zähler-Inkrementvorgang abgefangen, aber nach wie vor 
nicht den Event, daß das Register im 100MHz-Raster genau dann 
beschrieben wird wenn ich auf 64MHz-Ebene selbiges lese. Die 
Wahrscheinlichkeit wird zwar kleiner, ist aber dennoch da. 
Laufzeitunterschiede und so...

Ich versuch jetzt die ganze Zeit nachzudenken wie ich ein 2stufiges FIFO 
takten müsste, damit ich den Zählerwert sicher auf der 64-MHz-Seite 
lesen kann, aber igendwie komm ich nicht drauf. Da ist ein Knoten in der 
Windung...

Drum also hier nochmal die Bitte mir einen Schubs in die richtige 
Richtung zu geben.

Ciao, Günter

von SuperWilly (Gast)


Lesenswert?

>der Writestrobe ist nur einen 64MHz-Takt lang.

Wie groß ist der Abstand zwischen zwei Strobes ?

Gruß, SuperWilly

von Günter (. (dl4mea)


Lesenswert?

Hallo,

der kürzeste Abstand zwischen zwei WriteStrobes ins Fifo ist 100µs.

ciao, Günter

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Günter (dl4mea) schrieb:
> Da ist ein Knoten in der Windung...
Ich kapier die Aufgabe (noch) nicht so richtig. Kannst du mal eine 
Skizze zeichnen, wo welches Signal mit welcher Frequenz wie lange 
auftritt, und was damit passieren soll...

> ich habe einen 48 bit breiten Zähler, der mit 100MHz getaktet
> wird, und nichts anderes als einen Timestamp mit 10ns Auflösung
> erzeugt.
Woher kommen denn die 100MHz? Ist der Zähler ein externer Baustein?

von Günter (. (dl4mea)


Angehängte Dateien:

Lesenswert?

Hallo,

hier eine Zeichnung meines Aufbaus.

Der WriteStrobe ist 1 clock auf der 64MHz-Ebene lang. Und erst jetzt 
fällt mir noch ein weiteres Problem auf: Da der Counter auf 100MHz 
schneller zählt als die 64MHz-Ebene ist, kann natürlich auch die 
Setup-Zeit am Eingang des FIFO krass verletzt werden.

Eine Lösung ist also zwingend nötig.

Danke schon mal jetzt, Günter

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

Günter (dl4mea) schrieb:
> Danke für euere Mithilfe. Ich war ein paar Tage out-of-sync und konnte
> mich nicht beteiligen.
>
> 10ns ist in der Tat nur Bequemlichkeit wegen der Lesbarkeit. 128MHz wäre
> also machbar. Die Lösung mit dem 25/16 gefällt mir. Mit dem Graycode
> ists auch schlau. Es geht aber auch drum mal alles richtig zu machen
> wenns 10ns wären.

Hallo Günther,

hast du dir mal die Signallaufzeiten in deinem Zähler überlegt? Bei 48 
Bit und 128 MHz bleiben pro Bit 7,8125 ns / 48 = 162 ps für die 
Berechnung und die Laufzeit des Übertrags je Stelle. Ich bezweifle, dass 
dies dein Cyclone schafft. Bevor du dir eine Struktur überlegst, lass 
dir mal ein Design mit dem Zähler bauen. Dabei darfst du das 
Einschreiben des Zählerstands in ein Register nicht weglassen. Denn die 
Laufzeit der Signale zur Datensenke beeinflusst das Timing auch.

Tom

von Günter (. (dl4mea)


Lesenswert?

Hallo Tom,

auf 128MHz laufen lassen ist eher die 3. Lösungsmöglichkeit. Favorit 
nach 100MHz ist die Statemachine mit 16:25, die weiter oben schon 
vorgeschlagen wurde. Aber du hast Recht, das könnte sehr knapp werden. 
Das derzeitige Design drumrum meldet fmax=126MHz und liegt knapp 
drunter.

Ciao, Günter

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Günter (dl4mea) schrieb:
> Das derzeitige Design drumrum meldet fmax=126MHz
Was ist der kritische Pfad?
Die statische Timinganalyse hilft dir da weiter.
> Das derzeitige Design drumrum meldet fmax=126MHz
Besser, du drehst den Spieß um und sagst mit Timing-Constraints, was du 
da erreichen willst.

von Günter (. (dl4mea)


Lesenswert?

Hallo Lothar,

den Weg mit einem Zähler auf 128MHz will ich eigentlich als allerletzte 
Möglichkeit verfolgen. Mir wäre lieber ich würde den mit 100MHz 
laufenden Zähler sicher auf der 64MHz-Taktebene verarbeiten können. Ich 
hab 1000 Ideen aber immer wieder reißt der Gedankenfaden irgendwo ab.

Ciao, Günter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.