Forum: FPGA, VHDL & Co. VHDL Timing Probleme - Takt synchron herunterteilen


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 Stones (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe einen parallelen FIR Filter in einem FPGA implementiert, der 
mit 1GSPS arbeitet, bzw. mit 500MHz Takt arbeitet. Die Koeffizienten 
sind in ROMs gespeichert. Um die Wärmeentwicklung gering zu halten und 
nicht die 500MHz durch den ganzen FPGA zu ziehen, möchte ich den Takt 
auf 125MHz herunterteilen und mit diesem die ROM, FSM etc takten.


Wie mache ich dies am geschicktesten ohne mir Probleme einzuhandeln. Ich 
habe aktuell eine Lösung die halbwegs funktioniert, jedoch vermute ich, 
dass die vereinzelten Störungen hierher kommen.

Viele Grüße

von Duke Scarring (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das hängt vom FPGA ab. Welchen genau hast Du?

Duke

von Stones (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sorry vergessen mitzuteilen. Zynq UltraScale+ ZU4CG

von ticktack=fickfack (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Was spricht gegen die CMT die ohnehin benutzt wird um die 500 MHz im 
Chip zu verteilen?

https://www.xilinx.com/support/documentation/user_guides/ug572-ultrascale-clocking.pdf

von Duke Scarring (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Xilinx? Da würde ich den MMCM nehmen, wie im verlinkten UG572 
beschrieben.

Duke

von Christian U. (christian_u189)


Bewertung
0 lesenswert
nicht lesenswert
Bei 1 GSPS brauchst du einen Takt im FPA von 1 GHz um ein Sample pro 
Takt zu verarbeiten. Meinst du mit 500 MHz die Nyquist-Frequenz oder 
verabeitest du zwei Samples pro Takt?

Wenn du jetzt manchmal Daten verlierst hast du vielleicht Probleme im 
Clock Domain Crossing? Um die Daten zuverlässig zwischen den Clock 
Domains zu übertragen kannst du eine Asynchrone FIFO verwenden. Auf der 
500-MHz-Seite packst du 4 Samples zusammen und schreibst jeden 4. Takt 
in die FIFO. Die FIFO hat folglich eine Breite von 4 Samples. Auf der 
125-MHz-Seite kannst du dann jeden Takt 4 Samples auslesen sobald die 
FIFO ca. halb voll ist.
Wenn die Takte langfristig synchron laufen -- sprich: von der selben PLL 
kommen -- läuft die FIFO nie voll oder leer.
Ansonsten brauchst du ein Übersetzungsverhältnis dass etwas "Schlupf" 
zulässt. In diesem Beispiel würde du dann in jedem 5. Takt 5 Samples in 
die FIFO schreiben und die FIFO entsprechend breiter.

Hier eine generische Asynchrone FIFO: 
https://github.com/unhold/hdl/blob/master/vhdl/fifo.vhd

von Stones (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt eine externe PLL für den globalen Takt. Im FPGA selbst werden 
die Daten vom ADC (welcher mit 1GSPS arbeitet) mit dem eigenen 
synchronen Takt des ADC parallelisiert. Die DSP, DACs etc. arbeiten mit 
den 500MHz von der externen PLL.
Für diese beiden Clock Domains habe ich eine asynchronous group 
angelegt.

Mit den 125MHz wird die FSM der DSP und die Koeffizienten ROMs getaktet, 
die Signalverarbeitung selber erfolgt mit 500MHz. Mit dem Aufbau, wie im 
Anhang dargestellt, habe ich negative Setup Slack an 2200 Punkten.

Erzeuge ich den Takt ganz simple wie folgt, gibt es keine Fehler. 
Allerdings habe ich gerade auch festgestellt, dass da etwas mit den 
Constraints nicht zu stimmen scheint.
process(clk)
            begin
                if falling_edge(clk) then
                    clk_div <= clk_div +1;
                    clk_target_pre <= clk_div(clk_div'high);
                end if;
    end process;

bufg_inst_clk_target : BUFG
        port map (
            I => clk_target_pre,
            O => clk_targetx
        );

: Bearbeitet durch Moderator
von Christian U. (christian_u189)


Bewertung
0 lesenswert
nicht lesenswert
Mit den Änderungen an der Taktquelle beeinflusst du die Phase der Clocks 
zueinander. Das kann die unterschiedlichen Ergebnisse erklären.

Wie machst du die Clock Domain Crossings? Verlässt du dich darauf dass 
die Clocks synchron laufen? Dann darfst du keine unterschiedlichen 
Groups in "set_clock_groups -asynchronous" verwenden, weil das einem 
False Path auf alle Pfade zwischen den Clock Domains gleich kommt.

Kannst du den Clock vom ADC_PHY runter teilen? Dann hast du nur mehr 
einen Clock-Pfad zum FPGA und brauchst dich nicht um die Phasenlage der 
Clock-Eingänge zueinander kümmern.

von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht lesenswert
Nur aus Interesse: Welchen ADC verwendest du?

von Stones (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian,

bisher hatte ich für die beiden Domains "set_clock_groups -asynchronous" 
gewählt und die Phasenlage dann über die externe PLL korrigiert.

Ich habe jetzt mal den Takt von der externen PLL genommen um den 
gesamten FPGA zu takten incl. ADC. Die Phasen bekäme ich auch in dem 
Fall extern in den Griff. Bin jetzt jedoch bei über 11000 failing 
Endpoints und gerade am versuchen dies in den Griff zu bekommen. Die 
Implementierung läuft jetzt gefühlt auch noch ein gutes Stück länger als 
zuvor bereits bei über einer Stunde :(

Verwendet werden mehrere ADS5400, denn die Latenz ist auch noch wichtig.

von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
Deine schnelle Clock ist doch eine ganzzahlige Vielfache deiner 
langsamen.

Wenn Du durch geeigneten Hardwareeinsatz dafür sorgen kannst, dass die 
synchron sind und bleiben, musst Du der Synthese (über multicycles) doch 
bloss noch erklären, dass das so ist.

"set_clock_groups -asynchronous" macht genau das Gegenteil.

von Christian U. (christian_u189)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Stones,

So wie ich dein Design verstanden habe schlummert ein Timing-Problem, 
dass du mit "set_clock_groups -asynchronous" in der STA überdeckst.
Lass uns das gerne weiter diskutieren falls dir Bits kippen oder das 
Design sehr zuverlässig werden muss.

Viel Erfolg mit Vivado!

Freundliche Grüße

von daniel__m (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

Stones schrieb:
> Zynq UltraScale+

statt MMCM oder FF, nimm doch BUFGCE_DIV.

Bei den hohen Frequenzen mit Logik einen Takt erzeugen, wäre mir zu 
unsicher (Jitter) und bei mehreren Takten, welche zueinander Bezug haben 
(sollen), kommt noch Routingdelay hinzu. Die o.g. Primitives sind aus 
meiner Sicht ideal für diese Anwendung.

grüße

von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht lesenswert
Nun, 1 GHz braucht er nicht im FPGA, die braucht nur der ADC. Der ADC 
gibt seine Daten über einen oder zwei Bus(se) aus und zwar mit Takt.

Sampletakt am ADC ist immer 1 GHz.

Mit einem Datenbus:
Der ADC gibt einen Takt F_sample/2 aus und die Daten dazu als DDR, also 
bei steigender und fallender Flanke.

Mit zwei Datenbussen:
Der ADC gibt zwei Takte F_sample/2 aus und die Daten dazu als SDR. Und 
da kann man jetzt einstellen ob die beiden Takte synchron sein sollen, 
oder ob die um 180° phasenverschoben sein sollen. (Die Daten dann auch).

Er bekommt also immer einen F_sample/2 Takt in sein FPGA. Das sollte 
auch einigermaßen jitterfrei sein weil das unsprünglich aus der 
Sampleclock stammt.

Wenn er jetzt intern seine Daten mit geringerem Takt verarbeiten möchte, 
dann kann er problemlos diesen Takt in eine PLL/MMCM füttern und daraus 
weitere Takte erzeugen. Er kann aber auch einen weiteren externen 
Taktgeber verwenden und mit dem Takte erzeugen die dann zu dem ADC Takt 
asynchron laufen. Dafür gibt es dual independent Clock FIFOs um die 
Übergänge zwischen Taktdomänen zu erledigen.

Ich würde für die Logik im FPGA die unabhängig vom ADC laufen soll nicht 
den Takt vom ADC verwenden. Denn der Takt vom ADC leigt nicht an wenn du 
den ADC in den Standby versetzt.

von Gustl B. (-gb-)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Ich bastel selber gerade mit ADCs und hätte natürlich auch gerne einen 
FIR. Aber bei den hohen Datenraten muss das ja parallel gehen und das 
traue ich mir nicht zu, ich wollte das also an den PC auslagern.

Aber siehe da, der Xilinx FIR compiler kann das schon eingebaut. Man 
kann da sagen alle wie viele Takte ein neuer ADC Wert reinkommt. Und 
diesen Wert kann man auch deutlich < 1 einstellen. Wenn man also mit 
jeder Clock z. B. 4 ADC Werte bekommt, dann kann man das da einstellen 
und bekommt schlicht einen breiteren AXI Stream Bus. Im Anhang ein 
Bildchen wie das bei 4 ADC Werten ja FIR Clock aussieht.

Ausserdem bin ich freudig überrascht wie gut das optimiert. Ich habe 
jetzt nur aus Spaß einen FIR mit 128 Koeffizienten (symmetrisch) in 
einem kleinen Spartan7 und da ist noch Platz. Bei 200 MHz FIR Takt und 
10 MSample/s ADC braucht das nur 5 DSP Einheiten. Finde ich sehr gut und 
werde ich in Zukunft häufiger verwenden.

von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht lesenswert
Wow wie cool. Ich kann 1 GSample im Spartan7 XC7S50 mit 32 FIR 
Koeffizienten in Echtzeit filtern. Mehr Platz ist aber nicht.

von Blechbieger (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Stones schrieb:
> Verwendet werden mehrere ADS5400, denn die Latenz ist auch noch wichtig.

Mehrere ADC ist ein wesentlicher Punkt. Damit hast du bei n ADC n+1 
Takte mit zwar exakt identischer Frequenz da aus derselben PLL aber mit 
unterschiedlicher Phasenlage abhängig vom Boardlayout. Je höher n desto 
unwahrscheinlicher wird es dass es überhaupt ein gültiges Timing gibt. 
Wesentlich einfacher wird das Timing wenn du pro ADC ein dual-clock FIFO 
verwendest. Die Eingangsseite mit 2*16 Bit wird mit der lokalen Clock 
(500 MHz) des ADC-PHY betrieben, die Ausgangsseite mit 4*2*16 Bit mit 
der globalen Clock (125 MHz).

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.

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