mikrocontroller.net

Forum: FPGA, VHDL & Co. Timing Probleme, wieso?


Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

sorry für den wenig aussagekräftigen Thread-Titel aber ich tue mir 
schwer, das Problem kurz zu beschreiben.

Ich habe in meinem Virtex 5 Design Probleme, die sehr nach 
Timing-Problemen aussehen: Dinge, die in der Simulation funktionieren 
verhalten sich in der HW anders, bei manchen Syntheseergebnissen kommt 
es sogar zu einem vollkommen falschen Verhalten einer bestimmten State 
Machine, das ich mir nur mit einem Timing-Problem erklären kann, das 
dazu führt, dass die einen FFs in den Folgezustand gehen und die anderen 
nicht.

Das ganze tritt am Übergang zwischen zwei Clock-Domänen auf, allerdings 
sind diese nicht komplett asynchron sondern beide haben 125 MHz 
Taktfrequenz nur ist die eine mittels PLL aus der anderen abgeleitet. 
Diese zwei Taktdomänen existieren schon lange problemfrei im Design und 
bisher hatte ich keine Probleme, von der einen zu anderen ohne 
Synchronisation Daten zu schieben. Insbesondere dachte ich, dass das 
Synthesetool das durchaus berücksichtigt und eben den notwendigen margin 
für zusätzlichen Jitter durch die PLL sowie anderes Taktnetzwerk usw 
einrechnet. Der Timing-Report sagt jedenfalls, dass alle Constraints 
erfüllt sind.

Habe ich da was falsch verstanden bzgl Taktdomänen und via PLL 
abgeleiteten Taktdomänen. Ich hab da nämlich noch einige andere 
langsamere Taktdomänen (62.5 MHz), die aus derselben PLL kommen und die 
ich bisher auch als synchron zur 125 MHz Taktdomäne gesehen habe. Es 
wäre schlecht für mich, wenn die auch ein Problem haben.

Danke fürs Lesen und lG
Matthias

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In deinem Fall sollten alle Uebergaenge zwischen clock domains von den 
Tools beruecksichtigt werden. Durch die Benutzung der PLLs sind die 
Beziehungen zwischen den Clock Domains ja fest vorgegeben.

Wenn ein Design in der Simulation funktioniert, aber nicht in der 
Wirklichkeit, dann wuerde ich zu allererst ueberpruefen, ob auch 
wirklich ueberall alle sensitivity lists komplett und korrekt sind.

Aus welchem Grund benutzt du so viele verschiedene Takte? Gibt es nicht 
vielleicht doch eine Moeglichkeit, einen gemeinsamen Takt zu verwenden?

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um die vielen Takte komme ich wahrscheinlich nicht herum, ich habe eine 
PCIe Anbindung über den Endpoint Block Plus und brauche für die 
Ansteuerung diverser externer Koponenten Takte mit 62.5 MHz, teilweise 
auch mit 180 Grad Phasenversatz. Bisher hatte ich damit keine Probleme.

Jetzt soll auch noch der DDR2 auf dem Board an das ganze ran und der 
braucht neben den 125 MHz und den 62.5 MHz die ich habe auch noch einen 
125 MHz + 90 Grad Phase und einen 200 MHz Takt. Das ganze kann ich noch 
mit einer PLL erzeugen.

Und jetzt geschieht es eben, dass das ganze solange ordentlich läuft, 
wie ich nichts aus dem DDR2 auslesen, wenn von dem aber das 
rd_data_valid Signal kommt (das gültige Lesedaten anzeigt) dann gibt es 
Probleme, im nicht so dramatischen Fall kommt das erste der beiden 
gelesenen Wörter nicht im entsprechenden Register an aber die FSM macht, 
was sie soll, im dramatischen läuft die FSM "Amok" und das gesamte 
System hängt.

Soweit zumindest der Befund nachdem ich mir die Signale auf den 
Logikanalysator hinausgeführt habe.

Irgendwie kann es, soweit ich es derzeit sehe, nur ein Timing-Problem 
von diesem rd_data_valid Signal sein.

Das ganze passiert überall in getakteten Prozessen, darum glaube ich 
nicht, dass es an vergessenen Signalen in der Sensitivity List liegt, 
aber ich werde es natürlich checken.

Lg
Matthias

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um es noch ein wenig klarer zu machen: Die FSM die Amok läuft hängt am 
PCIe und benutzt den von dort ausgegebenen 125 MHz Takt, das DDR2 
Interface benutzt einen 125 MHz Takt der in der PLL mit aus dem Takt vom 
PCIe Endpoint erzeugt wird. Das sind die beiden Taktdomänen, zwischen 
denen das Problem auftritt.

Lg
Matthias

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das eine ist ein Takt, der ueber das Interface rein kommt, der andere 
kommt (ueber eine PLL) aus einem lokalen Oszillator?
Das heisst dann also, dass die Phasenbeziehung und die Unterschiede in 
der Frequenz vollkommen unbekannt sind? In diesem Fall kommst du um eine 
aufwendige Synchronisierung mittels eines dual-port-dual-clock-FIFO 
wahrscheinlich nicht herum. Ausserdem solltest du darauf achten, dass 
alle Eingaenge in den FPGA auch mit INPUT bzw. OUTPUT - constraints 
belegt sind, sowie die IO-Fliflops direkt an den Eingaengen auch 
wirklich benutzt werden.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Matthias (Gast)

>Um es noch ein wenig klarer zu machen: Die FSM die Amok läuft hängt am
>PCIe und benutzt den von dort ausgegebenen 125 MHz Takt, das DDR2
>Interface benutzt einen 125 MHz Takt der in der PLL mit aus dem Takt vom
>PCIe Endpoint erzeugt wird. Das sind die beiden Taktdomänen, zwischen
>denen das Problem auftritt.

Tja, und wenn der PCIe Takt jittert, dann ist die Phasenlage alles 
andere als konstant. Und er TUT jittern, vor allem weil er mittels 
Spread Spectrum erzeugt wird.

-> Ergo Die beiden Taktdomänen müssen als asynchron betrachtet werden. 
-> Asynchrones FIFO.

MFG
Falk

Autor: Matthias (@home) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antworten. Ich habe inzwischen folgendes gemacht: Ich habe 
einen Satz FFs, die ich schon vorher zur Behebung von Timing-Problemen 
am Lese-Interface dazwischen (sozusagen pipelined) reingehängt habe, von 
der steigenden Taktflanke (auf der der Rest läuft) auf die fallende 
Taktflanke umgehängt, das Ergebnis war sehr schön, alles hat perfekt 
funktioniert (min. 4 mio mal Schreiben/Auslesen ohne einen einzigen 
Fehler). Die Ursache des Problems dürfte also klarer werden. Jetzt muss 
ich mir noch klar werden, wie ich damit umgehe, immerhin gibts da ja 
noch diverse andere Taktdomänen, die zwar in allen Syntheseläufen bisher 
problemlos funktioniert haben aber die dasselbe Problem haben -> 
jitternde Clock am PCIe Interface trifft auf PLL gefilterter Clock im 
innerern des FPGA.

LG
Matthias

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch ein Grund auf mehrere Taktdomänen zu verzichten: Das läßt sich 
nicht gescheit simulieren.

Duke

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Duke Scarring (Gast)

>Auch ein Grund auf mehrere Taktdomänen zu verzichten:

Geht manchmal nicht. ABER!

Man sollte die Anzahl der Schnittstellen zwischen den Domänen möglichst 
gering halten. Und an den wenigen Stellen SEHR koneservativ arbeiten.

MFG
Falk

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mich gewundert hat ist dass die Synthese das nicht erkennt und das 
beim PAR entsprechend berücksichtigt. Ich habe jetzt bei den Constraints 
beim PERIOD Constraint das INPUT_JITTER Keyword entdeckt, damit sollte 
ich eigentlich die notwendige Information geben können. Aber wie kann 
ich der Spread-Spectrum PCIe Clock einen Jitterwert zuweisen? Ich habe 
noch nicht mal eine Angabe über das Spektrum der Clock gefunden.

LG
Matthias

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachdem ich mich gestern mit meinem Chef dazu eingehend besprochen habe 
hat er mir geraten, es mal mit einem DLL statt einer PLL zu versuchen, 
weil diese den Jitter nicht rausfiltert. Siehe da, jetzt funktioniert 
alles auch ohne Tricks wie die FFs auf der negativen Taktflanke 
dazwischen zu schalten.

Ich muss das ganze erst noch weiter erproben, immerhin hatte ich je nach 
Syntheselauf unterschiedliche Ergebnisse. Aber immerhin, das ist das 
erste Design das vollständig funktioniert, inzwischen schon für einige 
100 mio Schreib/Lesezugriffe auf den DDR2 fehlerfrei, also ganz so 
schlecht kann es ja nicht sein.

LG
Matthias

Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich mache es immer folgendermaßen:

Ich habe eine Takt z.B. deine 125MHz. Den Takt gibst Du auf ein Register 
das eine 1 enthält. Mit der steigenden Clockflanke schiebe ich die 1 um 
eine stelle nach links weiter. Mit der fallenden Clockflanke frage ich 
ab ob das Bit an der gewünschnten Stelle angekommen ist. Wenn das der 
Fall ist führe eine gewisse funktion aus. Wenn Du nur ein Takt durch 2 
teilen willst ist das Register halt nur zwei stellen lang. Zudem hälst 
Du damit immer die Setuptime ein.


--**********************************************************
--  Ansteuerung des AD-Wandlers über die CS-Leitung        *
--**********************************************************
process (CLK)

 begin
    if(CLK'event and CLK = '1') then
       if(GATE = '0' or CLR = '1')then
          CS_ADC <= '1';
       else
          CS_ADC <= S_REGA(0);
       end if;
    end if;
end process;


--**********************************************************
-- Irgendetwas ausführen        *
--**********************************************************
process (CLK)

 begin
    if(CLK'event and CLK = '1') then
       if(GATE = '0' or CLR = '1')then
          Test <= '1';
       else
          if(S_REGA(3) = '1')then;
             Test <= '0';  // Hier kann irgendeine Funktion ausgeführt 
werden
          end if;
       end if;
    end if;
end process;



--**********************************************************
--  Schieberegister für AD-Wandleransteuerung              *
--**********************************************************
process (CLK)

begin
   if(CLK'event and CLK = '0') then
      if(CLR = '1' or GATE = '0') then
         S_REGA <= "00000000000001";
      else
         S_REGA <=  S_REGA(12 downto 0) & S_REGA(13); -- schieben
      end if;
   end if;
end process;
end structure;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> if(CLK'event and CLK = '0') then ...
> if(CLK'event and CLK = '1') then ...
> Zudem hälst Du damit immer die Setuptime ein.
Klar, denn das ist trotzdem nur 1 Taktdomäne, beschrieben mit 
Clock-Enables.

Interessant wird es allerdings, wenn die Clock-Enables über größere 
Flächen (an viele FFs) geroutet werden müssen...
Da kann es schnell mal vorkommen, dass ein globales Taktnetz besser 
wäre.

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johann
Es gibt keinen Grund dies mit unterschiedlichen Flanken zu tun, ganz im 
Gegenteil, bei es kommt möglicherweise zu einen Halbierung der möglichen 
Taktrate, weil Du nur mehr die halbe Taktperiode als Setup-Zeit hast.

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.
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.