Forum: FPGA, VHDL & Co. Counter und Clock Domain Crossing


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von FPGA Einsteiger (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Hallo!

Ich benutze schon seit geraumer Zeit folgendes Setup als Counter, und 
frage mich aber seitdem ich einiges über Metastabilität und Clock Domain 
Crossing gelesen habe, ob das überhaupt so in Ordnung ist:

Xilinx Spartan 3 FPGA, getaktet mit externem 50MHz Quarz.
250MHz Takt, generiert mittels DCM (unter Nutzung des XILINX ISE Webpack 
DCM Tools).
1kHz clock-enable, erzeugt in der 50MHz Clock Domain.

Asynchrone Impulse von aussen werden mittels "double-flop" in der 250MHz 
Domain einsynchronisiert. Ein dritter Flip-Flop dient zur 
Flankenerkennung, a'la
1
process(i_clk_250) begin
2
  if(rising_edge(i_clk_250)) then
3
    if(i_signal_ff3 = '0' and i_signal_ff2 = '1') then
4
        r_counter <= r_counter + 1;
5
    end if;
6
  end if;
7
end process;

Mein erster und bisher auch finaler Ansatz war, diesen Counter einfach 
in der 50MHz Domain zu samplen, und zwar mit jedem 1kHz clock-enable:
1
process (i_clk50) begin
2
  if (rising_edge(i_clk50)) then
3
    if(i_en_1khzclk = '1') then
4
      r_to_fifo <= i_counter;  
5
    end if;
6
  end if;
7
end process;

Mit Countern bis etwa 10bit Breite scheint dies in der Simulation und 
auch auf der Hardware ohne Artifakte zu funktionieren. Erst bei noch 
breiteren Countern werden Timing Constraints erstmals nicht mehr 
eingehalten (soweit ich denn hoffentlich die Constraints Files richtig 
erstellt habe).

Ist das plausibel? Und falls ja, spricht irgendetwas dagegen, den 
Counter aus der 250MHz Domain (erhalten mittels DCM aus der 50MHz 
Domain) in der 50MHz Domain zu samplen? Sollte das der Fall sein, was 
wäre die bessere Alternative - eine Kopie des Counter Werts mit 50MHz 
Enable in der 250MHz Domain "erzeugen" und diese Kopie samplen?

Vielen Dank für jeden Hinweis oder Tipp diesbezüglich!

von 12345678981653184683154 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
FPGA Einsteiger schrieb im Beitrag #5291430:
> 1kHz clock-enable,
das ist kein clock enable

>erzeugt in der 50MHz Clock Domain.
das ist das timing problem

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
FPGA Einsteiger schrieb im Beitrag #5291430:
> Erst bei noch breiteren Countern werden Timing Constraints erstmals
> nicht mehr eingehalten
Klar, weil die Carry-Chain länger wird und mit 250 MHz durchlaufen 
werden muss.

> Und falls ja, spricht irgendetwas dagegen, den Counter aus der 250MHz
> Domain (erhalten mittels DCM aus der 50MHz Domain) in der 50MHz Domain
> zu samplen?
Es wird nichts bringen, auch dann muss das Design 250MHz "können".
Überleg einfach mal ein paar Fälle durch. Du kommst selber drauf, dass 
im "schlimmsten" Fall (und das ist der, den das Design immer sicher 
können muss) eben nur 4ns Zeit bleiben.

Was soll der Zinnober mit dem 250MHz Takt überhaupt bewirken?

von Robert M. (rmueller)


Bewertung
0 lesenswert
nicht lesenswert
Ich bin mir nicht sicher, worauf genau du hinausmöchtest, und ob ich 
diese knappe Antwort richtig verstanden habe. Der clock-enable Prozess 
sieht aus wie folgt (ich dachte, das sei nun nicht besonders 
erwähnenswert):
1
process(i_clk50) begin
2
if (rising_edge(i_clk50)) then
3
if(i_rst_sync = '1') then
4
  r_en_1khzclk <= '0';
5
  r_cnt_1khzclk <= 0;
6
else
7
  if r_cnt_1khzclk = 49999 then
8
    r_en_1khzclk <= '1';
9
    r_cnt_1khzclk <= 0;
10
  else
11
    r_en_1khzclk <= '0';
12
    r_cnt_1khzclk <= r_cnt_1khzclk + 1;
13
  end if; 
14
end if;
15
end if;
16
end process;

Ist deine Empfehlung, nur in der 250MHz Domain "zu arbeiten", und dort 
quasi auch schon ein 50MHz clock-enable zu erzeugen?


@Lothar:
Die Impulslänge kann deutlich weniger als 20ns betragen. Ich denke, 
deshalb brauche ich einen Takt, der schneller als 50MHz ist (oder andere 
Tricks).

Vielleicht sollte ich statt eines 16bit Zählers und zu langer Carry 
Chain dann besser zwei 8bit Zähler verwenden - oder beißt sich die Katze 
damit schon wieder in den Schwanz?

Viele Grüsse!

: Bearbeitet durch User
von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
Meiner Ansicht nach ist CDC zwischen Clocks, die ganzzahlige Vielfache 
einer anderen Clock sind, die ohne Phasenverschiebung aus derselben PLL 
stammt, keine echte CDC.

Da kann man sich in den meisten Fällen den Taktdomänenübergang deutlich 
vereinfachen. Eigentlich muss man nur aufpassen, dass man das den 
Timing-Analyzer Tools richtig verklickert und an der richtigen Stelle 
samplet.

von VHDL hotline (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Brauchst du in der 250MHz Domäne den absoluten Zählerwert? Ansonsten 
zähle dort nur über jeweils 5 Takte (also bis maximal 5 mittels eines 3 
Bit Zählers), halte das Ergebnis in der 250er Domäne für 5 Takte und 
addiere es in jedem 50MHz Takt zu einem absoluten Zählerwert. Sample 
dann mit deinem 1kHz enable den Zähler aus der 50er Domäne. Wenn deine 
Takte wie schon gesagt phasenstarre Vielfache sind, dann klappt das und 
du hast auch kein Problem mit CDC.

Falls du in der 250er den absoluten Zählerwert brauchst, gehen auch zwei 
8-Bit Zähler statt eines 16-Bit Zählers, du musst nur eine Registerstufe 
zwischen beide setzen.

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Robert M. schrieb:
> Ist deine Empfehlung, nur in der 250MHz Domain "zu arbeiten", und dort
> quasi auch schon ein 50MHz clock-enable zu erzeugen?
Kannst du, dann musst du aber heftig mit MultiClockCycle Constraints 
arbeiten. Denn sonst klemmt dir (wie du schon erfahren musstest) die 
Toolchain jeden Zähler mit mehr als 10 Bit ins Auge...

> Die Impulslänge kann deutlich weniger als 20ns betragen.
Und du willst "einfach" nur auch solche kurzen Impulse erfassen?
Dann sieh dir das mal an: 
http://www.lothar-miller.de/s9y/archives/19-Kurzer-Spike-in-Puls-umgewandelt.html

von Robert M. (rmueller)


Bewertung
0 lesenswert
nicht lesenswert
VHDL hotline schrieb:
> Brauchst du in der 250MHz Domäne den absoluten Zählerwert? Ansonsten
> zähle dort nur über jeweils 5 Takte (also bis maximal 5 mittels eines 3
> Bit Zählers), halte das Ergebnis in der 250er Domäne für 5 Takte und
> addiere es in jedem 50MHz Takt zu einem absoluten Zählerwert.

Nein, den brauche ich tatsächlich nicht. Das klingt interessant, so habe 
ich da noch nicht drüber nachgedacht! Wenn ich sowieso 3 Bit verwende, 
ließe sich dieser Teil (in diesem oder einem schnelleren FPGA) eventuell 
sogar mit 400MHz realisieren und von 0 bis 7 zählen. Die Pulsweite 
sollte dann 2-4 Taktzyklen betragen (ich erwarte eine Normalverteilung 
um ~7ns), und ich hätte vielleicht sogar die Möglichkeit, eine Art Flag 
zu setzen, falls ein Puls wider Erwarten zu lang ist. Dann hat 
wahrscheinlich jemand im Labor wieder das billige/alte/zu lange Kabel 
erwischt, oder die Leitung nicht terminiert.

Lothar Miller schrieb:
>Kannst du, dann musst du aber heftig mit MultiClockCycle Constraints
>arbeiten. Denn sonst klemmt dir (wie du schon erfahren musstest) die
>Toolchain jeden Zähler mit mehr als 10 Bit ins Auge...

Okay, das traue ich mich mir mangels Erfahrung glaube ich nicht zu. 
Alles funktioniert wunderbar soweit mit dem 50MHz Basis-Takt, UART, 
FIFO, USB2, externe Peripherie, und im Grunde auch das Samplen des 
Zählerstandes. Ich hatte beim letzten Punkt nur irgendwie eine Art 
Knackpunkt erwartet, sollte sich der Zählerstand in der 250MHz Domäne 
einmal während des Samplens ändern - in der Praxis scheint aber auch das 
kein Problem zu sein.

>Und du willst "einfach" nur auch solche kurzen Impulse erfassen?
>Dann sieh dir das mal an:
>http://www.lothar-miller.de/s9y/archives/19-Kurzer...

Vielen Dank! Deine Seite ist klasse, und hat mir schon viel geholfen! 
Ich hatte auch dies hier schon einmal gesehen, auch wenn ich die genaue 
Realisierung nicht mehr auf dem Schirm hatte (deshalb schrieb ich schon 
vorsichtig: "oder mit Trick"). Wenn ich das richtig sehe, kann ich 
zumindest diesen Workaround in meinem Fall nicht verwenden, denn die 
Pulse sind nicht nur kurz und selten, sondern sie können auch 
Burst-artig mit ihrer Maximalfrequenz von ~140MHz auftreten - auch wenn 
es dann nur wenige hintereinander sein werden.

Meine erste Intention war es, die Sample Frequenz von 1kHz auf 1Mhz zu 
erhöhen, und dann einen 12 oder 13 bit Zähler zu verwenden - der sollte 
selbst den worste-case von 140 Impulsen je 1us Sample Intervall abdecken 
können. Genau dabei bin ich dann in das Problem gerannt, dass sich ein 
13bit Zähler nicht mehr ohne Weiteres mit 250MHz betreiben ließ ;)

>Es wird nichts bringen, auch dann muss das Design 250MHz "können".
>Überleg einfach mal ein paar Fälle durch. Du kommst selber drauf, dass
>im "schlimmsten" Fall (und das ist der, den das Design immer sicher
>können muss) eben nur 4ns Zeit bleiben.

Ich glaube, mein Denkfehler war, anzunehmen, dass wenn ein Zählerstand 
nur mit 50MHz abgefragt wird, dieser 250MHz Zähler im Grunde auch nur 
einen in der 50MHz Domäne stabilen Zählerstand braucht, und somit mehr 
Zeit hat. Quasi, dass auch mehrere Signale hintereinander in der 
Carry-Chain sein können und ein Signal nicht zwangsläufig die komplette 
Chain in 4ns statt 20ns durchlaufen haben muss. Zumindest nicht, wenn 
ich mit einer Art "Kopie" des Zählerstandes arbeite. Aber das geht 
vielleicht so einfach nicht.

Vielen Dank auf jeden Fall für euren Input, ich werde heute Abend mal 
ein bisschen Gehirnschmalz da hineinstecken, und ausprobieren, was der 
beste Weg sein könnte, um zum Ziel zu kommen!

von VHDL hotline (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Robert M. schrieb:
> eventuell sogar mit 400MHz realisieren und von 0 bis 7 zählen.

Das wird nur bis 350 MHz gehen, weil die 0 ja auch ein gültiger 
Zählerwert ist.


Allerdings entspannt sich das Ganze dann doch etwas. Bis 7 bei 350 MHz 
bzw. bis 5 bei 250 MHz würde ja heißen, dass der Zähler in jedem Takt 
inkrementieren kann. Das tut er wegen der Flankenerkennung (die maximal 
aller zwei Takte eine steigende Flanke sieht) ja nicht. Daher kann man 
den Zähler ggf. sogar noch kleiner machen.

Wenn die Maximalfrequenz deiner Pulse 140 MHz beträgt wirst du mit dem 
Abtasten mit 250 MHz evtl. nicht ganz hinkommen.

von Robert M. (rmueller)


Bewertung
0 lesenswert
nicht lesenswert
VHDL hotline schrieb im Beitrag #5292674:
> Robert M. schrieb:
>> eventuell sogar mit 400MHz realisieren und von 0 bis 7 zählen.
>
> Das wird nur bis 350 MHz gehen, weil die 0 ja auch ein gültiger
> Zählerwert ist.

Da hast Du völlig recht, genau das meinte ich auch!

> Wenn die Maximalfrequenz deiner Pulse 140 MHz beträgt wirst du mit dem
> Abtasten mit 250 MHz evtl. nicht ganz hinkommen.

Das kommt davon, wenn man in der Eile und unterwegs antwortet ^^ Auch 
hier ist mir ein Flüchtigkeitsfehler unterlaufen...

Ich betreibe den Zähler an unterschiedlichen Ausgangsstufen, und je nach 
der genauen Konstellation habe ich es mit mittleren Puls_weiten_ (nicht 
Puls_frequenzen_, also nur der "HIGH" Part) von 5.5-7ns zu tun. So war 
ja auch die Flankenerkennung weiter oben ausgelegt. Bei einem maximalen 
Duty-Cycle von 50% (eher niedriger) geht es also "nur" um Pulsfrequenzen 
von 72-91MHz, nicht 144-182MHz. Trotzem ist ein 8 Bit Counter, der ja im 
Samplezeitraum von 1us lediglich bis 63 zählen würde, hier zu knapp 
bemessen.

Mit dem aktuellen 250Mhz Counter hatte ich jedenfalls keine Probleme, 
einzelne Impulse zu "übersehen". Das mit einem Speicheroszilloskop Burst 
für Burst zu überprüfen, war eine langwierige, aber im Endeffekt 
zufriedenstellende Arbeit ;)

von Sigi (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Auf einem S3 laufen 4Bit-Zähler bis ~543MHz, 6Bit bis ~419,
8Bit bis ~324 etc.
Damit kannst du z.B. in der 250MHz-Domäne eine 4Bit-Zähler Z1
laufen lassen. Parallel lässt du einen weiteren 4Bit-Zähler Z2
kontinuierlich durchlaufen. Läuft Z2 über, dann wird Z1 in
einen Puffer P übertragen und ein Flag F1 invertiert. F1 sollte
dann noch per Shiftregister um 1-2 Takte zu F2 verzögert werden.

In der 50MHz-Domäne musst du nur nich eine Flanke (oder beide)
von F2 abfragen und dann P zu einem 50er-Zähler Z3 hinzuaddieren.
Damit hast du zwar nicht immer den aktuellen Zählerstand, kannst
dafür aber mit 500MHz zählen (falls das überhaupt mit deiner
DCM/PLL möglich ist).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.