Forum: FPGA, VHDL & Co. Wie viel sind 304Mhz denn wirklich?


von Armin (Gast)


Lesenswert?

Hallo,
ich bin gerade dabei, eine Art Treiber-CPLD für LEDs anzudenken.

Die Idee ist, dass über einen mehrpoligen Bus der Reihe nach Farbwerte 
für die einzelnen angeschlossenen seriell LEDs übertragen werden. Diese 
werden abgespeichert und nach Erhalt eines "Start"-Signals aktiviert.
Ab diesem Zeitpunkt an werden die angeschlossenen LEDs mit den 
erhaltenen Helligkeitsinformationen PWM-gedimmt. Bis zum Eintreten des 
nächsten START-Signals werden währenddessen neue PWM-Werte empfangen.
Die Clock-Leitung des Busses dient dabei als Clock für das ganze CPLD. 
An ihr hängt also auch die PWM.

Hier mein Programm im Einzelnen:

Ein interner Counter zählt die erhaltenen CLK-Signale, um die 
Adressierung der Speicher-Flipflops sicher zu stellen. Damit es zu 
keiner Race-Condition kommt, zählt er als einziger Prozess bei einer 
negativen Flanke
1
Zaehler:
2
  process
3
  begin
4
    wait until falling_edge(CLK);
5
    if '1' = START then
6
      largeCnt <= 0;
7
    else
8
      largeCnt <= largeCnt + 1;
9
    end if;
10
  end process Zaehler;

Hier wird (wegen der vielen Konstanten etwas unübersichtlich) das am Bus 
anliegende Signal in das LEDdata-Array gespeichert.
1
Input:
2
  process
3
  begin
4
    wait until rising_edge(CLK);
5
    for j in 0 to BUSwidth-1 loop
6
      LEDdata(largeCnt*PWMbits + j) <= to_integer(unsigned(DATABUS(3*PWMbits*j+PWMbits to 3*PWMbits*j+PWMbits+PWMbits-1)));
7
    end loop;
8
  end process Input;

Dieser Prozess verschiebt die Daten in das LASTdata-Array, wenn die 
Übertragung abgeschlossen ist.
1
Startmove:
2
  process
3
  begin
4
    wait until rising_edge(CLK);
5
    if '1' = START then
6
      for j in 0 to LEDs-1 loop
7
        LASTdata(j) <= LEDdata(j);
8
      end loop;
9
    end if;
10
  end process Startmove;

Mit den interessanten bits des largeCnt-Signals und den in LASTdata 
gespeicherten Werten wird an den Ausgangspins eine PWM realisiert.
1
Output:
2
  process
3
  begin
4
    wait until rising_edge(CLK);
5
6
    for i in 0 to LEDs-1 loop
7
      if (largeCnt mod PWMres) < LASTdata(i) then
8
        LEDout(i) <= '0';
9
      else
10
        LEDout(i) <= '1';
11
      end if;
12
    end loop;
13
  end process Output;
14
end verhalten;

ich hoffe, der Code ist so zerstückelt besser lesbar geworden.


Als Plattform möchte ich einen Altera MAX II verwenden, der laut 
datasheet bis 304 MHz spezifiziert ist.
Allerdings wirft die Timing-Analyse einen Haufen Fehler (failed paths), 
wenn ich probehalber 266MHz verlange. "Actual time" wird mit 50MHz 
angegeben.

Nun stellen sich für mich mehrere Fragen:
- auf was beziehen sich denn diese angegebenen 304 MHz? Wie kann ich 
abschätzen, ob ein in Frage kommender PLD meinen Anforderungen 
entspricht?
- was bedeutet es denn, wenn ich 266MHz verlange? Bisher dachte ich, 
dass ich damit spezifiziere, dass die negativen Flanken dss CLK-Signals 
mit 266MHz ankommen können. Aber genauer betrachtet bin ich mir nicht 
sicher, ob das alles ist.
Immerhin wäre es mir ja egal, wenn alle Ausgänge z.B. 100ns später 
aktualisiert werden. Wichtig für die Funktionalität ist ja nur, das 
intern die Zuweisung der Adressen, die Speicherung der Buswerte und das 
"Verschieben" bei "START" sauber geschieht. Gleichmäßige Latenzen stören 
mich eher wenig. Oder anders: die Priorität der PWM ist eher gering =)
- Was kann ich am Code ändern, um die Timing Requirements zu erfüllen? 
Beziehungsweise, wie kann ich dem Programm klar machen, welche 
Funktionalität genau wichtig ist? Also dass ein anliegendes Signal nach 
3ns wieder im Ausgang liegt, gehört ja wie erläutert schon mal nicht 
dazu.
- gibt es unter Umständen eine klügere Lösung, als den Zähler bei einer 
rising_edge zu aktualisieren? Das hätte für die Erzeugung des 
BUS-Signals eventuell Vorteile...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Armin schrieb:
> - auf was beziehen sich denn diese angegebenen 304 MHz?
Auf die Schaltfrequnz zweier ideal verbundener Flipflops innerhalb des 
Bausteins. Da ist einiges an Handarbeit und wohlüberlegter Beschreibung 
nötig, dass dieser Wert erreicht wird. Garantiert bekommst du nicht das 
ganze Design so schnell. Bestenfalls kleine Teile davon.

> "Actual time" wird mit 50MHz angegeben.
Das kommt wahrscheinlich von dem Monstermux, den du da aufgebaut hast:
DATABUS(3*PWMbits*j+PWMbits to 3*PWMbits*j+PWMbits+PWMbits-1)
Mach sowas besser über ein Schieberegister.

von Armin (Gast)


Angehängte Dateien:

Lesenswert?

alles klar, danke für den Tip.
Ich hab das mal geändert und als Schieberegister realisiert (denke, das 
erkennt man schön)

Im Anhang hab ich mal einen aktuellen Schaltplan (inkl weiterer kleiner 
Änderungen)
der BUS hat hier eine Breite von 6 bit (2bit PWM und 3LEDs). In 4 Takten 
sind die Register alle gefüllt und ein START-Signal wäre sinnvoll.

Die Geschwindigkeit hat dadurch tatsächlich profitiert. Je nach Größe 
gehen mittlerweile 70-80MHz statt vorher 40-60MHz.

Wie geht's weiter?

von Armin (Gast)


Lesenswert?

Ich habe noch ein wenig experimentiert:

1. Eigentlich könnte man den LASTdata-Zwischenspeicher weglassen. Dann 
wird die Anzeige LED für LED aktualisiert und nicht mehr bei jedem 
START. Das bringt laut Timing Analyzer allerdings keine Vorteile.

2. Könnte man das gesamte design wegen dem hinzugekommenen 
Schieberegister auf die rising_edge takten? Der largeCnt-Counter ist ja 
nicht mehr zur Adressierung des MUX da, sondern nur noch für den enable 
der Schieberegister. Meint ihr das gibt Probleme?? Falls nicht, wäre die 
Frequenz schonmal doppelt so hoch.

3. Wenn man im output-process das "wait until" wegmacht und eine 
Sensitivity List schreibt, verschwinden die FlipFlops am Ausgang (siehe 
Schaltplan). Wirklich deutliche Geschwindigkeitsvorteile bringt das aber 
nicht. Was ist klüger?

4. Hier im Board habe ich gelesen, dass die "<"-Vergleiche sehr 
aufwändig sind. Ließen sich diese geschwindigkeitseffizient einsparen? 
Der erste "LessThan0" vergleicht den Zähler mit ein bis zwei Konstanten 
("nur ein paar Takte lang kommen wirklich Daten für Diesen CPLD"). Die 
Ausgangszähler realisieren die PWM (zeitunkritisch).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Armin schrieb:
> 3. Wenn man im output-process das "wait until" wegmacht und eine
> Sensitivity List schreibt, verschwinden die FlipFlops am Ausgang
Klar, denn dann ist das alles einfach nur noch kombinatorisch. Und 
warten auf einen Takt heißt ja gerade, dass FFs verwendet werden sollen.

> Was ist klüger?
Das kommt darauf an.
Wenn du in FPGAs diese Register drin lässt, dann kommen die Daten am 
Ausgang mit deutlich geringerem Laufzeitunterschied, und sie kosten 
keine zusätzlichen Ressourcen, weil sie dort im IO-Block schon mit drin 
sind.

Wenn du allerdings den 1 Takt Latency nicht brauchen kannst, dann mußt 
du die Dinger leider weglassen.

> Hier im Board habe ich gelesen, dass die "<"-Vergleiche
> sehr aufwändig sind.
Das betrifft CPLDs mit ihren Produkttermen.
In FPGAs kann die Synthese mit einem > und < Vergleich besser 
optimieren. Da habe ich die Erfahrung gemacht, dass solche Vergleiche 
durchschnittlich effizienter implementiert werden als ein = oder ein /=.

> Könnte man das gesamte design wegen dem hinzugekommenen
> Schieberegister auf die rising_edge takten?
Das wäre sowieso sinnvoll, denn die Toolchain muss durch die Verwendung 
der steigenden und der fallenden Flanke quasi mit der doppelten 
Frequenz kalkulieren. Wenn du im gesamten Design nur auf eine Flanke 
reagierst, könnte sich u.U. die maximale Frequenz sofort verdoppeln.

von Matthias G. (mgottke)


Lesenswert?

Lothar Miller schrieb:
>> Hier im Board habe ich gelesen, dass die "<"-Vergleiche
>> sehr aufwändig sind.
> Das betrifft CPLDs mit ihren Produkttermen.
> In FPGAs kann die Synthese ...

Die Altera MAX II die hier verwendet werden sind von Ihrem Aufbau quasi 
FPGAs und keine CPLDs. Sie unterscheiden sich signifikant von den Xilinx 
und Lattice CPLDs.

von Armin (Gast)


Lesenswert?

Also gut. Dann bleiben die Ungleichheitszeichen drin.


Mit allen bisherigen Ergebnissen und Experimenten komm ich auf eine 
maximal erlaubte Clock-Geschwindigkeit zwischen 80MHz und 120MHz - je 
nach Wahl der Konstanten.
Dann versuche ich - um auf Nummer sicher zu gehen - , unter diesem Wert 
zu bleiben.

Kann ich also davon ausgehen, dass wenn ich den MAXII mit diesem Takt 
anfahre, dass es dann intern keine Komplikationen gibt? Es existieren ja 
noch weitere Kenngrößen im "timing analyzer": tsu, tco, tpd, th
Versteh ich die Kenngrößen richtig?

tsu - da das CLK-Signal im Chip schneller unterwegs ist, müssen die 
BUS-Signale um tsu früher anliegen, damit sie intern an der Logik sind, 
bevor der CLK da ist. Für mich also zeitkritisch, da sonst die Werte 
nicht abgespeichert werden können. Ich gebe die halbe Taktperiode an, da 
meine BUSdaten mit der negativen Flanke angelegt werden?

tco - "maximum acceptable clock to output delay" - verstehe ich nicht 
ganz, aber da am output nichts mehr synchron sein muss, wähle ich eine 
große Zeit, oder? (10*Taktperiode, 40ns bei 250MHz)

tpd - "Specifies the maximum acceptable input to non-registered output 
delay, that is, the time required for a signal from an input pin to 
propagate through combinatorial logic and appear at an output pin." Ist 
mir auch nicht ganzt klar, was das genau bedeutet. Komplett durch den 
Chip durch geht ja kein Signal - außer vielleicht CLK über den Counter. 
Kann ich also wieder vernachlässigen (10*Taktperiode), da es wieder nur 
um die Ausgänge geht? Außerdem hab ich ja keine "non-registered" 
Outputs, wie oben im kleinen Schaltplan zu sehen ist.

th - "Specifies the maximum acceptable clock hold time for the input 
(data) pin." Bedeutet was? Dass der so Takt so lange aktiv sein muss, 
bis die Flanke im ganzen Chip angekommen ist? Hört sich eher gefährlich 
an... Halbe Taktperiode?


Aber werden mit dem Analyzer über diese Kenngrößen auch schon interne 
Laufzeitprobleme erfasst? Oder kann ich mich darauf verlassen, dass es 
die Toolchain hinbekommt, beispielsweise den Zähler schnell genug zu 
implementieren?

von Schrotty (Gast)


Lesenswert?

Die Toolchain sagt dir am Ende einer Synthese, mit welcher maximalen 
Frequenz du dein Desing im CPLD / FPGA laufen lassen kannst, dass 
gewährleistet ist, dass alle Zeitanforderungen eingehalten werden.
Es wird also sichergestellt, dass die Signallaufzeit durch den 
LANGSAMSTEN kombinatorischen Pfad zwischen zwei Registern inclusive der 
Brücksichtigung aller Werte für Tsu etc. nicht länger als eine Zeit X 
ist.
Die maximale Frequenz ergibt sich dann aus 1/X.

Aber ganz ehrlich sehe ich nicht, warum du eine PWM-Geschichte für LEDs 
mit 200MHz takten willst?

von Matthias G. (mgottke)


Lesenswert?

tsu
Am einem FF (Flip -Plop), auch Register genannt, müssen das Datenbit 
eine Weile vor dem Takt anliegen. Sonst wird das Datenbit nicht sicher 
erkannt. Das ist die Setup-Time (tsu)

th
Ebenso muss das Datenbit noch dem Takt noch für eine Weile anliegen. Das 
ist die Hold-Time.

Innerhalb der eines CPLDs oder FPGAs gibt ein ausgeklügeltes 
Clock-System mit speziellen Leitungen die den Takt auf dem Silizium so 
verteilt, dass ermöglichst synchron an allen FFs gleichzeitig anliegt 
(bitte mich jetzt nicht prügeln, für einen Anfänger reicht diese 
Betrachtung). Dann kommen noch Signallaufzeiten dazu die das Signal auf 
dem Chip von einem Ausgang eines FFs zum Eingang eines nächsten 
benötigt. tsu + th + Laufzeit begrenzen die maximale Taktrate. Damit das 
sicher funktioniert wird der Pfad gesucht, bei dem die Laufzeit am 
größten ist.

tco
Ist die Zeit die ein Signal benötigt das von einem Takt an einem FF 
übernommen wird und bis es dann an einem "Beinchen" ankommt.

tpd
Die Zeit die in einem rein kombinatorischen Pfad von einem 
Eingangsbeichen zu einem Ausgangsbeinchen benötigt wird.

Auf das innere Timing kannst Du dich verlassen, allerdings musst Du das 
"Einsynchronisieren" unbedingt beachten. Sonst kann es zu Metastabilen 
Zuständen kommen. Dazu gibt es genügend Beiträge im Forum was das 
bedeutet und wie so was zustande kommt.

von Armin (Gast)


Lesenswert?

Schrotty, du hast natürlich recht! Das Takten der LEDs muss nicht mit so 
hoher Frequenz passieren. Ich könnte genausogut vorher eine 
Integer-Division auf den Zähler durchführen und damit "weniger schnelle 
bits" die PWM steuern lassen.
[Zur Erklärung: die hohe Frequenz kommt von der Datenmenge, die über den 
Bus muss (in Verbindung mit begrenzen Pinzahlen).]
Einen Nachteil sehe ich derzeit aber darin auch nicht. Oder hat jemand 
Erfahrungen mit LED-Schaltverlusten bei diesen Geschwindigkeiten?

Wie schnell die PWM in der Praxis genau wird und welche Auswirkungen das 
hat werde ich dann beizeiten einfach durch "Testen" herausfinden. Was 
das Treiben angeht, habe ich demnächst ohnehin noch ein paar weitere 
Fragen, die hier thematisch gar nicht passen und deswegen einen neuen 
Thread bekommen.


Aktuell:
Die tsu macht mich noch Probleme. Das Design wäre jetzt mit ca. 100MHz 
lauffähig (10ns). Aber die tsu beträgt 6.6ns. Also müsste ich praktisch 
beim Erzeugen der Busdaten diese etwa einen 2/3 Takt vor dem CLK auf die 
Reise schicken oder?
Dafür sehe ich prinzipiell zwei Lösungen:
1. Die Erzeugung (wieder mittels CPLD oder FPGA) läuft mit der 
dreifachen Geschwindigkeit. im ersten Schritt werden die Daten an den 
BUS gelegt, im zweiten Schritt herrscht Langeweile, im dritten Schritt 
wird CLK hinterhergeschickt. Das sieht aber in meinen Augen ziemlich 
aufwändig aus.
2. ich schaff es, per Layout das CLK-Signal um 7ns zu verzögern. Das 
ergibt also 7ns * 300e06m/s = 2.1 Meter - und das, ohne eine Antenne zu 
bauen...
Auch das klingt - selbst so ganz ohne HF-Erfahrung - utopisch?

was meint ihr?
Wie löst man sowas üblicherweise?

von Falk B. (falk)


Lesenswert?

Armin (Gast)

>Wie löst man sowas üblicherweise?

Ganz anders. Beschäftige dich mal mit den Grundlagen synchroner, 
digitaler Schaltungen. Fang mal hier an, SDRAM-Timing

Ein schneller IC ersetzt kein Fachwissen.

MfG
Falk

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Aber die tsu beträgt 6.6ns.
Welche?
Die tsu eines heutigen FFs in einem FPGA ist garantiert um eine 
Zehnerpotenz niedriger. Du verwechselst da was.

> Wie löst man sowas üblicherweise?
Man schaut einfach mal über den Tellerrand, wie z.B. Daten zu 
LC-Displays übertragen werden. Dort geht das mit LVDs, damit der 
Datenpfad an sich mal sauber definiert ist und nicht noch Tricks mit der 
Terminierung gemacht werden müssen.

Warum brauchst du eifentlich so eine auffällig hohe Übertragungsrate? 
Eine LVDS-Lane bei einem Display kann 3*8 Bit bei ca. 25 MHz 
LVDS-(Pixel-)Takt, der dann 7-fach überabgetastet wird und in 175 MHz im 
FPGA resultiert.

von Schrotty (Gast)


Lesenswert?

>Aber die tsu beträgt 6.6ns
Welche Tsu meinst du? Die, der Register in deinem FPGA? Ganz sicher 
nicht, die ist viel geringer.

Ich versteh nicht ganz, wo dein problem ist. Offensichtlich redest du 
von einem externen Bus (also außerhalb des FPGA) mit einem ebenso 
externen CLK.

Solche Signale solltest du eigentlich mit dem internen Takt deines FPGA 
abtasten. Und dann kommt her Shannon in´s Spiel ;-)
Wenn dein FPGA SERDES-Blöcke zur Verfügung stellt, könntest du das 
Problem mit diesen Erschlagen, denn die können mit deutlich höheren 
Frequenzen zurechtkommen (mal salopp formuliert)

Wenn du keinen Separaten Takt für das FPGA verwendest, sondern das FPGA 
mit dem Bustakt des externen Bus taktest, dann kann man sowas auch 
machen, allerdings solltest du dann die Laufzeitunteschiede von deinen 
Pins (Takt und Daten) bis zum ersten Register durch geeignete 
Constraints so setzen, dass die Synthese "weiss", dass zwischen diesen 
Signalen nur ein maximaler Skew erlaubt ist.
Wie das geht, steht im Handbuch des Synthesewerkzeugs.

Ich hoff, ich hab dein Problem richtig erfasst

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.