Forum: FPGA, VHDL & Co. Wie Datenbus in fremder Domain verarbeiten


von Fredy (Gast)


Lesenswert?

Ich bekomme streaming daten mit einer 50MHz Clock rein (Je ein Datum pro 
Clock) und habe nebst den Daten selbst nur die Clock. Diese Daten müssen 
auf einen 80MHz DSP übertragen werden. Wie mache ich das ?

Bei einem Datenbus kriege ich das hin, da das OE nach den Adressen und 
den DAten kommt und man mindestens einen Clock Zeit hat.

Wenn ich aber hier einfach den Bus absample, kriege ich in seltenen 
(aber unweigerlich auftretenden) Fällen einen Aussetzer, da die Daten 
gerade nicht stabil sind. Die clock abzusampeln bringt mir auch nichts, 
da ich nicht jede Flanke erwische.

Wie mache ich das, Besten ?

von Falk B. (falk)


Lesenswert?

@ Fredy (Gast)

>Ich bekomme streaming daten mit einer 50MHz Clock rein (Je ein Datum pro
>Clock) und habe nebst den Daten selbst nur die Clock. Diese Daten müssen
>auf einen 80MHz DSP übertragen werden. Wie mache ich das ?

<OT>
Du hast DEN Takt!
</OT>

Das Zauberwort heisst asynchroner FIFO.

MfG
Falk

von Kest (Gast)


Lesenswert?

Die einfachste Lösung -- Fifo:


Pseudocode:

Fifo:(
  wrckl => 50 Mhz
  wrreq => '1'
  wrdata => Datenbus,

  rdclk => 80 MHz
  rdreq => if not empty
  rddata => Datenbus_80Mhz
)

Grüße
Kest

von Fredy (Gast)


Lesenswert?

FIFO ist nicht, ich brauche jedes Datum einmal und richtig. Bzw kann ich 
mir keine Latenz erlauben. Als FIFO kämen also nur 2 oder 3 Register in 
Betracht. Angedacht habe ich das schon, nur wie mache ich das mit den 
Zählern? Der eine wird ja vom Schreibtakt getrieben, der andere mit dem 
Lesetakt der neuen Domain. Was passiert beim Vergleich der Counter ?
Die beiden Counter kommen aus verschiedenen domain. Wenn ich den 
Schreibcounter in der Zieldomain abfrage, kann er instabil sein.

Ging es nicht mit einem Wechselbuffer und einem Mechanismus, der 
automtisch den selektiert, der gerade nicht beschrieben wird?

Ich meine mich zu errinnern, daß es auf der Xilinx-Seite mal so eine 
Handvoll Tutorials gab, die solche Sonderprobleme behandlete. Es waren 6 
Stpck, meine ich. Dort gabe es so einen Konstrukt zum Handling von 2 
domain-Takten - ich habe mich eben erfolglos totgesucht.

Jemand ne Idee ?

von Roger S. (edge)


Lesenswert?

Fredy wrote:
> FIFO ist nicht, ich brauche jedes Datum einmal und richtig.

mit was fuer komischen FIFOs hast du denn bis jetzt gearbeitet?

> Angedacht habe ich das schon, nur wie mache ich das mit den
> Zählern?

Du instanzierst ein FIFO vom FPGA Hersteller, denn darin ist die 
Problematik die du beschreibst schon sauber geloest. Dein Interface 
sieht etwa so aus wie von Kest beschrieben.

> Ging es nicht mit einem Wechselbuffer und einem Mechanismus, der
> automtisch den selektiert, der gerade nicht beschrieben wird?

Im Prinzip ja.

Cheers, Roger

von Kest (Gast)


Lesenswert?

Mach doch ein FIFO, welches aus 2-3 Registern besteht. Es muss ja nicht 
gleich riesengroßes sein.

Es gibt auch asynchrone FIFOs als VHDL-Beschreibung. Habe mal verwendet, 
aber nicht ausgiebig getestet. Also am besten einfach Coregenerator von 
Xilinx oder MegaWizzard von Altera anschmeißen. Viel Erfolg!

Grüße,

Kest

von chipschmied (Gast)


Lesenswert?

Zwei-drei register? du versuchst doch nicht etwa einen bus synchronizer 
zu bauen?! (also zwei register an unterschiedlichen takten miteinander 
zu verbinden) Das verfälscht mit Sicherheit das Datum, da müsstest du 
eine checksumme zur fehlerkorrektur mitführen undbist immer noch dem 
gesetz der Wahrscheinlichkeit ausgeliefert.

Ein kleiner Speicher aus den LUT-speicherzellen (distributetd RAM bei 
Xilinx)
als dual-port speicherfeld ist effizienter (1 slice hat 1 FF und 16 
Speicherzellen). eventuell müsstest du den Datenstrom in Pakete zerlegen 
(per Software).

Wie gesagt Grundprinzip ist ein RAM mit zwei Datenports (dual Port), 
eine Fifo ist ein sonderfall davon. Den datenport auf 50 MHz klemmst du 
fest auf write = '1', den anderen fest auf read = '1'. an die beiden 
adressen kommt jeweils ein counter. der an 50 MHz (writepointer) zählt 
bei jedem Takt, der an 80 MHz (readpointer) nur wenn die Differenz 
zwischen beiden countern groß genug ist. Vorsicht für die 
Differenzbildung mußt du über Taktgrenzen, nimm nur das oberer bit, dann 
klappt es mit einem synchronizer. Das wäre dann (wie) ein Wechselbuffer. 
das OE setzt du nur wenn der readpointer inkrementiert, sonst hast du 
doppelte worte auf dem Bus. ein bißchen Zeitversatz (meinst du das mit 
Latenz?) hast du immer.

vielleicht machen sich one hot counter für den Vergleich besser?
Aber wie ein Vorredner erwähnte, da hat coregen bestimmt schon ein 
geprüftes Modul dafür?

von Falk B. (falk)


Lesenswert?

@ Fredy (Gast)

>FIFO ist nicht, ich brauche jedes Datum einmal und richtig. Bzw kann ich

???
Ein FIFo macht das.

>mir keine Latenz erlauben. Als FIFO kämen also nur 2 oder 3 Register in

Vollkommen ohne Latenz geht es sowieso nicht, da die beiden Takte 
asycnhron zueinander sind.

>Betracht. Angedacht habe ich das schon, nur wie mache ich das mit den
>Zählern? Der eine wird ja vom Schreibtakt getrieben, der andere mit dem
>Lesetakt der neuen Domain. Was passiert beim Vergleich der Counter ?
>Die beiden Counter kommen aus verschiedenen domain. Wenn ich den
>Schreibcounter in der Zieldomain abfrage, kann er instabil sein.

Um genau dieses Problem zu lösen gibt es ASYNCHRONE FIFOs. Fix und 
Fertig gestestet von jedem FPGA HErsteller als 
Macro/Core/MegaWizard/Whatever.

>Ging es nicht mit einem Wechselbuffer und einem Mechanismus, der
>automtisch den selektiert, der gerade nicht beschrieben wird?

Im Prinzip schon, doch da muss man aufpassen, dass man sich nicht ins 
Knie schiesst. Solche Sachen sind anfällig für sporadische Fehler. Da 
fehlt dann hin und wieder ein Datum alle paar zehntausend Takte. Man 
muss hier WIRKLICH wissen was man tut!

>Stpck, meine ich. Dort gabe es so einen Konstrukt zum Handling von 2
>domain-Takten - ich habe mich eben erfolglos totgesucht.

http://www.xilinx.com/xlnx/xweb/xil_tx_display.jsp?category=&iLanguageID=1&multPartNum=1&sTechX_ID=pa_clock_bound

MfG
Falk

von Fredy (Gast)


Lesenswert?

Vielleicht hätte ich schreiben sollen "fertiges FIFO" ist nicht. Die 
FIFOs der Wizzards kenne und nutzeichja , aber ichhabe das Probem, daß 
ich aus diversen Gründen die pointer-Vrrwaltung selber machen muss. Es 
darf z.B. keinen overrun oder underrun geben, daher muss - weit VOR 
Erreichen von buffer full, bzw buffer empty, die datenrate des 
Schreibprozesses manipuliert werden. Der Schreibprozess kann NICHT 
warten und der Leseprozess ist ebenfalls immer lesewillig.

Mir würde es reichen, wenn ich ein buffer 25% and 75% hätte. Ich werde 
jetzt mal probieren, 3 Buffer zu nehmen und zu verketten. Damit wären 
die beiden Steuersignale des mittleren buffers in etwa das, was ich 
brauche. Allerdings habe ich dann nur jeweils einen Takt / ein Datum 
Reserve zum Nachbarpuffer und das wird knapp.

Ich brauche eine saubere Architektur, die mir jedes Datum einzeln per 
Handshake auf die andere Seite gibt. Da es vom langsamen in den 
schnellen Takt geht, müsste es eigentlich gehen.

von Roger S. (edge)


Lesenswert?

Fredy wrote:
> Es darf z.B. keinen overrun oder underrun geben, daher muss - weit VOR
> Erreichen von buffer full, bzw buffer empty, die datenrate des
> Schreibprozesses manipuliert werden. Der Schreibprozess kann NICHT
> warten und der Leseprozess ist ebenfalls immer lesewillig.

da widersprichst du dir aber. Wenn dein Leseprozess immer lesewillig 
ist, dann kann es keinen overrun geben.

> Ich brauche eine saubere Architektur, die mir jedes Datum einzeln per
> Handshake auf die andere Seite gibt. Da es vom langsamen in den
> schnellen Takt geht, müsste es eigentlich gehen.

Es einen anderen aktuellen thread mit aehnlichem Problem

Beitrag "Warnmeldung unter Xilinx"

Cheers, Roger

von Falk B. (falk)


Lesenswert?

@ Fredy (Gast)

>ich aus diversen Gründen die pointer-Vrrwaltung selber machen muss. Es

Glaub ich nicht. Nimm einen asynchronen FIFO, um die Daten über die 
Taktgrenzen hinweg zu bewegen. Dann kannst du auf der 80 MHz 
Empfängerseite alles mögliche machen, und zwar alles mit dem 80 MHz 
Takt. Schön synchron.

>darf z.B. keinen overrun oder underrun geben, daher muss - weit VOR

Geht alles spielend mit einem asynchronen FIFO.

>Erreichen von buffer full, bzw buffer empty, die datenrate des
>Schreibprozesses manipuliert werden. Der Schreibprozess kann NICHT
>warten und der Leseprozess ist ebenfalls immer lesewillig.

Auch alles kein Thema. Ist bissel Steuerlogik um den FIFO rum. Glaub 
mir, einen asynchronen FIFO willst du nicht selber machen.

>Ich brauche eine saubere Architektur, die mir jedes Datum einzeln per
>Handshake auf die andere Seite gibt. Da es vom langsamen in den

Eben, einen asynchronen FIFO.

>schnellen Takt geht, müsste es eigentlich gehen.

Der "schnelle" Takt ist nichtmal doppelt so schnell. Also alles nicht 
wirklich viel Luft.

MfG
Falk

von Fredy (Gast)


Lesenswert?

"Glaub ich nicht."

Gute Antwort, wenn man die Aufgabe nicht kennt. Wenn es so einfach wäre, 
einfach einen FIFO reinzuschmeissen, bräuchte ich ja GAR NICHTS 
programmieren und wäre fertig.

Wir sind leider keinen Schritt weiter: Es bliebe immer noch das Problem 
der Pointer-Behandlung und den eintakten geht nicht, da es kein 
Bezugsmass gibt. Ich mache es nun so, daß ich den auf Plausibilität 
prüfe und so eine zeitlich ungefähre Aussage habe. Reserven dafür habe 
ich.

Offen ist nach wie vor die Quelle der angesprochenen Xilinx-Seiten. Ich 
habe auch heute wieder mal gesucht und bin nicht fündig geworden.

von Falk B. (falk)


Lesenswert?

@ Fredy (Gast)

>Wir sind leider keinen Schritt weiter: Es bliebe immer noch das Problem
>der Pointer-Behandlung und den eintakten geht nicht, da es kein
>Bezugsmass gibt. Ich mache es nun so, daß ich den auf Plausibilität
>prüfe und so eine zeitlich ungefähre Aussage habe. Reserven dafür habe
>ich.

Totaler Murks! Du erfindest das Rad neu, aber leider kommt nur ein 
Fünfeck raus.

Mir scheint eher, dass du etwas starrsinnig bist und auf eine abstruse 
Lösung schon fixiert bist. Na dann mach mal. Viel Erfolg.

>Offen ist nach wie vor die Quelle der angesprochenen Xilinx-Seiten. Ich
>habe auch heute wieder mal gesucht und bin nicht fündig geworden.

Meinen Link gelesen? War das der falsche?

MFG
Falk

von J. S. (engineer) Benutzerseite


Lesenswert?

@Fredy : Hört sich nach einem Problem an, das ich auch gerade habe

>Erreichen von buffer full, bzw buffer empty, die datenrate des
>Schreibprozesses manipuliert werden. Der Schreibprozess kann NICHT
>warten und der Leseprozess ist ebenfalls immer lesewillig.

Der Schreibprozess MUSS aber warten, wenn Dein Buffer im Begriff ist, zu 
voll zu werden (wo auch immer da die Grenze sein mag. Wenn ich das 
richtig verstanden habe, willst Du die Datenrate träge nachregeln ?

Im Prinzip gibt es nur zwei Möglichkeiten: Die Takte stehen in einer 
festen Beziehung. Dann kannst Du die Zeiger wie jedes andere vom Takt 
gegenüber abhängige Signal normal eintakten wie Du willst: Du wirst 
immer stabile Werte haben.

Wenn die Takte weglaufen, musst Du die Stabilität an dem letzten sich 
änderenden Signal einer Signalgruppe festmachen, also eintakten und 
vergleichen. Dann hast Du doch Deinen stabilen Bus / Zeiger, Datenstrom, 
oder was auch immer. Kostet maximal 2-3 Takte Latenz.

von Falk B. (falk)


Lesenswert?

@ Jürgen ... (engineer)

>Der Schreibprozess MUSS aber warten, wenn Dein Buffer im Begriff ist, zu

Ja, aber das die Quelle nur 50 MHz hat, die Senke aber mit 80 MHz läuft 
sollte das kein Thema sein. E sei denn, die Bearbeitung/Abtransport auf 
dem 80 MHz Takt sind zu langsam (block weise gesehen).

MFG
Falk

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.