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'andi_signal_ff2='1')then
4
r_counter<=r_counter+1;
5
endif;
6
endif;
7
endprocess;
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
endif;
6
endif;
7
endprocess;
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!
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
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?
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
ifr_cnt_1khzclk=49999then
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
endif;
14
endif;
15
endif;
16
endprocess;
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!
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.
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.
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
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!
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.
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 ;)
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).