Hallo,
ich bin neu in der FPGA-Szene und hätte eine Frage:
mir ist klar, dass mein VHDL-Code die tatsächlich realisierbare
Schaltgeschwindigkeit im FPGA beeinflusst. Nur finde ich diesbezüglich
wenig in der Literatur. Habt ihr Tipps für mich, wie lautet der
Fachbegriff, wo gibt es Designrichtlinien für eine maximale
Geschwindigkeit, gute Webseiten etc?
LG und Danke
Paul
Was da glaube ich am meisten hilft ist das Verständnis wie die
Beschreibung in einem FPGA umgesetzt wird. Und wie das mit dem Takt so
ist.
Das ist ein sehr weites Feld.
Grundsätzlich würde ich sagen dass der Takt umso höher werden kann je
weniger Logik zwischen den Registern ist. Aber welche Beschreibung zu
wie viel Logik führt ist anfangs schwer abzuschätzen.
Wenn du Code hast, der optimiert werden soll, dann zeig der hier gerne
her. Am Beispiel sind manche Dinge einfacher zu erklären.
Und du kannst dir natürlich auch angucken was die Toolchain aus deiner
Beschreibung gemacht hat. Da siehst du genau was zwischen Registern
abläuft.
Vielen Dank für dein Angebot, aber ich habe momentan keinen konkreten
Code.
Es ist immer das Problem, dass man, bevor der Code nicht fertig ist, nie
wirklich weiß, wie hoch das Taktmaximum ausfallen wird. Teilweise gibt
es beträchtliche Unterschiede und manchmal kann ich das nicht wirklich
nachvollziehen.
Ja, stimmt, aber was ist das Ziel?
Ist das Ziel ein möglichst hoher Takt? Dann muss man optimieren was
geht. Wenig Logik zwischen Register und viel Pipelines bauen. Das ist
aber ein Kompromiss aus Takt und Latenz.
Oft ist das Ziel aber nicht ein möglichst hoher Takt, sondern ein
bestimmter Takt. Also um etwas zu erreichen muss der Takt mindestens 50
MHz betragen. Und da gibt es keinen Sinn weiter zu optimieren wenn das
Design den Takt schafft. Man macht das also nur so optimiert wie nötig.
Was du aber auf jeden Fall machen solltest:
Die Frequenz der Eingangstakte solltest du über Constraints der
Toolchain mitteilen.
Du solltest keine Takte durch Flipflops teilen. Ja, kann man machen,
aber nur wenn man weiß was man tut.
Und wenn du mehrere Takte verwendest dann achte auf einen sauberen
Übergang von Signalen aus der einen in die andere Taktdomäne. Dafür gibt
es einige Techniken. Und auch da muss man Constraints setzen, dass die
Toolchain weiß, dass die Takte nicht synchron sind.
Weils mir gerade einfällt:
vor einiger Zeit hing ich bei einem Problem mit einer PWM auf einem
low-cost-FPGA, der so ca. 300 MHz max. Taktfrequenz hatte laut
Datenblatt. Ich wollte eine PWM realisieren, Eingang 12 Bit parallel,
bei einer Trägerfrequenz von 60 kHz, das Nutzsignal hatte eine Frequenz
im Audiobereich. Die Taktfrequenz des FPGAs musste vorzugsweise sehr
hoch sein (ideal deutlich über 200 MHz), wegen weiterer Module, die das
brauchten.
Ich habe zig verschiedene Varianten ausprobiert und recherchiert, aber
da war leider nichts dabei, wodurch die Anforderungen erfüllt worden
wären. Hättest du einen Vorschlag für einen maximal optimierten Code
(Verilog) für ein solches PWM-Modul?
Danke nochmal, auch für die anderen wertvollen Tipps ;-)
Paul schrieb:> low-cost-FPGA, der so ca. 300 MHz max.
Diese Datenblatt Taktangaben sind selten zu gebrauchen. Um welches FPGA
geht es denn und wie hast du das zu lösen versucht?
Paul schrieb:> Ich habe zig verschiedene Varianten ausprobiert und recherchiert, aber> da war leider nichts dabei, wodurch die Anforderungen erfüllt worden> wären.
Wenn du dein Design durch die Toolchain schickst, und das das Timing
nicht schafft, dann kannst du dir ganz genau angucken wo das nicht
geschafft wird. Also welcher Pfad an welcher Stelle zu langsam ist. Oft
sind das Rechnungen die man dann auf mehrere Takte aufteilen kann. Oder
man baut eine Pipeline ein oder ... oft fehlen auch schlicht
Constraints. Dann ist es so, dass die Toolchain sagt, das Timing wird
nicht geschafft, aber das stimmt nicht weil ein set_false_path fehlt.
Paul schrieb:> Hättest du einen Vorschlag für einen maximal optimierten Code> (Verilog) für ein solches PWM-Modul?
Kannst du das nochmal genauer erklären?
Ich verstehe vorallem nicht was du mit Trägerfrequenz meinst in Bezug
auf PWM und deine Signale.
So wie ich das verstanden habe hast du einen 60 kHz Sinus und darauf ist
dann mit FM ein Audiosignal moduliert.
Welche Werte bekommt das FPGA, also was stellen diese 12 Bit dar? Sind
das Abtastwerte von einem AD-Wandler? Wenn ja, welche Abtastrate macht
der? Außerdem ist noch wichtig welche Auflösung die PWM haben soll.
Gustl B. schrieb:> Grundsätzlich würde ich sagen dass der Takt umso höher werden kann je> weniger Logik zwischen den Registern ist. Aber welche Beschreibung zu> wie viel Logik führt ist anfangs schwer abzuschätzen.
Du musst nur die Groessen der LUTs des Ziel FPGAs kennen. Dann kannst du
schon sehr frueh sehen wieviele kaskadiert werden muessen. Das bekommen
auch Anfaenger hin, sobald sie mit dem Konzept des FPGAs vertraut sind.
Ich weiss nicht ob ein Buch so effektiv ist um damit einzusteigen. Das
ist einfach alles Erfahrung. Und nicht nur Erfahrung mit FPGAs im
Allgemeinen, sondern auch Hersteller- und Toolchain spezifisch. Denn
genauso wie du durch Code Optimierungen deine Zielgeschwindigkeit
verbessern kannst, kannst du auch durch das Finden der richtigen Tool
Settings (angepasst auf dein Design) einiges erreichen. Kleines
Beispiel: Register Balancing.
Das lernt man am besten indem man einfach anfaengt. Loslegen und wenns
Probleme gibt, nachfragen. Und immer im Hinterkopf behalten: Man lernt
nie aus. :-)
Paul schrieb:> Die Taktfrequenz des FPGAs musste vorzugsweise sehr hoch sein> (ideal deutlich über 200 MHz), wegen weiterer Module, die das brauchten.
Man muss nicht das gesamte FPGA mit der theoretisch maximalen
Geschwindigkeit fahren. Oft muss man nur einzelne Module lokal mit hoher
Taktfrequenz anfahren. Die Datenrate "nach aussen" ist dann wesentlich
niedriger.
Paul schrieb:> Hättest du einen Vorschlag für einen maximal optimierten Code> (Verilog) für ein solches PWM-Modul?
Wenn du die Möglichkeiten eines speziellen FPGAs ausreizen musst, dann
musst du "das Modul" erst mal als Schaltung so auslegen, dass die Logik
(LUTs) samt der Register (Flipflops) gut auf das FPGA passt. Und diese
Schaltung beschreibst du mit der gewünschten
HardwareBESCHREIBUNGsssprache (=HDL, in deinem Fall Verilog) diese
optimale Schaltung in der Hoffnung, dass der Synthesizer aus deiner
Beschreibung das macht, was du gerne willst. Ob der Synthesizer deine
Beschreibung verstanden hat und du das bekommen hast, was du wolltest,
kannst du z.B. im RTL Schaltplan ansehen.
Wie du bestimmte Komponenten so beschreiben musst, dass der Synthesizer
darin bestimmte Hardwarekomponenten erkennt, steht im jeweiligen
Handbuch zum Synthesizer.
Hast du gemerkt, dass in meinen Text das Wort "Code" nicht vorgekommen
ist? Denn allzu leicht verwechselt der Anfänger das dann mit "C-Code"
und "programmiert" halt wie aus der Softwareentwicklung gewohnt
irgendwie vor sich hin und wundert sich, was herauskommt.
@ Gustl:
Danke für dein Interesse, nein du hast da was falsch verstanden: vom AD
kommen 12 Bit parallel, es wird ein Audiosignal digitalisiert,
Samplingfrequenz weiß ich nicht mehr, halt im üblichen Bereich. Daraus
soll der FPGA dann die PWM machen mit 60kHz Trägerfrequenz.
Ich sehe das wird hier sehr spezifisch, ich bin da gar nicht so tief
drinnen mit Timing Constraints etc. das muss ich mir noch ansehen. Es
ging mir eher um eine allgemeine Aussage, die wohl nicht so leicht
möglich ist.
Danke auch an alle anderen, und @ Lothar: ja ich weiß, dass es eine
HardwareBESCHREIBUNG ist. Code ist aber eine allgemeine Aussage... und
umfasst wohl auch das. Und nein, ich kenne auch den Unterschied zwischen
Programmierung und Beschreibung, C-Code ist nicht gemeint, danke für die
Belehrung
Paul schrieb:> Es ging mir eher um eine allgemeine Aussage, die wohl nicht so leicht> möglich ist.
Doch, genau diese allgemeine Aussage habe ich gemacht. Wenn man das
beachtet, was ich da geschrieben habe, dann kann man den Code so
schreiben, dass der Synthesizer die gewünschte Schaltung daraus macht.
Dadurch, dass ich mich an diese Arbeitsweise halte, kann ich die
Toolchain über Constraints so steuern, dass mein Ziel erreicht wird.
Oder andesrum: wenn ich vermurksten, dem Synthesizer unverständlichen
Code schreibe, dann kann ich hinterher mit Constraints auch nichts mehr
geradebiegen.
Paul schrieb:> Danke auch an alle anderen, und @ Lothar: ja ich weiß, dass es eine> HardwareBESCHREIBUNG ist. Code ist aber eine allgemeine Aussage... und> umfasst wohl auch das.
Deine Fragestellung lässt aber vermuten das der Unterschied zwischen C-
und HDL-Code eben nicht verstanden wurde.
Während bei C tatsächlich jede der nacheinander abgearbeitetn Code zeile
zu Ausführungsgeachwindigkeit beiträgt, kommt es bei Hardwaredesign
lediglich auf den den längsten (Routing-) Pfad zwischen zwei FLiFlop
(o.ä.) an um die maximale Taktfrequenz für die tausenden parallel
arbeiten FF u.ä. zu ermitteln.
Und dieser 'kritische' Pfad (critical path) wird nur von wenigen Zeilen
im HDL mitbestimmt, die Erstellung des HDL ist lediglich ein kleiner
Teil beim FPGA-design. Hinzukommt die Erstellung/Überprüfung der
compiler-schalter (bsp. Optimize für Area/clocking), Floorplaning
(location constraints, clocking resources, (dedicated) IO-Pinning) und
Geschwindigkeits-Randbedingungen (timing-condtraints):
'Mitbestimmt' weil die die länge nicht nur von der Funktion (wie in der
HDL festgehalten) bestimmt wird sondern auch von der Platzierung und der
Verdrahtung der Hardware-resourcen. Und diese Platzierung und
Verdrahtung ist von Compiler-optionen und Router-methoden (und nur
anteilig/gering vom HDL-Code) abhängig.
Du wirst also auch schauen müßen, das diese stimmen, also bspw. welche
Statemachine-codierung bei der Synthese verwendet wird (binnary,
One-hot),
ob die carry-chain, MuX7, Mux8 Elemente benutzt werden, ob FF-balancing
möglih ist, ob die FF in den IO-Pads liegen, ob der Skew durch die
PLL/DCM kompensiert wird,... um das Maximale an Taktfrequenz zu
erreichen. Und das Routing gerät schneller ans Optimum falls weniger
kritische Pfade als solche den Tools bekannt gemacht werden (false Path,
multi cycle path,..)
Es ist also IMHO mehr Falsch (also wie in C gedacht) als Richtig wenn
man behauptet: "dass mein VHDL-Code die tatsächlich realisierbare
Schaltgeschwindigkeit im FPGA beeinflusst". Es ist die Hardwarestruktur
(i.e. Pipeling, Fan out/in, parallele versus serielle Abarbeitung) und
das Routing das die max. erreichbare Geschwindigkeit für den jeweiligen
Teil des Designs bestimmt.
Fpgakuechle K. schrieb:> Es ist die Hardwarestruktur (i.e. Pipeling, Fan out/in, parallele versus> serielle Abarbeitung) und das Routing das die max. erreichbare> Geschwindigkeit für den jeweiligen Teil des Designs bestimmt.
Genau das beschreibt man mit Code. Das macht einen sehr großen
unterschied bei teilweise sehr einfachen Dingen.
Ein Vergleich einer Zahl (unsigned) mit einem Wert wird deutlich
komplizierter als nur der Vergleich eines Bits auf 1 oder 0. Daher
erreichen Zähler eine höhere Geschwindigkeit wenn man ihnen 1 Bit mehr
gibt und auf Überlauf oder eher Unterlauf mit dann nur dem MSB prüft.
Aber das ist der Code den man schreibt, auch Pipelines baut man im Code
und Register Balancing geht auch nur oder bringt nur was wenn man das
vorher im Code berücksichtigt hat.
Welchen Maximaltakt das Design erreicht hängt am FPGA, der Toolchain und
deren Einstellungen, und dann am eigenen Code samt IPs und Constraints.
Für optimierten Code braucht man Verständnis über die Hardware und man
sollte sich auch angucken was die Toolchain macht. Und ihr alles
mitteilen in Form von Constraints. Es ist hier aber nicht so wie in C
oder anderen Programmiersprachen, dass wenig oder kurzer Code schneller
läuft. Oft ist es sogar umgekehrt und mehr Code führt vielleicht zu mehr
Logik, auch nicht zwingend, erlaubt aber den höheren Takt.
Weil das so ist sollte man den Code schön lesbar schreiben und so, dass
ihn die Toolchain versteht, mit der unterhält man sich quasi über den
Code.
Paul schrieb:> vom AD> kommen 12 Bit parallel, es wird ein Audiosignal digitalisiert,> Samplingfrequenz weiß ich nicht mehr, halt im üblichen Bereich. Daraus> soll der FPGA dann die PWM machen mit 60kHz Trägerfrequenz.
Trägerfrequenz kenne ich zwar als was Anderes, aber ist sehe das jetzt
mal als die Frequenz mit der die PWM neue Werte ausgibt.
Ja, leider fehlen weiterhin viele Informationen wie Auflösung der PWM,
FPGAFamilie, ...
Für 60 kHz und 12 Bits brauchst du 1/(60 kHz *2**12) = 4,069 ns je Bit,
macht einen Takt von 245,8 MHz. Das sollte man schon schaffen können.
Edit:
Du hast da sehr wahrscheinlich mehrere Taktdomänen, eine für den ADC und
eine für die PWM. Idal wäre es ja, wenn du mit dem 2**12 fachen Takt der
ADC Abtastrate die PWM ausgibst. Oder anderes herum wenn der ADC
tatsächlich mit 60 kSample/s neue Werte liefert.
Gustl B. schrieb:> Fpgakuechle K. schrieb:>> Es ist die Hardwarestruktur (i.e. Pipeling, Fan out/in, parallele versus>> serielle Abarbeitung) und das Routing das die max. erreichbare>> Geschwindigkeit für den jeweiligen Teil des Designs bestimmt.>> Aber das ist der Code den man schreibt, auch Pipelines baut man im Code> und Register Balancing geht auch nur oder bringt nur was wenn man das> vorher im Code berücksichtigt hat.
Genau das ist es, was ich mit Hardwarestruktur aka Digitale
Schaltungstechnik meine, die man kennen sollte. Erst wählt man die
notwendige Counter/Timer- Architektur ( ripple, carry-chain,
shiftregister, LFSR, ..)
http://www.prevailing-technology.com/publications/counter_examples
,dann schreibt das in HDL so, das das vom Synthese-tool erkannt wird,
und das 'einbaut' was gewollt ist. Normalerweise findet sich im log dann
die Zeile ' x-bitcounter inferred' o.ä. .
Und dieses automatische inferring erreicht man, indem man genau den
Template-Vorgaben des Synthesetools folgt
(https://www.xilinx.com/support/documentation/sw_manuals/xilinx10/books/docs/xst/xst.pdf
S. 482f. und nicht irgendwelchen 'Code-Richtlinien für Dummies'
(register, static verwenden, Test auf 0,... )wie in C.
Wie heisst es doch: "Eine Stunde Programmieren erspart fünf Minuten
Nachdenken ;-)"
--
In C mag man mit solchen 'Bauernregeln für die optimale Codezeile' wie
'i++ langsamer als ++i' vorankommen, in HDL funktioniert das eher nicht.
Beitrag "C schneller machen"Beitrag "Code optimieren, switch case ersetzen"
In HDL sollte man die Komponente in ihrer Gesamtheit aus parallel
arbeitenden Gattern, LUT sowie FF und die Signallaufzeiten zwischen
diesen betrachten; eben Struktur statt Abfolge von Source-Code-Zeilen.
Fpgakuechle K. schrieb:> Erst wählt man die> notwendige Counter/Timer- Architektur ( ripple, carry-chain,> shiftregister, LFSR, ..)> http://www.prevailing-technology.com/publications/counter_examples> ,dann schreibt das in HDL so, das das vom Synthese-tool erkannt wird,> und das 'einbaut' was gewollt ist.
Richtig, genau das sollte man machen wenn einem die Ressourcen oder das
Timin wichtig sind. Wenn einem das egal ist, weil das FPGA groß genug
ist und der Takt nicht hoch sein muss, dann kann man VHDL schon auch
hinschreiben ohne daran zu denken was da genau draus wird.
Ich habe dazu einen Thread aufgemacht:
Beitrag "Vergleich von Zählern"
Wenn man einen Zähler einfach so hinschreibt wie man das ohne große
Kenntnis über FPGAs machen würde, dann reicht auch das für sehr viele
Anwendungen. Klar ist nicht optimal, aber eben für viele Fälle gut genug
und spart Denkarbeit. Ich sage nicht, dass man das so machen sollte und
schon gar nicht, dass man das nur so machen sollte.
Wenn ich Code schreibe achte ich erstmal auf Lesbarkeit, damit man den
auch nach etwas Zeit wenn man den wieder liest auch noch versteht. Der
Code ist oft gut genug. Wenn es dann irgendwo hakt, dann denke ich da
länger drüber nach und optimiere.
Gustl B. schrieb:> Richtig, genau das sollte man machen wenn einem die Ressourcen oder das> Timin wichtig sind.
In welchem Projekt sind die nicht wichtig??
Weltbester FPGA-Pongo schrieb im Beitrag #6643217:
> In welchem Projekt sind die nicht wichtig??
In den meisten Projekten. Ja, fast in jedem Projekt ist eines der Beiden
wichtig, aber nicht überall. Wenn ich also einen kritischen Pfad habe
der mein Timing limitiert, dann kann ich trotzdem an anderer Stelle im
FPGA etwas haben das das Timing locker schafft. Wenn ich das Andere also
noch weiter optimiere, dann gewinne ich nichts an besserem Timing.